diff --git a/OtterGui b/OtterGui index 9ec5e2ad..b92dbe60 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 9ec5e2ad2f2d35d62c2ac7c300b914fffbda2191 +Subproject commit b92dbe60887503a77a89aeae80729236fb2bfa10 diff --git a/Penumbra.GameData/ByteString/ByteStringFunctions.Case.cs b/Penumbra.GameData/ByteString/ByteStringFunctions.Case.cs index e1e0970c..7d9a94f9 100644 --- a/Penumbra.GameData/ByteString/ByteStringFunctions.Case.cs +++ b/Penumbra.GameData/ByteString/ByteStringFunctions.Case.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Runtime.InteropServices; using Penumbra.GameData.Util; namespace Penumbra.GameData.ByteString; diff --git a/Penumbra.GameData/Enums/ObjectType.cs b/Penumbra.GameData/Enums/ObjectType.cs index 414497b1..d081e6a6 100644 --- a/Penumbra.GameData/Enums/ObjectType.cs +++ b/Penumbra.GameData/Enums/ObjectType.cs @@ -1,5 +1,3 @@ -using System; - namespace Penumbra.GameData.Enums; public enum ObjectType : byte diff --git a/Penumbra.GameData/GameData.cs b/Penumbra.GameData/GameData.cs index 421b0031..c8885c3c 100644 --- a/Penumbra.GameData/GameData.cs +++ b/Penumbra.GameData/GameData.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Dalamud; using Dalamud.Data; using Lumina.Excel.GeneratedSheets; using Penumbra.GameData.Enums; diff --git a/Penumbra/Api/IPenumbraApi.cs b/Penumbra/Api/IPenumbraApi.cs index 05b56c80..cfc373df 100644 --- a/Penumbra/Api/IPenumbraApi.cs +++ b/Penumbra/Api/IPenumbraApi.cs @@ -1,10 +1,10 @@ -using System; -using System.Collections.Generic; using Dalamud.Game.ClientState.Objects.Types; using Lumina.Data; using Penumbra.Collections; using Penumbra.GameData.Enums; using Penumbra.Mods; +using System; +using System.Collections.Generic; namespace Penumbra.Api; diff --git a/Penumbra/Api/IpcTester.cs b/Penumbra/Api/IpcTester.cs index f5140db4..133f5f7e 100644 --- a/Penumbra/Api/IpcTester.cs +++ b/Penumbra/Api/IpcTester.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Numerics; -using System.Reflection; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Interface; -using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using ImGuiNET; @@ -16,6 +9,12 @@ using Penumbra.Collections; using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; using Penumbra.Mods; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Numerics; +using System.Reflection; namespace Penumbra.Api; @@ -62,7 +61,6 @@ public class IpcTester : IDisposable { if( !_subscribed ) { - _initialized.Subscribe( AddInitialized ); _disposed.Subscribe( AddDisposed ); _redrawn.Subscribe( SetLastRedrawn ); @@ -124,7 +122,7 @@ public class IpcTester : IDisposable } catch( Exception e ) { - PluginLog.Error( $"Error during IPC Tests:\n{e}" ); + Penumbra.Log.Error( $"Error during IPC Tests:\n{e}" ); } } @@ -911,7 +909,7 @@ public class IpcTester : IDisposable return; } - using var table = ImRaii.Table( "##collTree", 4 ); + using var table = ImRaii.Table( "##collTree", 5 ); if( !table ) { return; @@ -927,6 +925,11 @@ public class IpcTester : IDisposable ImGui.TextUnformatted( collection.ResolvedFiles.Count.ToString() ); ImGui.TableNextColumn(); ImGui.TextUnformatted( collection.MetaCache?.Count.ToString() ?? "0" ); + ImGui.TableNextColumn(); + if( ImGui.Button( $"Save##{character}" ) ) + { + Mod.TemporaryMod.SaveTempCollection( collection, character ); + } } } diff --git a/Penumbra/Api/ModsController.cs b/Penumbra/Api/ModsController.cs index 082bbb25..3432fb86 100644 --- a/Penumbra/Api/ModsController.cs +++ b/Penumbra/Api/ModsController.cs @@ -1,8 +1,7 @@ -using System.Collections.Generic; -using System.Linq; using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; +using System.Linq; namespace Penumbra.Api; diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index 982d5c22..eb1a189b 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Reflection; using Dalamud.Game.ClientState.Objects.Types; -using Dalamud.Logging; using Lumina.Data; using Newtonsoft.Json; using OtterGui; @@ -16,6 +9,12 @@ using Penumbra.Interop.Resolver; using Penumbra.Interop.Structs; using Penumbra.Meta.Manipulations; using Penumbra.Mods; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Reflection; namespace Penumbra.Api; @@ -206,12 +205,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi return collection.ChangedItems.ToDictionary( kvp => kvp.Key, kvp => kvp.Value.Item2 ); } - PluginLog.Warning( $"Collection {collectionName} does not exist or is not loaded." ); + Penumbra.Log.Warning( $"Collection {collectionName} does not exist or is not loaded." ); return new Dictionary< string, object? >(); } catch( Exception e ) { - PluginLog.Error( $"Could not obtain Changed Items for {collectionName}:\n{e}" ); + Penumbra.Log.Error( $"Could not obtain Changed Items for {collectionName}:\n{e}" ); throw; } } @@ -619,7 +618,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi } catch( Exception e ) { - PluginLog.Warning( $"Could not load file {resolvedPath}:\n{e}" ); + Penumbra.Log.Warning( $"Could not load file {resolvedPath}:\n{e}" ); return null; } } diff --git a/Penumbra/Api/PenumbraIpc.cs b/Penumbra/Api/PenumbraIpc.cs index fa9ada66..eb9035e1 100644 --- a/Penumbra/Api/PenumbraIpc.cs +++ b/Penumbra/Api/PenumbraIpc.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; using Dalamud.Game.ClientState.Objects.Types; -using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Penumbra.Collections; using Penumbra.GameData.Enums; +using System; +using System.Collections.Generic; namespace Penumbra.Api; @@ -73,7 +72,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderInitialized}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderInitialized}:\n{e}" ); } try @@ -82,7 +81,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderDisposed}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderDisposed}:\n{e}" ); } try @@ -90,13 +89,13 @@ public partial class PenumbraIpc ProviderApiVersion = pi.GetIpcProvider< int >( LabelProviderApiVersion ); ProviderApiVersion.RegisterFunc( () => { - PluginLog.Warning( $"{LabelProviderApiVersion} is outdated. Please use {LabelProviderApiVersions} instead." ); + Penumbra.Log.Warning( $"{LabelProviderApiVersion} is outdated. Please use {LabelProviderApiVersions} instead." ); return Api.ApiVersion.Breaking; } ); } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderApiVersion}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderApiVersion}:\n{e}" ); } try @@ -106,7 +105,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderApiVersions}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderApiVersions}:\n{e}" ); } try @@ -116,7 +115,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetModDirectory}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetModDirectory}:\n{e}" ); } try @@ -126,7 +125,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderModDirectoryChanged}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderModDirectoryChanged}:\n{e}" ); } try @@ -136,7 +135,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetConfiguration}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetConfiguration}:\n{e}" ); } try @@ -146,7 +145,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderPreSettingsDraw}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderPreSettingsDraw}:\n{e}" ); } try @@ -156,7 +155,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderPostSettingsDraw}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderPostSettingsDraw}:\n{e}" ); } } @@ -215,7 +214,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" ); } try @@ -225,7 +224,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawObject}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawObject}:\n{e}" ); } try @@ -235,7 +234,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" ); } try @@ -245,7 +244,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawAll}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawAll}:\n{e}" ); } try @@ -255,7 +254,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGameObjectRedrawn}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGameObjectRedrawn}:\n{e}" ); } } @@ -305,7 +304,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderResolveDefault}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveDefault}:\n{e}" ); } try @@ -315,7 +314,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" ); } try @@ -325,7 +324,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" ); } try @@ -335,7 +334,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetDrawObjectInfo}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetDrawObjectInfo}:\n{e}" ); } try @@ -345,7 +344,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetCutsceneParentIndex}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetCutsceneParentIndex}:\n{e}" ); } try @@ -355,7 +354,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderReverseResolvePath}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderReverseResolvePath}:\n{e}" ); } try @@ -365,7 +364,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderReverseResolvePlayerPath}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderReverseResolvePlayerPath}:\n{e}" ); } try @@ -376,7 +375,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderCreatingCharacterBase}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCreatingCharacterBase}:\n{e}" ); } try @@ -387,7 +386,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderCreatedCharacterBase}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCreatedCharacterBase}:\n{e}" ); } try @@ -398,7 +397,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGameObjectResourcePathResolved}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGameObjectResourcePathResolved}:\n{e}" ); } } @@ -462,7 +461,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemTooltip}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemTooltip}:\n{e}" ); } try @@ -472,7 +471,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); } try @@ -482,7 +481,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); } } @@ -521,7 +520,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetMods}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetMods}:\n{e}" ); } try @@ -531,7 +530,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetCollections}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetCollections}:\n{e}" ); } try @@ -541,7 +540,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderCurrentCollectionName}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCurrentCollectionName}:\n{e}" ); } try @@ -551,7 +550,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderDefaultCollectionName}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderDefaultCollectionName}:\n{e}" ); } try @@ -561,7 +560,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderCharacterCollectionName}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCharacterCollectionName}:\n{e}" ); } try @@ -571,7 +570,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetPlayerMetaManipulations}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetPlayerMetaManipulations}:\n{e}" ); } try @@ -581,7 +580,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetMetaManipulations}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetMetaManipulations}:\n{e}" ); } } @@ -633,7 +632,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderModSettingChanged}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderModSettingChanged}:\n{e}" ); } try @@ -645,7 +644,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetAvailableModSettings}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetAvailableModSettings}:\n{e}" ); } try @@ -655,7 +654,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderReloadMod}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderReloadMod}:\n{e}" ); } try @@ -665,7 +664,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); } try @@ -677,7 +676,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetCurrentModSettings}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetCurrentModSettings}:\n{e}" ); } try @@ -687,7 +686,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderTryInheritMod}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTryInheritMod}:\n{e}" ); } try @@ -697,7 +696,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderTrySetMod}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetMod}:\n{e}" ); } try @@ -707,7 +706,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderTrySetModPriority}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetModPriority}:\n{e}" ); } try @@ -718,7 +717,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderTrySetModSetting}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetModSetting}:\n{e}" ); } try @@ -729,7 +728,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderTrySetModSettings}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetModSettings}:\n{e}" ); } } @@ -782,7 +781,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderCreateTemporaryCollection}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCreateTemporaryCollection}:\n{e}" ); } try @@ -793,7 +792,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryCollection}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryCollection}:\n{e}" ); } try @@ -805,7 +804,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderAddTemporaryModAll}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderAddTemporaryModAll}:\n{e}" ); } try @@ -817,7 +816,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderAddTemporaryMod}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderAddTemporaryMod}:\n{e}" ); } try @@ -827,7 +826,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryModAll}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryModAll}:\n{e}" ); } try @@ -837,7 +836,7 @@ public partial class PenumbraIpc } catch( Exception e ) { - PluginLog.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryMod}:\n{e}" ); + Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryMod}:\n{e}" ); } } diff --git a/Penumbra/Api/RedrawController.cs b/Penumbra/Api/RedrawController.cs index df470a1a..9aef89b7 100644 --- a/Penumbra/Api/RedrawController.cs +++ b/Penumbra/Api/RedrawController.cs @@ -1,8 +1,8 @@ -using System.Threading.Tasks; using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; using Penumbra.GameData.Enums; +using System.Threading.Tasks; namespace Penumbra.Api; diff --git a/Penumbra/Api/TempModManager.cs b/Penumbra/Api/TempModManager.cs index 9fb40ec6..263b892f 100644 --- a/Penumbra/Api/TempModManager.cs +++ b/Penumbra/Api/TempModManager.cs @@ -1,11 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using OtterGui; using Penumbra.Collections; using Penumbra.GameData.ByteString; using Penumbra.Meta.Manipulations; using Penumbra.Mods; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Penumbra.Api; diff --git a/Penumbra/Collections/CollectionManager.Active.cs b/Penumbra/Collections/CollectionManager.Active.cs index 81b3d7db..6885cdee 100644 --- a/Penumbra/Collections/CollectionManager.Active.cs +++ b/Penumbra/Collections/CollectionManager.Active.cs @@ -1,13 +1,12 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Dalamud.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; using Penumbra.Mods; using Penumbra.UI; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; namespace Penumbra.Collections; @@ -197,7 +196,7 @@ public partial class ModCollection var defaultIdx = GetIndexForCollectionName( defaultName ); if( defaultIdx < 0 ) { - PluginLog.Error( $"Last choice of {ConfigWindow.DefaultCollection} {defaultName} is not available, reset to {Empty.Name}." ); + Penumbra.Log.Error( $"Last choice of {ConfigWindow.DefaultCollection} {defaultName} is not available, reset to {Empty.Name}." ); Default = Empty; configChanged = true; } @@ -211,7 +210,7 @@ public partial class ModCollection var currentIdx = GetIndexForCollectionName( currentName ); if( currentIdx < 0 ) { - PluginLog.Error( $"Last choice of {ConfigWindow.SelectedCollection} {currentName} is not available, reset to {DefaultCollection}." ); + Penumbra.Log.Error( $"Last choice of {ConfigWindow.SelectedCollection} {currentName} is not available, reset to {DefaultCollection}." ); Current = DefaultName; configChanged = true; } @@ -229,7 +228,7 @@ public partial class ModCollection var idx = GetIndexForCollectionName( typeName ); if( idx < 0 ) { - PluginLog.Error( $"Last choice of {type.ToName()} Collection {typeName} is not available, removed." ); + Penumbra.Log.Error( $"Last choice of {type.ToName()} Collection {typeName} is not available, removed." ); configChanged = true; } else @@ -246,7 +245,7 @@ public partial class ModCollection var idx = GetIndexForCollectionName( collectionName ); if( idx < 0 ) { - PluginLog.Error( $"Last choice of <{player}>'s Collection {collectionName} is not available, reset to {Empty.Name}." ); + Penumbra.Log.Error( $"Last choice of <{player}>'s Collection {collectionName} is not available, reset to {Empty.Name}." ); _characters.Add( player, Empty ); configChanged = true; } @@ -306,11 +305,11 @@ public partial class ModCollection j.WriteEndObject(); j.WriteEndObject(); - PluginLog.Verbose( "Active Collections saved." ); + Penumbra.Log.Verbose( "Active Collections saved." ); } catch( Exception e ) { - PluginLog.Error( $"Could not save active collections to file {file}:\n{e}" ); + Penumbra.Log.Error( $"Could not save active collections to file {file}:\n{e}" ); } } @@ -328,7 +327,7 @@ public partial class ModCollection } catch( Exception e ) { - PluginLog.Error( $"Could not read active collections from file {file}:\n{e}" ); + Penumbra.Log.Error( $"Could not read active collections from file {file}:\n{e}" ); } } diff --git a/Penumbra/Collections/CollectionManager.cs b/Penumbra/Collections/CollectionManager.cs index 9bc2138c..961478b5 100644 --- a/Penumbra/Collections/CollectionManager.cs +++ b/Penumbra/Collections/CollectionManager.cs @@ -1,13 +1,12 @@ +using OtterGui; +using OtterGui.Filesystem; +using Penumbra.Mods; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; -using Dalamud.Logging; -using OtterGui; -using OtterGui.Filesystem; -using Penumbra.Mods; namespace Penumbra.Collections; @@ -107,7 +106,7 @@ public partial class ModCollection { if( !CanAddCollection( name, out var fixedName ) ) { - PluginLog.Warning( $"The new collection {name} would lead to the same path {fixedName} as one that already exists." ); + Penumbra.Log.Warning( $"The new collection {name} would lead to the same path {fixedName} as one that already exists." ); return false; } @@ -115,7 +114,7 @@ public partial class ModCollection newCollection.Index = _collections.Count; _collections.Add( newCollection ); newCollection.Save(); - PluginLog.Debug( "Added collection {Name:l}.", newCollection.AnonymizedName ); + Penumbra.Log.Debug( $"Added collection {newCollection.AnonymizedName}." ); CollectionChanged.Invoke( CollectionType.Inactive, null, newCollection ); SetCollection( newCollection.Index, CollectionType.Current ); return true; @@ -128,13 +127,13 @@ public partial class ModCollection { if( idx <= Empty.Index || idx >= _collections.Count ) { - PluginLog.Error( "Can not remove the empty collection." ); + Penumbra.Log.Error( "Can not remove the empty collection." ); return false; } if( idx == DefaultName.Index ) { - PluginLog.Error( "Can not remove the default collection." ); + Penumbra.Log.Error( "Can not remove the default collection." ); return false; } @@ -179,7 +178,7 @@ public partial class ModCollection } } - PluginLog.Debug( "Removed collection {Name:l}.", collection.AnonymizedName ); + Penumbra.Log.Debug( $"Removed collection {collection.AnonymizedName}." ); CollectionChanged.Invoke( CollectionType.Inactive, collection, null ); return true; } @@ -335,12 +334,12 @@ public partial class ModCollection if( !ByName( subCollectionName, out var subCollection ) ) { changes = true; - PluginLog.Warning( $"Inherited collection {subCollectionName} for {collection.Name} does not exist, removed." ); + Penumbra.Log.Warning( $"Inherited collection {subCollectionName} for {collection.Name} does not exist, removed." ); } else if( !collection.AddInheritance( subCollection ) ) { changes = true; - PluginLog.Warning( $"{collection.Name} can not inherit from {subCollectionName}, removed." ); + Penumbra.Log.Warning( $"{collection.Name} can not inherit from {subCollectionName}, removed." ); } } @@ -370,12 +369,12 @@ public partial class ModCollection if( file.Name != $"{collection.Name.RemoveInvalidPathSymbols()}.json" ) { - PluginLog.Warning( $"Collection {file.Name} does not correspond to {collection.Name}." ); + Penumbra.Log.Warning( $"Collection {file.Name} does not correspond to {collection.Name}." ); } if( this[ collection.Name ] != null ) { - PluginLog.Warning( $"Duplicate collection found: {collection.Name} already exists." ); + Penumbra.Log.Warning( $"Duplicate collection found: {collection.Name} already exists." ); } else { diff --git a/Penumbra/Collections/CollectionType.cs b/Penumbra/Collections/CollectionType.cs index 3aabea1f..2946498d 100644 --- a/Penumbra/Collections/CollectionType.cs +++ b/Penumbra/Collections/CollectionType.cs @@ -1,6 +1,6 @@ +using Penumbra.GameData.Enums; using System; using System.Linq; -using Penumbra.GameData.Enums; namespace Penumbra.Collections; diff --git a/Penumbra/Collections/ModCollection.Cache.Access.cs b/Penumbra/Collections/ModCollection.Cache.Access.cs index fdc65e4b..351ae2fc 100644 --- a/Penumbra/Collections/ModCollection.Cache.Access.cs +++ b/Penumbra/Collections/ModCollection.Cache.Access.cs @@ -1,13 +1,14 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.CompilerServices; -using System.Threading; -using Dalamud.Logging; using OtterGui.Classes; using Penumbra.GameData.ByteString; +using Penumbra.GameData.Enums; using Penumbra.Meta.Manager; using Penumbra.Mods; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Threading; +using Penumbra.Interop; +using Penumbra.Meta.Manipulations; namespace Penumbra.Collections; @@ -29,7 +30,7 @@ public partial class ModCollection if( _cache == null ) { CalculateEffectiveFileList(); - PluginLog.Verbose( "Created new cache for collection {Name:l}.", Name ); + Penumbra.Log.Verbose( $"Created new cache for collection {Name}." ); } } @@ -61,7 +62,7 @@ public partial class ModCollection { _cache?.Dispose(); _cache = null; - PluginLog.Verbose( "Cleared cache of collection {Name:l}.", Name ); + Penumbra.Log.Verbose( $"Cleared cache of collection {Name}." ); } public IEnumerable< Utf8GamePath > ReverseResolvePath( FullPath path ) @@ -87,7 +88,7 @@ public partial class ModCollection return true; } - PluginLog.Error( $"The redirected path is too long to add the redirection\n\t{path}\n\t--> {fullPath}" ); + Penumbra.Log.Error( $"The redirected path is too long to add the redirection\n\t{path}\n\t--> {fullPath}" ); return false; } @@ -125,13 +126,11 @@ public partial class ModCollection return; } - PluginLog.Debug( "[{Thread}] Recalculating effective file list for {CollectionName:l}", - Thread.CurrentThread.ManagedThreadId, AnonymizedName ); + Penumbra.Log.Debug( $"[{Thread.CurrentThread.ManagedThreadId}] Recalculating effective file list for {AnonymizedName}" ); _cache ??= new Cache( this ); _cache.FullRecalculation(); - PluginLog.Debug( "[{Thread}] Recalculation of effective file list for {CollectionName:l} finished.", - Thread.CurrentThread.ManagedThreadId, AnonymizedName ); + Penumbra.Log.Debug( $"[{Thread.CurrentThread.ManagedThreadId}] Recalculation of effective file list for {AnonymizedName} finished." ); } // Set Metadata files. @@ -204,7 +203,24 @@ public partial class ModCollection else { _cache.MetaManipulations.SetFiles(); - PluginLog.Debug( "Set CharacterUtility resources for collection {Name:l}.", Name ); + Penumbra.Log.Debug( $"Set CharacterUtility resources for collection {Name}." ); } } -} \ No newline at end of file + + // Used for short periods of changed files. + public CharacterUtility.List.MetaReverter? TemporarilySetEqdpFile( GenderRace genderRace, bool accessory ) + => _cache?.MetaManipulations.TemporarilySetEqdpFile( genderRace, accessory ); + + public CharacterUtility.List.MetaReverter? TemporarilySetEqpFile() + => _cache?.MetaManipulations.TemporarilySetEqpFile(); + + public CharacterUtility.List.MetaReverter? TemporarilySetGmpFile() + => _cache?.MetaManipulations.TemporarilySetGmpFile(); + + public CharacterUtility.List.MetaReverter? TemporarilySetCmpFile() + => _cache?.MetaManipulations.TemporarilySetCmpFile(); + + public CharacterUtility.List.MetaReverter? TemporarilySetEstFile( EstManipulation.EstType type ) + => _cache?.MetaManipulations.TemporarilySetEstFile( type ); + +} diff --git a/Penumbra/Collections/ModCollection.Cache.cs b/Penumbra/Collections/ModCollection.Cache.cs index dbb07b95..9d0be99a 100644 --- a/Penumbra/Collections/ModCollection.Cache.cs +++ b/Penumbra/Collections/ModCollection.Cache.cs @@ -1,13 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Dalamud.Logging; using OtterGui; using OtterGui.Classes; using Penumbra.GameData.ByteString; using Penumbra.Meta.Manager; using Penumbra.Meta.Manipulations; using Penumbra.Mods; +using System; +using System.Collections.Generic; +using System.Linq; namespace Penumbra.Collections; @@ -496,7 +495,7 @@ public partial class ModCollection } catch( Exception e ) { - PluginLog.Error( $"Unknown Error:\n{e}" ); + Penumbra.Log.Error( $"Unknown Error:\n{e}" ); } } } diff --git a/Penumbra/Collections/ModCollection.Changes.cs b/Penumbra/Collections/ModCollection.Changes.cs index b2c9ffd5..32826dc8 100644 --- a/Penumbra/Collections/ModCollection.Changes.cs +++ b/Penumbra/Collections/ModCollection.Changes.cs @@ -1,7 +1,7 @@ +using Penumbra.Mods; using System; using System.Collections.Generic; using System.Linq; -using Penumbra.Mods; namespace Penumbra.Collections; diff --git a/Penumbra/Collections/ModCollection.File.cs b/Penumbra/Collections/ModCollection.File.cs index 6f76199b..a9cef608 100644 --- a/Penumbra/Collections/ModCollection.File.cs +++ b/Penumbra/Collections/ModCollection.File.cs @@ -1,13 +1,12 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using OtterGui.Filesystem; +using Penumbra.Mods; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using Dalamud.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using OtterGui.Filesystem; -using Penumbra.Mods; namespace Penumbra.Collections; @@ -67,7 +66,7 @@ public partial class ModCollection } catch( Exception e ) { - PluginLog.Error( $"Could not save collection {AnonymizedName}:\n{e}" ); + Penumbra.Log.Error( $"Could not save collection {AnonymizedName}:\n{e}" ); } } @@ -90,11 +89,11 @@ public partial class ModCollection try { file.Delete(); - PluginLog.Information( "Deleted collection file for {Name:l}.", AnonymizedName ); + Penumbra.Log.Information( $"Deleted collection file for {AnonymizedName}." ); } catch( Exception e ) { - PluginLog.Error( $"Could not delete collection file for {AnonymizedName}:\n{e}" ); + Penumbra.Log.Error( $"Could not delete collection file for {AnonymizedName}:\n{e}" ); } } @@ -105,7 +104,7 @@ public partial class ModCollection inheritance = Array.Empty< string >(); if( !file.Exists ) { - PluginLog.Error( $"Could not read collection because file does not exist." ); + Penumbra.Log.Error( "Could not read collection because file does not exist." ); return null; } @@ -123,7 +122,7 @@ public partial class ModCollection } catch( Exception e ) { - PluginLog.Error( $"Could not read collection information from file:\n{e}" ); + Penumbra.Log.Error( $"Could not read collection information from file:\n{e}" ); } return null; diff --git a/Penumbra/Collections/ModCollection.Inheritance.cs b/Penumbra/Collections/ModCollection.Inheritance.cs index 12b5c054..16415a09 100644 --- a/Penumbra/Collections/ModCollection.Inheritance.cs +++ b/Penumbra/Collections/ModCollection.Inheritance.cs @@ -1,9 +1,8 @@ +using OtterGui.Filesystem; +using Penumbra.Mods; using System; using System.Collections.Generic; using System.Linq; -using Dalamud.Logging; -using OtterGui.Filesystem; -using Penumbra.Mods; namespace Penumbra.Collections; @@ -81,7 +80,7 @@ public partial class ModCollection collection.ModSettingChanged += OnInheritedModSettingChange; collection.InheritanceChanged += OnInheritedInheritanceChange; InheritanceChanged.Invoke( false ); - PluginLog.Debug( "Added {InheritedName:l} to {Name:l} inheritances.", collection.AnonymizedName, AnonymizedName ); + Penumbra.Log.Debug( $"Added {collection.AnonymizedName} to {AnonymizedName} inheritances." ); return true; } @@ -91,7 +90,7 @@ public partial class ModCollection ClearSubscriptions( inheritance ); _inheritance.RemoveAt( idx ); InheritanceChanged.Invoke( false ); - PluginLog.Debug( "Removed {InheritedName:l} from {Name:l} inheritances.", inheritance.AnonymizedName, AnonymizedName ); + Penumbra.Log.Debug( $"Removed {inheritance.AnonymizedName} from {AnonymizedName} inheritances." ); } private void ClearSubscriptions( ModCollection other ) @@ -106,7 +105,7 @@ public partial class ModCollection if( _inheritance.Move( from, to ) ) { InheritanceChanged.Invoke( false ); - PluginLog.Debug( "Moved {Name:l}s inheritance {From} to {To}.", AnonymizedName, from, to ); + Penumbra.Log.Debug( $"Moved {AnonymizedName}s inheritance {from} to {to}." ); } } @@ -122,7 +121,7 @@ public partial class ModCollection default: if( modIdx < 0 || modIdx >= _settings.Count ) { - PluginLog.Warning( + Penumbra.Log.Warning( $"Collection state broken, Mod {modIdx} in inheritance does not exist. ({_settings.Count} mods exist)." ); return; } diff --git a/Penumbra/Collections/ModCollection.Migration.cs b/Penumbra/Collections/ModCollection.Migration.cs index 74215dd8..bc940651 100644 --- a/Penumbra/Collections/ModCollection.Migration.cs +++ b/Penumbra/Collections/ModCollection.Migration.cs @@ -1,6 +1,6 @@ +using Penumbra.Mods; using System.Collections.Generic; using System.Linq; -using Penumbra.Mods; namespace Penumbra.Collections; diff --git a/Penumbra/Collections/ModCollection.cs b/Penumbra/Collections/ModCollection.cs index 0ffff1b5..b01a8fad 100644 --- a/Penumbra/Collections/ModCollection.cs +++ b/Penumbra/Collections/ModCollection.cs @@ -1,8 +1,8 @@ +using OtterGui.Filesystem; +using Penumbra.Mods; using System; using System.Collections.Generic; using System.Linq; -using OtterGui.Filesystem; -using Penumbra.Mods; namespace Penumbra.Collections; diff --git a/Penumbra/Configuration.Migration.cs b/Penumbra/Configuration.Migration.cs index a62c091b..cd11594b 100644 --- a/Penumbra/Configuration.Migration.cs +++ b/Penumbra/Configuration.Migration.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using Dalamud.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui.Filesystem; @@ -47,6 +46,15 @@ public partial class Configuration m.Version1To2(); m.Version2To3(); m.Version3To4(); + m.Version4To5(); + } + + // Mod backup extension was changed from .zip to .pmp. + // Actual migration takes place in ModManager. + private void Version4To5() + { + Mod.Manager.MigrateModBackups = true; + _config.Version = 5; } // SortMode was changed from an enum to a type. @@ -117,7 +125,7 @@ public partial class Configuration } catch( Exception e ) { - PluginLog.Error( $"Could not delete the outdated penumbrametatmp folder:\n{e}" ); + Penumbra.Log.Error( $"Could not delete the outdated penumbrametatmp folder:\n{e}" ); } } } @@ -144,7 +152,7 @@ public partial class Configuration } catch( Exception e ) { - PluginLog.Error( + Penumbra.Log.Error( $"Could not transfer forced collection {ForcedCollection} to inheritance of collection {collection}:\n{e}" ); } } @@ -249,7 +257,7 @@ public partial class Configuration } catch( Exception e ) { - PluginLog.Error( $"Could not migrate the old collection file to new collection files:\n{e}" ); + Penumbra.Log.Error( $"Could not migrate the old collection file to new collection files:\n{e}" ); throw; } } @@ -265,7 +273,7 @@ public partial class Configuration } catch( Exception e ) { - PluginLog.Error( $"Could not create backup copy of config at {bakName}:\n{e}" ); + Penumbra.Log.Error( $"Could not create backup copy of config at {bakName}:\n{e}" ); } } diff --git a/Penumbra/Configuration.cs b/Penumbra/Configuration.cs index 0e95a7f6..65eeb5db 100644 --- a/Penumbra/Configuration.cs +++ b/Penumbra/Configuration.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Dalamud.Configuration; -using Dalamud.Logging; using Newtonsoft.Json; using OtterGui; using OtterGui.Classes; @@ -23,6 +22,7 @@ public partial class Configuration : IPluginConfiguration public int Version { get; set; } = Constants.CurrentVersion; public int LastSeenVersion { get; set; } = ConfigWindow.LastChangelogVersion; + public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New; public bool EnableMods { get; set; } = true; public string ModDirectory { get; set; } = string.Empty; @@ -79,7 +79,7 @@ public partial class Configuration : IPluginConfiguration { void HandleDeserializationError( object? sender, ErrorEventArgs errorArgs ) { - PluginLog.Error( + Penumbra.Log.Error( $"Error parsing Configuration at {errorArgs.ErrorContext.Path}, using default or migrating:\n{errorArgs.ErrorContext.Error}" ); errorArgs.ErrorContext.Handled = true; } @@ -117,7 +117,7 @@ public partial class Configuration : IPluginConfiguration } catch( Exception e ) { - PluginLog.Error( $"Could not save plugin configuration:\n{e}" ); + Penumbra.Log.Error( $"Could not save plugin configuration:\n{e}" ); } } @@ -142,7 +142,7 @@ public partial class Configuration : IPluginConfiguration // Contains some default values or boundaries for config values. public static class Constants { - public const int CurrentVersion = 4; + public const int CurrentVersion = 5; public const float MaxAbsoluteSize = 600; public const int DefaultAbsoluteSize = 250; public const float MinAbsoluteSize = 50; diff --git a/Penumbra/Import/MetaFileInfo.cs b/Penumbra/Import/MetaFileInfo.cs index 5393fa6c..53c23496 100644 --- a/Penumbra/Import/MetaFileInfo.cs +++ b/Penumbra/Import/MetaFileInfo.cs @@ -1,6 +1,6 @@ -using System.Text.RegularExpressions; using Penumbra.GameData.Enums; using Penumbra.GameData.Util; +using System.Text.RegularExpressions; namespace Penumbra.Import; diff --git a/Penumbra/Import/StreamDisposer.cs b/Penumbra/Import/StreamDisposer.cs index 09300ed1..fb5ccef4 100644 --- a/Penumbra/Import/StreamDisposer.cs +++ b/Penumbra/Import/StreamDisposer.cs @@ -1,6 +1,6 @@ +using Penumbra.Util; using System; using System.IO; -using Penumbra.Util; namespace Penumbra.Import; diff --git a/Penumbra/Import/TexToolsImport.cs b/Penumbra/Import/TexToolsImport.cs index fd659278..cdcdcd1d 100644 --- a/Penumbra/Import/TexToolsImport.cs +++ b/Penumbra/Import/TexToolsImport.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using Dalamud.Logging; using Newtonsoft.Json; using Penumbra.Mods; using FileMode = System.IO.FileMode; @@ -121,7 +120,7 @@ public partial class TexToolsImporter : IDisposable // Puts out warnings if extension does not correspond to data. private DirectoryInfo VerifyVersionAndImport( FileInfo modPackFile ) { - if( modPackFile.Extension is ".zip" or ".7z" or ".rar" ) + if( modPackFile.Extension.ToLowerInvariant() is ".pmp" or ".zip" or ".7z" or ".rar" ) { return HandleRegularArchive( modPackFile ); } @@ -142,7 +141,7 @@ public partial class TexToolsImporter : IDisposable { if( modPackFile.Extension != ".ttmp2" ) { - PluginLog.Warning( $"File {modPackFile.FullName} seems to be a V2 TTMP, but has the wrong extension." ); + Penumbra.Log.Warning( $"File {modPackFile.FullName} seems to be a V2 TTMP, but has the wrong extension." ); } return ImportV2ModPack( modPackFile, extractedModPack, modRaw ); @@ -150,7 +149,7 @@ public partial class TexToolsImporter : IDisposable if( modPackFile.Extension != ".ttmp" ) { - PluginLog.Warning( $"File {modPackFile.FullName} seems to be a V1 TTMP, but has the wrong extension." ); + Penumbra.Log.Warning( $"File {modPackFile.FullName} seems to be a V1 TTMP, but has the wrong extension." ); } return ImportV1ModPack( modPackFile, extractedModPack, modRaw ); diff --git a/Penumbra/Import/TexToolsImporter.Archives.cs b/Penumbra/Import/TexToolsImporter.Archives.cs index 5c0371dd..a6403027 100644 --- a/Penumbra/Import/TexToolsImporter.Archives.cs +++ b/Penumbra/Import/TexToolsImporter.Archives.cs @@ -1,7 +1,3 @@ -using System; -using System.IO; -using System.Linq; -using Dalamud.Logging; using Dalamud.Utility; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -13,6 +9,9 @@ using SharpCompress.Archives.SevenZip; using SharpCompress.Archives.Zip; using SharpCompress.Common; using SharpCompress.Readers; +using System; +using System.IO; +using System.Linq; namespace Penumbra.Import; @@ -43,7 +42,7 @@ public partial class TexToolsImporter SevenZipArchive s => s.Entries.Count, _ => archive.Entries.Count(), }; - PluginLog.Log( $" -> Importing {archive.Type} Archive." ); + Penumbra.Log.Information( $" -> Importing {archive.Type} Archive." ); _currentModDirectory = Mod.CreateModFolder( _baseDirectory, Path.GetRandomFileName() ); var options = new ExtractionOptions() @@ -66,7 +65,7 @@ public partial class TexToolsImporter continue; } - PluginLog.Log( " -> Extracting {0}", reader.Entry.Key ); + Penumbra.Log.Information( $" -> Extracting {reader.Entry.Key}" ); // Check that the mod has a valid name in the meta.json file. if( Path.GetFileName( reader.Entry.Key ) == "meta.json" ) { diff --git a/Penumbra/Import/TexToolsImporter.ModPack.cs b/Penumbra/Import/TexToolsImporter.ModPack.cs index 574efb1f..5227b454 100644 --- a/Penumbra/Import/TexToolsImporter.ModPack.cs +++ b/Penumbra/Import/TexToolsImporter.ModPack.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using Dalamud.Logging; using Newtonsoft.Json; using Penumbra.Mods; using Penumbra.Util; @@ -24,7 +23,7 @@ public partial class TexToolsImporter _currentGroupName = string.Empty; _currentOptionName = DefaultTexToolsData.DefaultOption; - PluginLog.Log( " -> Importing V1 ModPack" ); + Penumbra.Log.Information( " -> Importing V1 ModPack" ); var modListRaw = modRaw.Split( new[] { "\r\n", "\r", "\n" }, @@ -62,12 +61,12 @@ public partial class TexToolsImporter try { - PluginLog.Warning( $"Unknown TTMPVersion <{modList.TtmpVersion}> given, trying to export as simple mod pack." ); + Penumbra.Log.Warning( $"Unknown TTMPVersion <{modList.TtmpVersion}> given, trying to export as simple mod pack." ); return ImportSimpleV2ModPack( extractedModPack, modList ); } catch( Exception e1 ) { - PluginLog.Warning( $"Exporting as simple mod pack failed with following error, retrying as extended mod pack:\n{e1}" ); + Penumbra.Log.Warning( $"Exporting as simple mod pack failed with following error, retrying as extended mod pack:\n{e1}" ); try { return ImportExtendedV2ModPack( extractedModPack, modRaw ); @@ -87,7 +86,7 @@ public partial class TexToolsImporter _currentModName = modList.Name; _currentGroupName = string.Empty; _currentOptionName = DefaultTexToolsData.DefaultOption; - PluginLog.Log( " -> Importing Simple V2 ModPack" ); + Penumbra.Log.Information( " -> Importing Simple V2 ModPack" ); _currentModDirectory = Mod.CreateModFolder( _baseDirectory, _currentModName ); Mod.CreateMeta( _currentModDirectory, _currentModName, modList.Author, string.IsNullOrEmpty( modList.Description ) @@ -128,7 +127,7 @@ public partial class TexToolsImporter private DirectoryInfo ImportExtendedV2ModPack( ZipArchive extractedModPack, string modRaw ) { _currentOptionIdx = 0; - PluginLog.Log( " -> Importing Extended V2 ModPack" ); + Penumbra.Log.Information( " -> Importing Extended V2 ModPack" ); var modList = JsonConvert.DeserializeObject< ExtendedModPack >( modRaw, JsonSettings )!; _currentNumOptions = GetOptionCount( modList ); @@ -243,7 +242,7 @@ public partial class TexToolsImporter return; } - PluginLog.Log( " -> Extracting {0} at {1}", mod.FullPath, mod.ModOffset.ToString( "X" ) ); + Penumbra.Log.Information( $" -> Extracting {mod.FullPath} at {mod.ModOffset:X}" ); _token.ThrowIfCancellationRequested(); var data = stream.ReadFile< PenumbraSqPackStream.PenumbraFileResource >( mod.ModOffset ); diff --git a/Penumbra/Import/TexToolsMeta.Deserialization.cs b/Penumbra/Import/TexToolsMeta.Deserialization.cs index 5e79659b..e2428cbb 100644 --- a/Penumbra/Import/TexToolsMeta.Deserialization.cs +++ b/Penumbra/Import/TexToolsMeta.Deserialization.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using Dalamud.Logging; using Lumina.Extensions; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -166,7 +165,7 @@ public partial class TexToolsMeta } catch( Exception e ) { - PluginLog.Warning( + Penumbra.Log.Warning( $"Could not compute IMC manipulation for {metaFileInfo.PrimaryType} {metaFileInfo.PrimaryId}. This is in all likelihood due to TexTools corrupting your index files.\n" + $"If the following error looks like Lumina is having trouble to read an IMC file, please do a do-over in TexTools:\n{e}" ); } diff --git a/Penumbra/Import/TexToolsMeta.Rgsp.cs b/Penumbra/Import/TexToolsMeta.Rgsp.cs index 97ce6915..cc4055ad 100644 --- a/Penumbra/Import/TexToolsMeta.Rgsp.cs +++ b/Penumbra/Import/TexToolsMeta.Rgsp.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using Dalamud.Logging; using Penumbra.GameData.Enums; using Penumbra.Meta.Files; using Penumbra.Meta.Manipulations; @@ -14,7 +13,7 @@ public partial class TexToolsMeta { if( data.Length != 45 && data.Length != 42 ) { - PluginLog.Error( "Error while parsing .rgsp file:\n\tInvalid number of bytes." ); + Penumbra.Log.Error( "Error while parsing .rgsp file:\n\tInvalid number of bytes." ); return Invalid; } @@ -32,7 +31,7 @@ public partial class TexToolsMeta var subRace = ( SubRace )( version == 1 ? flag + 1 : br.ReadByte() + 1 ); if( !Enum.IsDefined( typeof( SubRace ), subRace ) || subRace == SubRace.Unknown ) { - PluginLog.Error( $"Error while parsing .rgsp file:\n\t{subRace} is not a valid SubRace." ); + Penumbra.Log.Error( $"Error while parsing .rgsp file:\n\t{subRace} is not a valid SubRace." ); return Invalid; } @@ -40,7 +39,7 @@ public partial class TexToolsMeta var gender = br.ReadByte(); if( gender != 1 && gender != 0 ) { - PluginLog.Error( $"Error while parsing .rgsp file:\n\t{gender} is neither Male nor Female." ); + Penumbra.Log.Error( $"Error while parsing .rgsp file:\n\t{gender} is neither Male nor Female." ); return Invalid; } diff --git a/Penumbra/Import/TexToolsMeta.cs b/Penumbra/Import/TexToolsMeta.cs index 1a0f05fd..0058764c 100644 --- a/Penumbra/Import/TexToolsMeta.cs +++ b/Penumbra/Import/TexToolsMeta.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using Dalamud.Logging; using Penumbra.Meta.Manipulations; namespace Penumbra.Import; @@ -72,7 +71,7 @@ public partial class TexToolsMeta catch( Exception e ) { FilePath = ""; - PluginLog.Error( $"Error while parsing .meta file:\n{e}" ); + Penumbra.Log.Error( $"Error while parsing .meta file:\n{e}" ); } } diff --git a/Penumbra/Import/Textures/TextureImporter.cs b/Penumbra/Import/Textures/TextureImporter.cs index e029632a..7e62830f 100644 --- a/Penumbra/Import/Textures/TextureImporter.cs +++ b/Penumbra/Import/Textures/TextureImporter.cs @@ -1,8 +1,8 @@ -using System; -using System.IO; using Lumina.Data.Files; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; +using System; +using System.IO; namespace Penumbra.Import.Dds; diff --git a/Penumbra/Interop/CharacterUtility.List.cs b/Penumbra/Interop/CharacterUtility.List.cs new file mode 100644 index 00000000..27146af6 --- /dev/null +++ b/Penumbra/Interop/CharacterUtility.List.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; + +namespace Penumbra.Interop; + +public unsafe partial class CharacterUtility +{ + public class List : IDisposable + { + private readonly LinkedList< MetaReverter > _entries = new(); + public readonly InternalIndex Index; + public readonly Structs.CharacterUtility.Index GlobalIndex; + + private IntPtr _defaultResourceData = IntPtr.Zero; + private int _defaultResourceSize = 0; + public bool Ready { get; private set; } = false; + + public List( InternalIndex index ) + { + Index = index; + GlobalIndex = RelevantIndices[ index.Value ]; + } + + public void SetDefaultResource( IntPtr data, int size ) + { + if( !Ready ) + { + _defaultResourceData = data; + _defaultResourceSize = size; + Ready = _defaultResourceData != IntPtr.Zero && size != 0; + if( _entries.Count > 0 ) + { + var first = _entries.First!.Value; + SetResource( first.Data, first.Length ); + } + } + } + + public (IntPtr Address, int Size) DefaultResource + => ( _defaultResourceData, _defaultResourceSize ); + + public MetaReverter TemporarilySetResource( IntPtr data, int length ) + { + Penumbra.Log.Verbose( $"Temporarily set resource {GlobalIndex} to 0x{( ulong )data:X} ({length} bytes)." ); + var reverter = new MetaReverter( this, data, length ); + _entries.AddFirst( reverter ); + SetResourceInternal( data, length ); + return reverter; + } + + public MetaReverter TemporarilyResetResource() + { + Penumbra.Log.Verbose( $"Temporarily reset resource {GlobalIndex} to default at 0x{_defaultResourceData:X} ({_defaultResourceSize} bytes)." ); + var reverter = new MetaReverter( this ); + _entries.AddFirst( reverter ); + ResetResourceInternal(); + return reverter; + } + + public void SetResource( IntPtr data, int length ) + { + Penumbra.Log.Verbose( $"Set resource {GlobalIndex} to 0x{( ulong )data:X} ({length} bytes)." ); + SetResourceInternal( data, length ); + } + + public void ResetResource() + { + Penumbra.Log.Verbose( $"Reset resource {GlobalIndex} to default at 0x{_defaultResourceData:X} ({_defaultResourceSize} bytes)." ); + ResetResourceInternal(); + } + + + // Set the currently stored data of this resource to new values. + private void SetResourceInternal( IntPtr data, int length ) + { + if( Ready ) + { + var resource = Penumbra.CharacterUtility.Address->Resource( GlobalIndex ); + resource->SetData( data, length ); + } + } + + // Reset the currently stored data of this resource to its default values. + private void ResetResourceInternal() + => SetResourceInternal( _defaultResourceData, _defaultResourceSize ); + + public void Dispose() + { + if( _entries.Count > 0 ) + { + _entries.Clear(); + ResetResourceInternal(); + } + } + + public sealed class MetaReverter : IDisposable + { + public readonly List List; + public readonly IntPtr Data; + public readonly int Length; + public readonly bool Resetter; + + public MetaReverter( List list, IntPtr data, int length ) + { + List = list; + Data = data; + Length = length; + } + + public MetaReverter( List list ) + { + List = list; + Data = IntPtr.Zero; + Length = 0; + Resetter = true; + } + + public void Dispose() + { + var list = List._entries; + var wasCurrent = ReferenceEquals( this, list.First?.Value ); + list.Remove( this ); + if( !wasCurrent ) + { + return; + } + + if( list.Count == 0 ) + { + List.ResetResourceInternal(); + } + else + { + var next = list.First!.Value; + if( next.Resetter ) + { + List.ResetResourceInternal(); + } + else + { + List.SetResourceInternal( next.Data, next.Length ); + } + } + } + } + } +} \ No newline at end of file diff --git a/Penumbra/Interop/CharacterUtility.cs b/Penumbra/Interop/CharacterUtility.cs index 1175eb52..a5b155c1 100644 --- a/Penumbra/Interop/CharacterUtility.cs +++ b/Penumbra/Interop/CharacterUtility.cs @@ -1,11 +1,10 @@ using System; using System.Linq; -using Dalamud.Logging; using Dalamud.Utility.Signatures; namespace Penumbra.Interop; -public unsafe class CharacterUtility : IDisposable +public unsafe partial class CharacterUtility : IDisposable { public record struct InternalIndex( int Value ); @@ -35,22 +34,20 @@ public unsafe class CharacterUtility : IDisposable public static readonly InternalIndex[] ReverseIndices = Enumerable.Range( 0, Structs.CharacterUtility.TotalNumResources ) - .Select( i => new InternalIndex( Array.IndexOf( RelevantIndices, (Structs.CharacterUtility.Index) i ) ) ) + .Select( i => new InternalIndex( Array.IndexOf( RelevantIndices, ( Structs.CharacterUtility.Index )i ) ) ) .ToArray(); - - private readonly (IntPtr Address, int Size)[] _defaultResources = new (IntPtr, int)[RelevantIndices.Length]; - - public (IntPtr Address, int Size) DefaultResource( Structs.CharacterUtility.Index idx ) - => _defaultResources[ ReverseIndices[ ( int )idx ].Value ]; + private readonly List[] _lists = Enumerable.Range( 0, RelevantIndices.Length ) + .Select( idx => new List( new InternalIndex( idx ) ) ) + .ToArray(); public (IntPtr Address, int Size) DefaultResource( InternalIndex idx ) - => _defaultResources[ idx.Value ]; + => _lists[ idx.Value ].DefaultResource; public CharacterUtility() { SignatureHelper.Initialise( this ); - LoadingFinished += () => PluginLog.Debug( "Loading of CharacterUtility finished." ); + LoadingFinished += () => Penumbra.Log.Debug( "Loading of CharacterUtility finished." ); LoadDefaultResources( null! ); if( !Ready ) { @@ -61,30 +58,25 @@ public unsafe class CharacterUtility : IDisposable // We store the default data of the resources so we can always restore them. private void LoadDefaultResources( object _ ) { - var missingCount = 0; if( Address == null ) { return; } + var anyMissing = false; for( var i = 0; i < RelevantIndices.Length; ++i ) { - if( _defaultResources[ i ].Size == 0 ) + var list = _lists[ i ]; + if( !list.Ready ) { - var resource = Address->Resource( RelevantIndices[i] ); - var data = resource->GetData(); - if( data.Data != IntPtr.Zero && data.Length != 0 ) - { - _defaultResources[ i ] = data; - } - else - { - ++missingCount; - } + var resource = Address->Resource( RelevantIndices[ i ] ); + var (data, length) = resource->GetData(); + list.SetDefaultResource( data, length ); + anyMissing |= !_lists[ i ].Ready; } } - if( missingCount == 0 ) + if( !anyMissing ) { Ready = true; LoadingFinished.Invoke(); @@ -92,51 +84,41 @@ public unsafe class CharacterUtility : IDisposable } } - // Set the data of one of the stored resources to a given pointer and length. - public bool SetResource( Structs.CharacterUtility.Index resourceIdx, IntPtr data, int length ) + public void SetResource( Structs.CharacterUtility.Index resourceIdx, IntPtr data, int length ) { - if( !Ready ) - { - PluginLog.Error( $"Can not set resource {resourceIdx}: CharacterUtility not ready yet." ); - return false; - } - - var resource = Address->Resource( resourceIdx ); - var ret = resource->SetData( data, length ); - PluginLog.Verbose( "Set resource {Idx} to 0x{NewData:X} ({NewLength} bytes).", resourceIdx, ( ulong )data, length ); - return ret; + var idx = ReverseIndices[( int )resourceIdx]; + var list = _lists[idx.Value]; + list.SetResource( data, length ); } - // Reset the data of one of the stored resources to its default values. public void ResetResource( Structs.CharacterUtility.Index resourceIdx ) { - if( !Ready ) - { - PluginLog.Error( $"Can not reset {resourceIdx}: CharacterUtility not ready yet." ); - return; - } + var idx = ReverseIndices[( int )resourceIdx]; + var list = _lists[idx.Value]; + list.ResetResource(); + } - var (data, length) = DefaultResource( resourceIdx); - var resource = Address->Resource( resourceIdx ); - PluginLog.Verbose( "Reset resource {Idx} to default at 0x{DefaultData:X} ({NewLength} bytes).", resourceIdx, ( ulong )data, length ); - resource->SetData( data, length ); + public List.MetaReverter TemporarilySetResource( Structs.CharacterUtility.Index resourceIdx, IntPtr data, int length ) + { + var idx = ReverseIndices[ ( int )resourceIdx ]; + var list = _lists[ idx.Value ]; + return list.TemporarilySetResource( data, length ); + } + + public List.MetaReverter TemporarilyResetResource( Structs.CharacterUtility.Index resourceIdx ) + { + var idx = ReverseIndices[ ( int )resourceIdx ]; + var list = _lists[ idx.Value ]; + return list.TemporarilyResetResource(); } // Return all relevant resources to the default resource. public void ResetAll() { - if( !Ready ) + foreach( var list in _lists ) { - PluginLog.Error( "Can not reset all resources: CharacterUtility not ready yet." ); - return; + list.Dispose(); } - - foreach( var idx in RelevantIndices ) - { - ResetResource( idx ); - } - - PluginLog.Debug( "Reset all CharacterUtility resources to default." ); } public void Dispose() diff --git a/Penumbra/Interop/FontReloader.cs b/Penumbra/Interop/FontReloader.cs index aad57199..e084f70c 100644 --- a/Penumbra/Interop/FontReloader.cs +++ b/Penumbra/Interop/FontReloader.cs @@ -1,4 +1,3 @@ -using Dalamud.Logging; using FFXIVClientStructs.FFXIV.Client.System.Framework; using FFXIVClientStructs.FFXIV.Component.GUI; @@ -22,7 +21,7 @@ public static unsafe class FontReloader } else { - PluginLog.Error( "Could not reload fonts, function could not be found." ); + Penumbra.Log.Error( "Could not reload fonts, function could not be found." ); } } diff --git a/Penumbra/Interop/Loader/ResourceLoader.Debug.cs b/Penumbra/Interop/Loader/ResourceLoader.Debug.cs index ada91c0a..f04f2930 100644 --- a/Penumbra/Interop/Loader/ResourceLoader.Debug.cs +++ b/Penumbra/Interop/Loader/ResourceLoader.Debug.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; using Dalamud.Hooking; -using Dalamud.Logging; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; @@ -20,7 +19,7 @@ public unsafe partial class ResourceLoader private readonly Hook< ResourceHandleDecRef > _decRefHook; public delegate IntPtr ResourceHandleDestructor( ResourceHandle* handle ); - + [Signature( "48 89 5C 24 ?? 57 48 83 EC ?? 48 8D 05 ?? ?? ?? ?? 48 8B D9 48 89 01 B8", DetourName = nameof( ResourceHandleDestructorDetour ) )] public static Hook< ResourceHandleDestructor >? ResourceHandleDestructorHook; @@ -29,8 +28,7 @@ public unsafe partial class ResourceLoader { if( handle != null ) { - PluginLog.Information( "[ResourceLoader] Destructing Resource Handle {Path:l} at 0x{Address:X} (Refcount {Refcount}).", - handle->FileName, ( ulong )handle, handle->RefCount ); + Penumbra.Log.Information( $"[ResourceLoader] Destructing Resource Handle {handle->FileName} at 0x{( ulong )handle:X} (Refcount {handle->RefCount})."); } return ResourceHandleDestructorHook!.Original( handle ); @@ -95,7 +93,7 @@ public unsafe partial class ResourceLoader } catch( Exception e ) { - PluginLog.Error( e.ToString() ); + Penumbra.Log.Error( e.ToString() ); } } @@ -236,22 +234,22 @@ public unsafe partial class ResourceLoader return _decRefHook.Original( handle ); } - PluginLog.Error( $"Caught decrease of Reference Counter for {handle->FileName} at 0x{( ulong )handle:X} below 0." ); + Penumbra.Log.Error( $"Caught decrease of Reference Counter for {handle->FileName} at 0x{( ulong )handle:X} below 0." ); return 1; } // Logging functions for EnableFullLogging. private static void LogPath( Utf8GamePath path, bool synchronous ) - => PluginLog.Information( $"[ResourceLoader] Requested {path} {( synchronous ? "synchronously." : "asynchronously." )}" ); + => Penumbra.Log.Information( $"[ResourceLoader] Requested {path} {( synchronous ? "synchronously." : "asynchronously." )}" ); private static void LogResource( Structs.ResourceHandle* handle, Utf8GamePath path, FullPath? manipulatedPath, ResolveData _ ) { var pathString = manipulatedPath != null ? $"custom file {manipulatedPath} instead of {path}" : path.ToString(); - PluginLog.Information( $"[ResourceLoader] Loaded {pathString} to 0x{( ulong )handle:X}. (Refcount {handle->RefCount})" ); + Penumbra.Log.Information( $"[ResourceLoader] Loaded {pathString} to 0x{( ulong )handle:X}. (Refcount {handle->RefCount})" ); } private static void LogLoadedFile( Utf8String path, bool success, bool custom ) - => PluginLog.Information( success + => Penumbra.Log.Information( success ? $"[ResourceLoader] Loaded {path} from {( custom ? "local files" : "SqPack" )}" : $"[ResourceLoader] Failed to load {path} from {( custom ? "local files" : "SqPack" )}." ); } \ No newline at end of file diff --git a/Penumbra/Interop/Loader/ResourceLoader.Replacement.cs b/Penumbra/Interop/Loader/ResourceLoader.Replacement.cs index afd18d2a..f0cd656b 100644 --- a/Penumbra/Interop/Loader/ResourceLoader.Replacement.cs +++ b/Penumbra/Interop/Loader/ResourceLoader.Replacement.cs @@ -1,12 +1,9 @@ using System; -using System.Collections.Concurrent; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Dalamud.Hooking; -using Dalamud.Logging; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.System.Resource; using Penumbra.Collections; @@ -68,7 +65,7 @@ public unsafe partial class ResourceLoader { if( local != game ) { - PluginLog.Warning( "Hash function appears to have changed. Computed {Hash1:X8} vs Game {Hash2:X8} for {Path}.", local, game, path ); + Penumbra.Log.Warning( $"Hash function appears to have changed. Computed {local:X8} vs Game {game:X8} for {path}." ); } } @@ -79,7 +76,7 @@ public unsafe partial class ResourceLoader { if( !Utf8GamePath.FromPointer( path, out var gamePath ) ) { - PluginLog.Error( "Could not create GamePath from resource path." ); + Penumbra.Log.Error( "Could not create GamePath from resource path." ); return CallOriginalHandler( isSync, resourceManager, categoryId, resourceType, resourceHash, path, pGetResParams, isUnk ); } @@ -161,7 +158,7 @@ public unsafe partial class ResourceLoader if( fileDescriptor == null || fileDescriptor->ResourceHandle == null ) { - PluginLog.Error( "Failure to load file from SqPack: invalid File Descriptor." ); + Penumbra.Log.Error( "Failure to load file from SqPack: invalid File Descriptor." ); return ReadSqPackHook.Original( resourceManager, fileDescriptor, priority, isSync ); } diff --git a/Penumbra/Interop/Loader/ResourceLogger.cs b/Penumbra/Interop/Loader/ResourceLogger.cs index 278aea7d..25d8ea59 100644 --- a/Penumbra/Interop/Loader/ResourceLogger.cs +++ b/Penumbra/Interop/Loader/ResourceLogger.cs @@ -1,6 +1,5 @@ using System; using System.Text.RegularExpressions; -using Dalamud.Logging; using Penumbra.GameData.ByteString; namespace Penumbra.Interop.Loader; @@ -79,7 +78,7 @@ public class ResourceLogger : IDisposable var path = Match( data.Path ); if( path != null ) { - PluginLog.Information( $"{path} was requested {( synchronous ? "synchronously." : "asynchronously." )}" ); + Penumbra.Log.Information( $"{path} was requested {( synchronous ? "synchronously." : "asynchronously." )}" ); } } diff --git a/Penumbra/Interop/ResidentResourceManager.cs b/Penumbra/Interop/ResidentResourceManager.cs index f533a7ba..37ed1bfe 100644 --- a/Penumbra/Interop/ResidentResourceManager.cs +++ b/Penumbra/Interop/ResidentResourceManager.cs @@ -1,4 +1,3 @@ -using Dalamud.Logging; using Dalamud.Utility.Signatures; namespace Penumbra.Interop; @@ -31,7 +30,7 @@ public unsafe class ResidentResourceManager { if( Address != null && Address->NumResources > 0 ) { - PluginLog.Debug( "Reload of resident resources triggered." ); + Penumbra.Log.Debug( "Reload of resident resources triggered." ); UnloadPlayerResources.Invoke( Address ); LoadPlayerResources.Invoke( Address ); } diff --git a/Penumbra/Interop/Resolver/PathResolver.AnimationState.cs b/Penumbra/Interop/Resolver/PathResolver.AnimationState.cs index 7211d109..9a38bf56 100644 --- a/Penumbra/Interop/Resolver/PathResolver.AnimationState.cs +++ b/Penumbra/Interop/Resolver/PathResolver.AnimationState.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; using Dalamud.Hooking; using Dalamud.Utility.Signatures; using Penumbra.Collections; diff --git a/Penumbra/Interop/Resolver/PathResolver.DrawObjectState.cs b/Penumbra/Interop/Resolver/PathResolver.DrawObjectState.cs index 7c9690fc..d6e6ec0e 100644 --- a/Penumbra/Interop/Resolver/PathResolver.DrawObjectState.cs +++ b/Penumbra/Interop/Resolver/PathResolver.DrawObjectState.cs @@ -3,7 +3,6 @@ using Dalamud.Utility.Signatures; using Penumbra.Collections; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using FFXIVClientStructs.FFXIV.Client.Game.Object; using Penumbra.Api; @@ -55,7 +54,7 @@ public unsafe partial class PathResolver public bool HandleDecalFile( ResourceType type, Utf8GamePath gamePath, out ResolveData resolveData ) { - if( type == ResourceType.Tex + if( type == ResourceType.Tex && LastCreatedCollection.Valid && gamePath.Path.Substring( "chara/common/texture/".Length ).StartsWith( 'd', 'e', 'c', 'a', 'l', '_', 'f', 'a', 'c', 'e' ) ) { @@ -124,7 +123,7 @@ public unsafe partial class PathResolver // This map links DrawObjects directly to Actors (by ObjectTable index) and their collections. // It contains any DrawObjects that correspond to a human actor, even those without specific collections. - private readonly Dictionary< IntPtr, (ResolveData, int) > _drawObjectToObject = new(); + private readonly Dictionary< IntPtr, (ResolveData, int) > _drawObjectToObject = new(); private ResolveData _lastCreatedCollection = ResolveData.Invalid; // Keep track of created DrawObjects that are CharacterBase, @@ -136,22 +135,37 @@ public unsafe partial class PathResolver private IntPtr CharacterBaseCreateDetour( uint a, IntPtr b, IntPtr c, byte d ) { - using var cmp = MetaChanger.ChangeCmp( LastGameObject, out _lastCreatedCollection ); - + CharacterUtility.List.MetaReverter? cmp = null; if( LastGameObject != null ) { + _lastCreatedCollection = IdentifyCollection( LastGameObject ); var modelPtr = &a; - CreatingCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection, ( IntPtr )modelPtr, b, c ); + if( _lastCreatedCollection.ModCollection != Penumbra.CollectionManager.Default ) + { + cmp = _lastCreatedCollection.ModCollection.TemporarilySetCmpFile(); + } + + try + { + CreatingCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection, ( IntPtr )modelPtr, b, c ); + } + catch( Exception e ) + { + Penumbra.Log.Error( $"Unknown Error during CreatingCharacterBase:\n{e}" ); + } } var ret = _characterBaseCreateHook.Original( a, b, c, d ); - if( LastGameObject != null ) + using( cmp ) { - _drawObjectToObject[ ret ] = ( _lastCreatedCollection!, LastGameObject->ObjectIndex ); - CreatedCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection, ret ); - } + if( LastGameObject != null ) + { + _drawObjectToObject[ ret ] = ( _lastCreatedCollection!, LastGameObject->ObjectIndex ); + CreatedCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection, ret ); + } - return ret; + return ret; + } } diff --git a/Penumbra/Interop/Resolver/PathResolver.Identification.cs b/Penumbra/Interop/Resolver/PathResolver.Identification.cs index 39efe25b..8b038a54 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Identification.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Identification.cs @@ -1,17 +1,14 @@ using System; using System.Diagnostics.CodeAnalysis; -using Dalamud.Logging; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Object; -using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; using Lumina.Excel.GeneratedSheets; using Penumbra.Collections; using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; using CustomizeData = Penumbra.GameData.Structs.CustomizeData; using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; @@ -41,10 +38,10 @@ public unsafe partial class PathResolver } var ui = ( AtkUnitBase* )addon; - var nodeId = Dalamud.GameData.GetExcelSheet< Title >()?.GetRow( *_inspectTitleId )?.IsPrefix == true ? 2u : 6u; + var nodeId = Dalamud.GameData.GetExcelSheet< Title >()?.GetRow( *_inspectTitleId )?.IsPrefix == true ? 7u : 6u; var text = ( AtkTextNode* )ui->UldManager.SearchNodeById( nodeId ); - return text != null ? text->NodeText.ToString() : null; + return text != null && text->AtkResNode.Type == NodeType.Text ? text->NodeText.ToString() : null; } // Obtain the name displayed in the Character Card from the agent. @@ -205,7 +202,7 @@ public unsafe partial class PathResolver } catch( Exception e ) { - PluginLog.Error( $"Error identifying collection:\n{e}" ); + Penumbra.Log.Error( $"Error identifying collection:\n{e}" ); return Penumbra.CollectionManager.Default.ToResolveData( gameObject ); } } @@ -245,7 +242,7 @@ public unsafe partial class PathResolver collection = null; // Check for the Yourself collection. if( actor->ObjectIndex == 0 - || actor->ObjectIndex == ObjectReloader.GPosePlayerIdx && name.Length > 0 + || Cutscenes.GetParentIndex(actor->ObjectIndex) == 0 || name == Dalamud.ClientState.LocalPlayer?.Name.ToString() ) { collection = Penumbra.CollectionManager.ByType( CollectionType.Yourself ); diff --git a/Penumbra/Interop/Resolver/PathResolver.Material.cs b/Penumbra/Interop/Resolver/PathResolver.Material.cs index 6e81dbac..baf333f2 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Material.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Material.cs @@ -1,8 +1,6 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Hooking; -using Dalamud.Logging; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.System.Resource; using Penumbra.Collections; @@ -95,7 +93,7 @@ public unsafe partial class PathResolver || Penumbra.CollectionManager.ByName( name, out collection ) ) { #if DEBUG - PluginLog.Verbose( "Using MtrlLoadHandler with collection {$Split:l} for path {$Path:l}.", name, path ); + Penumbra.Log.Verbose( $"Using MtrlLoadHandler with collection {name} for path {path}." ); #endif var objFromObjTable = Dalamud.Objects.FirstOrDefault( f => f.Name.TextValue == name ); @@ -105,7 +103,7 @@ public unsafe partial class PathResolver else { #if DEBUG - PluginLog.Verbose( "Using MtrlLoadHandler with no collection for path {$Path:l}.", path ); + Penumbra.Log.Verbose( $"Using MtrlLoadHandler with no collection for path {path}." ); #endif } diff --git a/Penumbra/Interop/Resolver/PathResolver.Meta.cs b/Penumbra/Interop/Resolver/PathResolver.Meta.cs index e305b6db..ba52182a 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Meta.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Meta.cs @@ -1,10 +1,9 @@ using System; using Dalamud.Hooking; using Dalamud.Utility.Signatures; -using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Penumbra.Collections; -using Penumbra.Meta.Manipulations; +using Penumbra.GameData.Enums; +using ObjectType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType; namespace Penumbra.Interop.Resolver; @@ -30,17 +29,13 @@ namespace Penumbra.Interop.Resolver; // ChangeCustomize and RspSetupCharacter, which is hooked here. // GMP Entries seem to be only used by "48 8B ?? 53 55 57 48 83 ?? ?? 48 8B", which has a DrawObject as its first parameter. - public unsafe partial class PathResolver { - public unsafe class MetaState : IDisposable + public class MetaState : IDisposable { - private readonly PathResolver _parent; - - public MetaState( PathResolver parent, IntPtr* humanVTable ) + public MetaState( IntPtr* humanVTable ) { SignatureHelper.Initialise( this ); - _parent = parent; _onModelLoadCompleteHook = Hook< OnModelLoadCompleteDelegate >.FromAddress( humanVTable[ 58 ], OnModelLoadCompleteDetour ); } @@ -82,8 +77,10 @@ public unsafe partial class PathResolver var collection = GetResolveData( drawObject ); if( collection.Valid ) { - using var eqp = MetaChanger.ChangeEqp( collection.ModCollection ); - using var eqdp = MetaChanger.ChangeEqdp( collection.ModCollection ); + var race = GetDrawObjectGenderRace( drawObject ); + using var eqp = collection.ModCollection.TemporarilySetEqpFile(); + using var eqdp1 = collection.ModCollection.TemporarilySetEqdpFile( race, false ); + using var eqdp2 = collection.ModCollection.TemporarilySetEqdpFile( race, true ); _onModelLoadCompleteHook.Original.Invoke( drawObject ); } else @@ -109,8 +106,10 @@ public unsafe partial class PathResolver var collection = GetResolveData( drawObject ); if( collection.Valid ) { - using var eqp = MetaChanger.ChangeEqp( collection.ModCollection ); - using var eqdp = MetaChanger.ChangeEqdp( collection.ModCollection ); + var race = GetDrawObjectGenderRace( drawObject ); + using var eqp = collection.ModCollection.TemporarilySetEqpFile(); + using var eqdp1 = collection.ModCollection.TemporarilySetEqdpFile( race, false ); + using var eqdp2 = collection.ModCollection.TemporarilySetEqdpFile( race, true ); _updateModelsHook.Original.Invoke( drawObject ); } else @@ -119,6 +118,24 @@ public unsafe partial class PathResolver } } + private static GenderRace GetDrawObjectGenderRace( IntPtr drawObject ) + { + var draw = ( DrawObject* )drawObject; + if( draw->Object.GetObjectType() == ObjectType.CharacterBase ) + { + var c = ( CharacterBase* )drawObject; + if( c->GetModelType() == CharacterBase.ModelType.Human ) + { + return GetHumanGenderRace( drawObject ); + } + } + + return GenderRace.Unknown; + } + + public static GenderRace GetHumanGenderRace( IntPtr human ) + => ( GenderRace )( ( Human* )human )->RaceSexId; + [Signature( "40 ?? 48 83 ?? ?? ?? 81 ?? ?? ?? ?? ?? 48 8B ?? 74 ?? ?? 83 ?? ?? ?? ?? ?? ?? 74 ?? 4C", DetourName = nameof( GetEqpIndirectDetour ) )] private readonly Hook< OnModelLoadCompleteDelegate > _getEqpIndirectHook = null!; @@ -132,7 +149,8 @@ public unsafe partial class PathResolver return; } - using var eqp = MetaChanger.ChangeEqp( _parent, drawObject ); + var resolveData = GetResolveData( drawObject ); + using var eqp = resolveData.Valid ? resolveData.ModCollection.TemporarilySetEqpFile() : null; _getEqpIndirectHook.Original( drawObject ); } @@ -146,7 +164,8 @@ public unsafe partial class PathResolver private byte SetupVisorDetour( IntPtr drawObject, ushort modelId, byte visorState ) { - using var gmp = MetaChanger.ChangeGmp( _parent, drawObject ); + var resolveData = GetResolveData( drawObject ); + using var eqp = resolveData.Valid ? resolveData.ModCollection.TemporarilySetGmpFile() : null; return _setupVisorHook.Original( drawObject, modelId, visorState ); } @@ -164,13 +183,14 @@ public unsafe partial class PathResolver } else { - using var rsp = MetaChanger.ChangeCmp( _parent, drawObject ); + var resolveData = GetResolveData( drawObject ); + using var eqp = resolveData.Valid ? resolveData.ModCollection.TemporarilySetCmpFile() : null; _rspSetupCharacterHook.Original( drawObject, unk2, unk3, unk4, unk5 ); } } // ChangeCustomize calls RspSetupCharacter, so skip the additional cmp change. - private bool _inChangeCustomize = false; + private bool _inChangeCustomize; private delegate bool ChangeCustomizeDelegate( IntPtr human, IntPtr data, byte skipEquipment ); [Signature( "E8 ?? ?? ?? ?? 41 0F B6 C5 66 41 89 86", DetourName = nameof( ChangeCustomizeDetour ) )] @@ -179,154 +199,9 @@ public unsafe partial class PathResolver private bool ChangeCustomizeDetour( IntPtr human, IntPtr data, byte skipEquipment ) { _inChangeCustomize = true; - using var rsp = MetaChanger.ChangeCmp( _parent, human ); + var resolveData = GetResolveData( human ); + using var eqp = resolveData.Valid ? resolveData.ModCollection.TemporarilySetEqpFile() : null; return _changeCustomize.Original( human, data, skipEquipment ); } } - - // Small helper to handle setting metadata and reverting it at the end of the function. - // Since eqp and eqdp may be called multiple times in a row, we need to count them, - // so that we do not reset the files too early. - private readonly struct MetaChanger : IDisposable - { - private static int _eqpCounter; - private static int _eqdpCounter; - private readonly MetaManipulation.Type _type; - - private MetaChanger( MetaManipulation.Type type ) - { - _type = type; - if( type == MetaManipulation.Type.Eqp ) - { - ++_eqpCounter; - } - else if( type == MetaManipulation.Type.Eqdp ) - { - ++_eqdpCounter; - } - } - - public static MetaChanger ChangeEqp( ModCollection collection ) - { - collection.SetEqpFiles(); - return new MetaChanger( MetaManipulation.Type.Eqp ); - } - - public static MetaChanger ChangeEqp( PathResolver _, IntPtr drawObject ) - { - var resolveData = GetResolveData( drawObject ); - if( resolveData.Valid ) - { - return ChangeEqp( resolveData.ModCollection ); - } - - return new MetaChanger( MetaManipulation.Type.Unknown ); - } - - // We only need to change anything if it is actually equipment here. - public static MetaChanger ChangeEqdp( PathResolver _, IntPtr drawObject, uint modelType ) - { - if( modelType < 10 ) - { - var collection = GetResolveData( drawObject ); - if( collection.Valid ) - { - return ChangeEqdp( collection.ModCollection ); - } - } - - return new MetaChanger( MetaManipulation.Type.Unknown ); - } - - public static MetaChanger ChangeEqdp( ModCollection collection ) - { - collection.SetEqdpFiles(); - return new MetaChanger( MetaManipulation.Type.Eqdp ); - } - - public static MetaChanger ChangeGmp( PathResolver resolver, IntPtr drawObject ) - { - var resolveData = GetResolveData( drawObject ); - if( resolveData.Valid ) - { - resolveData.ModCollection.SetGmpFiles(); - return new MetaChanger( MetaManipulation.Type.Gmp ); - } - - return new MetaChanger( MetaManipulation.Type.Unknown ); - } - - public static MetaChanger ChangeEst( PathResolver resolver, IntPtr drawObject ) - { - var resolveData = GetResolveData( drawObject ); - if( resolveData.Valid ) - { - resolveData.ModCollection.SetEstFiles(); - return new MetaChanger( MetaManipulation.Type.Est ); - } - - return new MetaChanger( MetaManipulation.Type.Unknown ); - } - - public static MetaChanger ChangeCmp( GameObject* gameObject, out ResolveData resolveData ) - { - if( gameObject != null ) - { - resolveData = IdentifyCollection( gameObject ); - if( resolveData.ModCollection != Penumbra.CollectionManager.Default && resolveData.ModCollection.HasCache ) - { - resolveData.ModCollection.SetCmpFiles(); - return new MetaChanger( MetaManipulation.Type.Rsp ); - } - } - else - { - resolveData = ResolveData.Invalid; - } - - return new MetaChanger( MetaManipulation.Type.Unknown ); - } - - public static MetaChanger ChangeCmp( PathResolver resolver, IntPtr drawObject ) - { - var resolveData = GetResolveData( drawObject ); - if( resolveData.Valid ) - { - resolveData.ModCollection.SetCmpFiles(); - return new MetaChanger( MetaManipulation.Type.Rsp ); - } - - return new MetaChanger( MetaManipulation.Type.Unknown ); - } - - public void Dispose() - { - switch( _type ) - { - case MetaManipulation.Type.Eqdp: - if( --_eqdpCounter == 0 ) - { - Penumbra.CollectionManager.Default.SetEqdpFiles(); - } - - break; - case MetaManipulation.Type.Eqp: - if( --_eqpCounter == 0 ) - { - Penumbra.CollectionManager.Default.SetEqpFiles(); - } - - break; - case MetaManipulation.Type.Est: - Penumbra.CollectionManager.Default.SetEstFiles(); - break; - case MetaManipulation.Type.Gmp: - Penumbra.CollectionManager.Default.SetGmpFiles(); - break; - case MetaManipulation.Type.Rsp: - Penumbra.CollectionManager.Default.SetCmpFiles(); - break; - } - } - } } \ No newline at end of file diff --git a/Penumbra/Interop/Resolver/PathResolver.PathState.cs b/Penumbra/Interop/Resolver/PathResolver.PathState.cs index f5c11771..a9bd1ee0 100644 --- a/Penumbra/Interop/Resolver/PathResolver.PathState.cs +++ b/Penumbra/Interop/Resolver/PathResolver.PathState.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Dalamud.Utility.Signatures; using Penumbra.Collections; diff --git a/Penumbra/Interop/Resolver/PathResolver.ResolverHooks.cs b/Penumbra/Interop/Resolver/PathResolver.ResolverHooks.cs index 02729c07..b5335dc8 100644 --- a/Penumbra/Interop/Resolver/PathResolver.ResolverHooks.cs +++ b/Penumbra/Interop/Resolver/PathResolver.ResolverHooks.cs @@ -2,7 +2,9 @@ using System; using System.Runtime.CompilerServices; using Dalamud.Hooking; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Penumbra.Collections; +using OtterGui.Classes; +using Penumbra.GameData.Enums; +using Penumbra.Meta.Manipulations; namespace Penumbra.Interop.Resolver; @@ -141,34 +143,64 @@ public partial class PathResolver private IntPtr ResolveMdlHuman( IntPtr drawObject, IntPtr path, IntPtr unk3, uint modelType ) { - using var eqdp = MetaChanger.ChangeEqdp( _parent, drawObject, modelType ); + CharacterUtility.List.MetaReverter? Get() + { + if( modelType > 9 ) + { + return null; + } + + var race = MetaState.GetHumanGenderRace( drawObject ); + if( race == GenderRace.Unknown ) + { + return null; + } + + var data = GetResolveData( drawObject ); + return !data.Valid ? null : data.ModCollection.TemporarilySetEqdpFile( race, modelType > 4 ); + } + + using var eqdp = Get(); return ResolvePath( drawObject, _resolveMdlPathHook.Original( drawObject, path, unk3, modelType ) ); } private IntPtr ResolvePapHuman( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 ) { - using var est = MetaChanger.ChangeEst( _parent, drawObject ); + using var est = GetEstChanges( drawObject ); return ResolvePath( drawObject, _resolvePapPathHook.Original( drawObject, path, unk3, unk4, unk5 ) ); } private IntPtr ResolvePhybHuman( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) { - using var est = MetaChanger.ChangeEst( _parent, drawObject ); + using var est = GetEstChanges( drawObject ); return ResolvePath( drawObject, _resolvePhybPathHook.Original( drawObject, path, unk3, unk4 ) ); } private IntPtr ResolveSklbHuman( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) { - using var est = MetaChanger.ChangeEst( _parent, drawObject ); + using var est = GetEstChanges( drawObject ); return ResolvePath( drawObject, _resolveSklbPathHook.Original( drawObject, path, unk3, unk4 ) ); } private IntPtr ResolveSkpHuman( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) { - using var est = MetaChanger.ChangeEst( _parent, drawObject ); + using var est = GetEstChanges( drawObject ); return ResolvePath( drawObject, _resolveSkpPathHook.Original( drawObject, path, unk3, unk4 ) ); } + private DisposableContainer GetEstChanges( IntPtr drawObject ) + { + var data = GetResolveData( drawObject ); + if( !data.Valid ) + { + return DisposableContainer.Empty; + } + + return new DisposableContainer( data.ModCollection.TemporarilySetEstFile( EstManipulation.EstType.Face ), + data.ModCollection.TemporarilySetEstFile( EstManipulation.EstType.Body ), + data.ModCollection.TemporarilySetEstFile( EstManipulation.EstType.Hair ), + data.ModCollection.TemporarilySetEstFile( EstManipulation.EstType.Head ) ); + } private IntPtr ResolveDecalWeapon( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) => ResolveWeaponPath( drawObject, _resolveDecalPathHook.Original( drawObject, path, unk3, unk4 ) ); @@ -227,9 +259,10 @@ public partial class PathResolver // Implementation [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] private IntPtr ResolvePath( IntPtr drawObject, IntPtr path ) - => _parent._paths.ResolvePath( (IntPtr?)FindParent( drawObject, out _) ?? IntPtr.Zero, FindParent( drawObject, out var collection ) == null - ? Penumbra.CollectionManager.Default - : collection.ModCollection, path ); + => _parent._paths.ResolvePath( ( IntPtr? )FindParent( drawObject, out _ ) ?? IntPtr.Zero, + FindParent( drawObject, out var collection ) == null + ? Penumbra.CollectionManager.Default + : collection.ModCollection, path ); // Weapons have the characters DrawObject as a parent, // but that may not be set yet when creating a new object, so we have to do the same detour @@ -240,18 +273,18 @@ public partial class PathResolver var parent = FindParent( drawObject, out var collection ); if( parent != null ) { - return _parent._paths.ResolvePath( (IntPtr)parent, collection.ModCollection, path ); + return _parent._paths.ResolvePath( ( IntPtr )parent, collection.ModCollection, path ); } var parentObject = ( IntPtr )( ( DrawObject* )drawObject )->Object.ParentObject; var parentCollection = DrawObjects.CheckParentDrawObject( drawObject, parentObject ); if( parentCollection.Valid ) { - return _parent._paths.ResolvePath( (IntPtr)FindParent(parentObject, out _), parentCollection.ModCollection, path ); + return _parent._paths.ResolvePath( ( IntPtr )FindParent( parentObject, out _ ), parentCollection.ModCollection, path ); } parent = FindParent( parentObject, out collection ); - return _parent._paths.ResolvePath( (IntPtr?)parent ?? IntPtr.Zero, parent == null + return _parent._paths.ResolvePath( ( IntPtr? )parent ?? IntPtr.Zero, parent == null ? Penumbra.CollectionManager.Default : collection.ModCollection, path ); } diff --git a/Penumbra/Interop/Resolver/PathResolver.cs b/Penumbra/Interop/Resolver/PathResolver.cs index 06536b30..6b1d76a4 100644 --- a/Penumbra/Interop/Resolver/PathResolver.cs +++ b/Penumbra/Interop/Resolver/PathResolver.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Dalamud.Logging; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; @@ -35,7 +34,7 @@ public partial class PathResolver : IDisposable _loader = loader; _animations = new AnimationState( DrawObjects ); _paths = new PathState( this ); - _meta = new MetaState( this, _paths.HumanVTable ); + _meta = new MetaState( _paths.HumanVTable ); _materials = new MaterialState( _paths ); } @@ -84,7 +83,7 @@ public partial class PathResolver : IDisposable _materials.Enable(); _loader.ResolvePathCustomization += CharacterResolver; - PluginLog.Debug( "Character Path Resolver enabled." ); + Penumbra.Log.Debug( "Character Path Resolver enabled." ); } public void Disable() @@ -103,7 +102,7 @@ public partial class PathResolver : IDisposable _materials.Disable(); _loader.ResolvePathCustomization -= CharacterResolver; - PluginLog.Debug( "Character Path Resolver disabled." ); + Penumbra.Log.Debug( "Character Path Resolver disabled." ); } public void Dispose() diff --git a/Penumbra/Interop/Structs/ResourceHandle.cs b/Penumbra/Interop/Structs/ResourceHandle.cs index 88f38dca..6b3a8a72 100644 --- a/Penumbra/Interop/Structs/ResourceHandle.cs +++ b/Penumbra/Interop/Structs/ResourceHandle.cs @@ -2,7 +2,6 @@ using System; using System.Runtime.InteropServices; using FFXIVClientStructs.FFXIV.Client.System.Resource; using Penumbra.GameData.Enums; -using Penumbra.Interop.Resolver; namespace Penumbra.Interop.Structs; diff --git a/Penumbra/Meta/Files/EqpGmpFile.cs b/Penumbra/Meta/Files/EqpGmpFile.cs index e6f48a3d..60649952 100644 --- a/Penumbra/Meta/Files/EqpGmpFile.cs +++ b/Penumbra/Meta/Files/EqpGmpFile.cs @@ -2,7 +2,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.Numerics; -using System.Runtime.CompilerServices; using Penumbra.GameData.Structs; using Penumbra.GameData.Util; using Penumbra.Interop.Structs; diff --git a/Penumbra/Meta/Files/ImcFile.cs b/Penumbra/Meta/Files/ImcFile.cs index b6e631a3..dc9fe001 100644 --- a/Penumbra/Meta/Files/ImcFile.cs +++ b/Penumbra/Meta/Files/ImcFile.cs @@ -1,6 +1,5 @@ using System; using System.Numerics; -using Dalamud.Logging; using Newtonsoft.Json; using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; @@ -125,7 +124,7 @@ public unsafe class ImcFile : MetaBaseFile if( ActualLength > Length ) { var newLength = ( ( ( ActualLength - 1 ) >> 7 ) + 1 ) << 7; - PluginLog.Verbose( "Resized IMC {Path} from {Length} to {NewLength}.", Path, Length, newLength ); + Penumbra.Log.Verbose( $"Resized IMC {Path} from {Length} to {newLength}." ); ResizeResources( newLength ); } @@ -135,7 +134,7 @@ public unsafe class ImcFile : MetaBaseFile Functions.MemCpyUnchecked( defaultPtr + i * NumParts, defaultPtr, NumParts * sizeof( ImcEntry ) ); } - PluginLog.Verbose( "Expanded IMC {Path} from {Count} to {NewCount} variants.", Path, oldCount, numVariants ); + Penumbra.Log.Verbose( $"Expanded IMC {Path} from {oldCount} to {numVariants} variants." ); return true; } @@ -151,7 +150,7 @@ public unsafe class ImcFile : MetaBaseFile var variantPtr = VariantPtr( Data, partIdx, variantIdx ); if( variantPtr == null ) { - PluginLog.Error( "Error during expansion of imc file." ); + Penumbra.Log.Error( "Error during expansion of imc file." ); return false; } @@ -222,7 +221,7 @@ public unsafe class ImcFile : MetaBaseFile var newData = Penumbra.MetaFileManager.AllocateDefaultMemory( ActualLength, 8 ); if( newData == null ) { - PluginLog.Error("Could not replace loaded IMC data at 0x{Data:X}, allocation failed." ); + Penumbra.Log.Error($"Could not replace loaded IMC data at 0x{(ulong) resource:X}, allocation failed." ); return; } Functions.MemCpyUnchecked( newData, Data, ActualLength ); diff --git a/Penumbra/Meta/Manager/MetaManager.Cmp.cs b/Penumbra/Meta/Manager/MetaManager.Cmp.cs index b624a360..8cd17a1e 100644 --- a/Penumbra/Meta/Manager/MetaManager.Cmp.cs +++ b/Penumbra/Meta/Manager/MetaManager.Cmp.cs @@ -18,6 +18,9 @@ public partial class MetaManager public static void ResetCmpFiles() => SetFile( null, CharacterUtility.Index.HumanCmp ); + public Interop.CharacterUtility.List.MetaReverter TemporarilySetCmpFile() + => TemporarilySetFile( _cmpFile, CharacterUtility.Index.HumanCmp ); + public void ResetCmp() { if( _cmpFile == null ) diff --git a/Penumbra/Meta/Manager/MetaManager.Eqdp.cs b/Penumbra/Meta/Manager/MetaManager.Eqdp.cs index dc9a31d6..35857be0 100644 --- a/Penumbra/Meta/Manager/MetaManager.Eqdp.cs +++ b/Penumbra/Meta/Manager/MetaManager.Eqdp.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using OtterGui; using OtterGui.Filesystem; using Penumbra.GameData.Enums; using Penumbra.Interop.Structs; @@ -23,6 +24,21 @@ public partial class MetaManager } } + public Interop.CharacterUtility.List.MetaReverter? TemporarilySetEqdpFile( GenderRace genderRace, bool accessory ) + { + var idx = CharacterUtility.EqdpIdx( genderRace, accessory ); + if( ( int )idx != -1 ) + { + var i = CharacterUtility.EqdpIndices.IndexOf( idx ); + if( i != -1 ) + { + return TemporarilySetFile( _eqdpFiles[ i ], idx ); + } + } + + return null; + } + public static void ResetEqdpFiles() { foreach( var idx in CharacterUtility.EqdpIndices ) @@ -33,7 +49,7 @@ public partial class MetaManager public void ResetEqdp() { - foreach( var file in _eqdpFiles.OfType() ) + foreach( var file in _eqdpFiles.OfType< ExpandedEqdpFile >() ) { var relevant = Interop.CharacterUtility.RelevantIndices[ file.Index.Value ]; file.Reset( _eqdpManipulations.Where( m => m.FileIndex() == relevant ).Select( m => ( int )m.SetId ) ); diff --git a/Penumbra/Meta/Manager/MetaManager.Eqp.cs b/Penumbra/Meta/Manager/MetaManager.Eqp.cs index adae4378..7a5da091 100644 --- a/Penumbra/Meta/Manager/MetaManager.Eqp.cs +++ b/Penumbra/Meta/Manager/MetaManager.Eqp.cs @@ -18,6 +18,9 @@ public partial class MetaManager public static void ResetEqpFiles() => SetFile( null, CharacterUtility.Index.Eqp ); + public Interop.CharacterUtility.List.MetaReverter TemporarilySetEqpFile() + => TemporarilySetFile( _eqpFile, CharacterUtility.Index.Eqp ); + public void ResetEqp() { if( _eqpFile == null ) diff --git a/Penumbra/Meta/Manager/MetaManager.Est.cs b/Penumbra/Meta/Manager/MetaManager.Est.cs index 728a024d..193e749d 100644 --- a/Penumbra/Meta/Manager/MetaManager.Est.cs +++ b/Penumbra/Meta/Manager/MetaManager.Est.cs @@ -33,6 +33,20 @@ public partial class MetaManager SetFile( null, CharacterUtility.Index.HeadEst ); } + public Interop.CharacterUtility.List.MetaReverter? TemporarilySetEstFile(EstManipulation.EstType type) + { + var (file, idx) = type switch + { + EstManipulation.EstType.Face => ( _estFaceFile, CharacterUtility.Index.FaceEst ), + EstManipulation.EstType.Hair => ( _estHairFile, CharacterUtility.Index.HairEst ), + EstManipulation.EstType.Body => ( _estBodyFile, CharacterUtility.Index.BodyEst ), + EstManipulation.EstType.Head => ( _estHeadFile, CharacterUtility.Index.HeadEst ), + _ => ( null, 0 ), + }; + + return idx != 0 ? TemporarilySetFile( file, idx ) : null; + } + public void ResetEst() { _estFaceFile?.Reset(); diff --git a/Penumbra/Meta/Manager/MetaManager.Gmp.cs b/Penumbra/Meta/Manager/MetaManager.Gmp.cs index df35cace..02e1dc78 100644 --- a/Penumbra/Meta/Manager/MetaManager.Gmp.cs +++ b/Penumbra/Meta/Manager/MetaManager.Gmp.cs @@ -1,12 +1,9 @@ -using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using OtterGui.Filesystem; using Penumbra.Interop.Structs; using Penumbra.Meta.Files; using Penumbra.Meta.Manipulations; -using Penumbra.Mods; namespace Penumbra.Meta.Manager; @@ -21,6 +18,9 @@ public partial class MetaManager public static void ResetGmpFiles() => SetFile( null, CharacterUtility.Index.Gmp ); + public Interop.CharacterUtility.List.MetaReverter TemporarilySetGmpFile() + => TemporarilySetFile( _gmpFile, CharacterUtility.Index.Gmp ); + public void ResetGmp() { if( _gmpFile == null ) diff --git a/Penumbra/Meta/Manager/MetaManager.Imc.cs b/Penumbra/Meta/Manager/MetaManager.Imc.cs index 517681ff..bdbf9512 100644 --- a/Penumbra/Meta/Manager/MetaManager.Imc.cs +++ b/Penumbra/Meta/Manager/MetaManager.Imc.cs @@ -1,10 +1,7 @@ using System; using System.Collections.Generic; -using System.Linq; -using Dalamud.Logging; using FFXIVClientStructs.FFXIV.Client.System.Resource; using OtterGui.Filesystem; -using Penumbra.Collections; using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; using Penumbra.Interop.Structs; @@ -81,7 +78,7 @@ public partial class MetaManager catch( Exception e ) { ++Penumbra.ImcExceptions; - PluginLog.Error( $"Could not apply IMC Manipulation:\n{e}" ); + Penumbra.Log.Error( $"Could not apply IMC Manipulation:\n{e}" ); return false; } } @@ -156,7 +153,7 @@ public partial class MetaManager return false; } - PluginLog.Verbose( "Using ImcLoadHandler for path {$Path:l}.", path ); + Penumbra.Log.Verbose( $"Using ImcLoadHandler for path {path}." ); ret = Penumbra.ResourceLoader.ReadSqPackHook.Original( resourceManager, fileDescriptor, priority, isSync ); var lastUnderscore = split.LastIndexOf( ( byte )'_' ); @@ -166,8 +163,7 @@ public partial class MetaManager && collection.HasCache && collection.MetaCache!._imcFiles.TryGetValue( Utf8GamePath.FromSpan( path.Span, out var p ) ? p : Utf8GamePath.Empty, out var file ) ) { - PluginLog.Debug( "Loaded {GamePath:l} from file and replaced with IMC from collection {Collection:l}.", path, - collection.AnonymizedName ); + Penumbra.Log.Debug( $"Loaded {path} from file and replaced with IMC from collection {collection.AnonymizedName}." ); file.Replace( fileDescriptor->ResourceHandle ); } diff --git a/Penumbra/Meta/Manager/MetaManager.cs b/Penumbra/Meta/Manager/MetaManager.cs index aa46e7f7..701b77c0 100644 --- a/Penumbra/Meta/Manager/MetaManager.cs +++ b/Penumbra/Meta/Manager/MetaManager.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; -using Dalamud.Logging; using Penumbra.Collections; using Penumbra.Interop.Structs; using Penumbra.Meta.Files; @@ -165,7 +164,7 @@ public partial class MetaManager : IDisposable, IEnumerable< KeyValuePair< MetaM } Penumbra.CharacterUtility.LoadingFinished -= ApplyStoredManipulations; - PluginLog.Debug( "{Collection}: Loaded {Num} delayed meta manipulations.", _collection.Name, loaded ); + Penumbra.Log.Debug( $"{_collection.AnonymizedName}: Loaded {loaded} delayed meta manipulations." ); } [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] @@ -180,4 +179,10 @@ public partial class MetaManager : IDisposable, IEnumerable< KeyValuePair< MetaM Penumbra.CharacterUtility.SetResource( index, ( IntPtr )file.Data, file.Length ); } } + + [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] + private static unsafe Interop.CharacterUtility.List.MetaReverter TemporarilySetFile( MetaBaseFile? file, CharacterUtility.Index index ) + => file == null + ? Penumbra.CharacterUtility.TemporarilyResetResource( index ) + : Penumbra.CharacterUtility.TemporarilySetResource( index, ( IntPtr )file.Data, file.Length ); } \ No newline at end of file diff --git a/Penumbra/Meta/Manipulations/GmpManipulation.cs b/Penumbra/Meta/Manipulations/GmpManipulation.cs index f686ec31..9890f113 100644 --- a/Penumbra/Meta/Manipulations/GmpManipulation.cs +++ b/Penumbra/Meta/Manipulations/GmpManipulation.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using Penumbra.GameData.Structs; using Penumbra.Interop.Structs; diff --git a/Penumbra/Mods/Editor/Mod.Editor.Duplicates.cs b/Penumbra/Mods/Editor/Mod.Editor.Duplicates.cs index 486da507..0f9ef463 100644 --- a/Penumbra/Mods/Editor/Mod.Editor.Duplicates.cs +++ b/Penumbra/Mods/Editor/Mod.Editor.Duplicates.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using System.Security.Cryptography; using System.Threading.Tasks; -using Dalamud.Logging; using Penumbra.GameData.ByteString; namespace Penumbra.Mods; @@ -87,7 +86,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"[DeleteDuplicates] Could not delete duplicate {duplicate.FullName} of {remaining.FullName}:\n{e}" ); + Penumbra.Log.Error( $"[DeleteDuplicates] Could not delete duplicate {duplicate.FullName} of {remaining.FullName}:\n{e}" ); } } @@ -100,7 +99,7 @@ public partial class Mod } changes = true; - PluginLog.Debug( "[DeleteDuplicates] Changing {GamePath:l} for {Mod:d}\n : {Old:l}\n -> {New:l}", key, _mod.Name, from, to ); + Penumbra.Log.Debug( $"[DeleteDuplicates] Changing {key} for {_mod.Name}\n : {from}\n -> {to}" ); return to; } @@ -263,7 +262,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not delete empty directories in {baseDir.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Could not delete empty directories in {baseDir.FullName}:\n{e}" ); } } @@ -282,7 +281,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Warning( $"Could not deduplicate mod {modDirectory.Name}:\n{e}" ); + Penumbra.Log.Warning( $"Could not deduplicate mod {modDirectory.Name}:\n{e}" ); } } } diff --git a/Penumbra/Mods/Editor/Mod.Editor.Files.cs b/Penumbra/Mods/Editor/Mod.Editor.Files.cs index ab610f5d..480261ee 100644 --- a/Penumbra/Mods/Editor/Mod.Editor.Files.cs +++ b/Penumbra/Mods/Editor/Mod.Editor.Files.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; -using Dalamud.Logging; using Penumbra.GameData.ByteString; namespace Penumbra.Mods; @@ -114,7 +113,7 @@ public partial class Mod return true; } - PluginLog.Debug( "[RemoveMissingPaths] Removing {GamePath} -> {File} from {Mod}.", key, file, _mod.Name ); + Penumbra.Log.Debug( $"[RemoveMissingPaths] Removing {key} -> {file} from {_mod.Name}." ); return false; } @@ -257,12 +256,12 @@ public partial class Mod try { File.Delete( file.File.FullName ); - PluginLog.Debug( "[DeleteFiles] Deleted {File} from {Mod}.", file.File.FullName, _mod.Name ); + Penumbra.Log.Debug( $"[DeleteFiles] Deleted {file.File.FullName} from {_mod.Name}." ); ++deletions; } catch( Exception e ) { - PluginLog.Error( $"[DeleteFiles] Could not delete {file.File.FullName} from {_mod.Name}:\n{e}" ); + Penumbra.Log.Error( $"[DeleteFiles] Could not delete {file.File.FullName} from {_mod.Name}:\n{e}" ); } } diff --git a/Penumbra/Mods/Editor/Mod.Editor.Groups.cs b/Penumbra/Mods/Editor/Mod.Editor.Groups.cs index 9f2a35e9..2e1a4ab2 100644 --- a/Penumbra/Mods/Editor/Mod.Editor.Groups.cs +++ b/Penumbra/Mods/Editor/Mod.Editor.Groups.cs @@ -1,6 +1,3 @@ -using System.Collections.Generic; -using Penumbra.GameData.ByteString; - namespace Penumbra.Mods; public partial class Mod diff --git a/Penumbra/Mods/Editor/Mod.Editor.MdlMaterials.cs b/Penumbra/Mods/Editor/Mod.Editor.MdlMaterials.cs index 5c1f2c7e..3061d390 100644 --- a/Penumbra/Mods/Editor/Mod.Editor.MdlMaterials.cs +++ b/Penumbra/Mods/Editor/Mod.Editor.MdlMaterials.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; -using Dalamud.Logging; using OtterGui; using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; @@ -90,7 +89,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Unexpected error scanning {_mod.Name}'s {file.File.FullName} for materials:\n{e}" ); + Penumbra.Log.Error( $"Unexpected error scanning {_mod.Name}'s {file.File.FullName} for materials:\n{e}" ); } } } @@ -152,7 +151,7 @@ public partial class Mod catch( Exception e ) { Restore(); - PluginLog.Error( $"Could not write manipulated .mdl file {Path.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Could not write manipulated .mdl file {Path.FullName}:\n{e}" ); } } diff --git a/Penumbra/Mods/Editor/ModBackup.cs b/Penumbra/Mods/Editor/ModBackup.cs index acc9e8af..48bbc4fa 100644 --- a/Penumbra/Mods/Editor/ModBackup.cs +++ b/Penumbra/Mods/Editor/ModBackup.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.IO.Compression; using System.Threading.Tasks; -using Dalamud.Logging; namespace Penumbra.Mods; @@ -18,10 +17,39 @@ public class ModBackup public ModBackup( Mod mod ) { _mod = mod; - Name = mod.ModPath + ".zip"; + Name = _mod.ModPath + ".pmp"; Exists = File.Exists( Name ); } + // Migrate file extensions. + public static void MigrateZipToPmp(Mod.Manager manager) + { + foreach( var mod in manager ) + { + var pmpName = mod.ModPath + ".pmp"; + var zipName = mod.ModPath + ".zip"; + if( File.Exists( zipName ) ) + { + try + { + if( !File.Exists( pmpName ) ) + { + File.Move( zipName, pmpName ); + } + else + { + File.Delete( zipName ); + } + Penumbra.Log.Information( $"Migrated mod backup from {zipName} to {pmpName}." ); + } + catch( Exception e ) + { + Penumbra.Log.Warning( $"Could not migrate mod backup of {mod.ModPath} from .pmp to .zip:\n{e}" ); + } + } + } + } + // Create a backup zip without blocking the main thread. public async void CreateAsync() { @@ -43,11 +71,11 @@ public class ModBackup { Delete(); ZipFile.CreateFromDirectory( _mod.ModPath.FullName, Name, CompressionLevel.Optimal, false ); - PluginLog.Debug( "Created backup file {backupName} from {modDirectory}.", Name, _mod.ModPath.FullName ); + Penumbra.Log.Debug( $"Created backup file {Name} from {_mod.ModPath.FullName}."); } catch( Exception e ) { - PluginLog.Error( $"Could not backup mod {_mod.Name} to \"{Name}\":\n{e}" ); + Penumbra.Log.Error( $"Could not backup mod {_mod.Name} to \"{Name}\":\n{e}" ); } } @@ -62,11 +90,11 @@ public class ModBackup try { File.Delete( Name ); - PluginLog.Debug( "Deleted backup file {backupName}.", Name ); + Penumbra.Log.Debug( $"Deleted backup file {Name}." ); } catch( Exception e ) { - PluginLog.Error( $"Could not delete file \"{Name}\":\n{e}" ); + Penumbra.Log.Error( $"Could not delete file \"{Name}\":\n{e}" ); } } @@ -79,16 +107,16 @@ public class ModBackup if( Directory.Exists( _mod.ModPath.FullName ) ) { Directory.Delete( _mod.ModPath.FullName, true ); - PluginLog.Debug( "Deleted mod folder {modFolder}.", _mod.ModPath.FullName ); + Penumbra.Log.Debug( $"Deleted mod folder {_mod.ModPath.FullName}." ); } ZipFile.ExtractToDirectory( Name, _mod.ModPath.FullName ); - PluginLog.Debug( "Extracted backup file {backupName} to {modName}.", Name, _mod.ModPath.FullName ); + Penumbra.Log.Debug( $"Extracted backup file {Name} to {_mod.ModPath.FullName}."); Penumbra.ModManager.ReloadMod( _mod.Index ); } catch( Exception e ) { - PluginLog.Error( $"Could not restore {_mod.Name} from backup \"{Name}\":\n{e}" ); + Penumbra.Log.Error( $"Could not restore {_mod.Name} from backup \"{Name}\":\n{e}" ); } } } \ No newline at end of file diff --git a/Penumbra/Mods/Editor/ModCleanup.cs b/Penumbra/Mods/Editor/ModCleanup.cs index c19c1b1f..a2e7dec0 100644 --- a/Penumbra/Mods/Editor/ModCleanup.cs +++ b/Penumbra/Mods/Editor/ModCleanup.cs @@ -274,7 +274,7 @@ public partial class Mod // } // catch( Exception e ) // { -// PluginLog.Error( $"Could not split Mod:\n{e}" ); +// Penumbra.Log.Error( $"Could not split Mod:\n{e}" ); // } // } // @@ -394,7 +394,7 @@ public partial class Mod // } // } // -// PluginLog.Information( $"File {relName1} and {relName2} are identical. Deleting the second." ); +// Penumbra.Log.Information( $"File {relName1} and {relName2} are identical. Deleting the second." ); // f2.Delete(); // } // @@ -498,7 +498,7 @@ public partial class Mod // } // catch( Exception e ) // { -// PluginLog.Error( $"Could not move file from {oldRelPath} to {newRelPath}:\n{e}" ); +// Penumbra.Log.Error( $"Could not move file from {oldRelPath} to {newRelPath}:\n{e}" ); // return false; // } // diff --git a/Penumbra/Mods/Manager/Mod.Manager.BasePath.cs b/Penumbra/Mods/Manager/Mod.Manager.BasePath.cs index e9a2d104..0d908866 100644 --- a/Penumbra/Mods/Manager/Mod.Manager.BasePath.cs +++ b/Penumbra/Mods/Manager/Mod.Manager.BasePath.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Linq; -using Dalamud.Logging; namespace Penumbra.Mods; @@ -34,7 +33,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not delete empty directory {dir!.FullName} to move {mod.Name} to it:\n{e}" ); + Penumbra.Log.Error( $"Could not delete empty directory {dir!.FullName} to move {mod.Name} to it:\n{e}" ); return; } @@ -55,7 +54,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not move {mod.Name} from {oldDirectory.Name} to {dir!.Name}:\n{e}" ); + Penumbra.Log.Error( $"Could not move {mod.Name} from {oldDirectory.Name} to {dir!.Name}:\n{e}" ); return; } @@ -63,7 +62,7 @@ public partial class Mod mod.ModPath = dir; if( !mod.Reload( out var metaChange ) ) { - PluginLog.Error( $"Error reloading moved mod {mod.Name}." ); + Penumbra.Log.Error( $"Error reloading moved mod {mod.Name}." ); return; } @@ -81,10 +80,10 @@ public partial class Mod var mod = this[ idx ]; var oldName = mod.Name; - ModPathChanged.Invoke(ModPathChangeType.StartingReload, mod, mod.ModPath, mod.ModPath ); + ModPathChanged.Invoke( ModPathChangeType.StartingReload, mod, mod.ModPath, mod.ModPath ); if( !mod.Reload( out var metaChange ) ) { - PluginLog.Warning( mod.Name.Length == 0 + Penumbra.Log.Warning( mod.Name.Length == 0 ? $"Reloading mod {oldName} has failed, new name is empty. Deleting instead." : $"Reloading mod {oldName} failed, {mod.ModPath.FullName} does not exist anymore or it ha. Deleting instead." ); @@ -110,11 +109,11 @@ public partial class Mod try { Directory.Delete( mod.ModPath.FullName, true ); - PluginLog.Debug( "Deleted directory {Directory:l} for {Name:l}.", mod.ModPath.FullName, mod.Name ); + Penumbra.Log.Debug( $"Deleted directory {mod.ModPath.FullName} for {mod.Name}."); } catch( Exception e ) { - PluginLog.Error( $"Could not delete the mod {mod.ModPath.Name}:\n{e}" ); + Penumbra.Log.Error( $"Could not delete the mod {mod.ModPath.Name}:\n{e}" ); } } @@ -125,7 +124,7 @@ public partial class Mod --remainingMod.Index; } - PluginLog.Debug( "Deleted mod {Name:l}.", mod.Name ); + Penumbra.Log.Debug( $"Deleted mod {mod.Name}." ); } // Load a new mod and add it to the manager if successful. @@ -145,7 +144,7 @@ public partial class Mod mod.Index = _mods.Count; _mods.Add( mod ); ModPathChanged.Invoke( ModPathChangeType.Added, mod, null, mod.ModPath ); - PluginLog.Debug( "Added new mod {Name:l} from {Directory:l}.", mod.Name, modFolder.FullName ); + Penumbra.Log.Debug( $"Added new mod {mod.Name} from {modFolder.FullName}." ); } public enum NewDirectoryState diff --git a/Penumbra/Mods/Manager/Mod.Manager.Options.cs b/Penumbra/Mods/Manager/Mod.Manager.Options.cs index b5d3f36a..b2ecdc54 100644 --- a/Penumbra/Mods/Manager/Mod.Manager.Options.cs +++ b/Penumbra/Mods/Manager/Mod.Manager.Options.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Dalamud.Logging; using OtterGui; using OtterGui.Filesystem; using Penumbra.GameData.ByteString; @@ -88,7 +87,7 @@ public sealed partial class Mod { foreach( var (group, groupIdx) in mod._groups.WithIndex().Skip( fromGroup ) ) { - foreach( var (o, optionIdx) in group.OfType().WithIndex() ) + foreach( var (o, optionIdx) in group.OfType< SubMod >().WithIndex() ) { o.SetPosition( groupIdx, optionIdx ); } @@ -176,18 +175,19 @@ public sealed partial class Mod public void AddOption( Mod mod, int groupIdx, string newName ) { - var group = mod._groups[groupIdx]; + var group = mod._groups[ groupIdx ]; + var subMod = new SubMod( mod ) { Name = newName }; + subMod.SetPosition( groupIdx, group.Count ); switch( group ) { case SingleModGroup s: - s.OptionData.Add( new SubMod(mod) { Name = newName } ); + s.OptionData.Add( subMod ); break; case MultiModGroup m: - m.PrioritizedOptions.Add( ( new SubMod(mod) { Name = newName }, 0 ) ); + m.PrioritizedOptions.Add( ( subMod, 0 ) ); break; } - group.UpdatePositions( group.Count - 1 ); ModOptionChanged.Invoke( ModOptionChangeType.OptionAdded, mod, groupIdx, group.Count - 1, -1 ); } @@ -201,12 +201,14 @@ public sealed partial class Mod var group = mod._groups[ groupIdx ]; if( group.Count > 63 ) { - PluginLog.Error( + Penumbra.Log.Error( $"Could not add option {option.Name} to {group.Name} for mod {mod.Name}, " + "since only up to 64 options are supported in one group." ); return; } + o.SetPosition( groupIdx, group.Count ); + switch( group ) { case SingleModGroup s: @@ -216,13 +218,13 @@ public sealed partial class Mod m.PrioritizedOptions.Add( ( o, priority ) ); break; } - group.UpdatePositions( group.Count - 1 ); + ModOptionChanged.Invoke( ModOptionChangeType.OptionAdded, mod, groupIdx, group.Count - 1, -1 ); } public void DeleteOption( Mod mod, int groupIdx, int optionIdx ) { - var group = mod._groups[groupIdx]; + var group = mod._groups[ groupIdx ]; ModOptionChanged.Invoke( ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1 ); switch( group ) { @@ -234,6 +236,7 @@ public sealed partial class Mod m.PrioritizedOptions.RemoveAt( optionIdx ); break; } + group.UpdatePositions( optionIdx ); ModOptionChanged.Invoke( ModOptionChangeType.OptionDeleted, mod, groupIdx, optionIdx, -1 ); } @@ -307,7 +310,7 @@ public sealed partial class Mod { if( message ) { - PluginLog.Warning( $"Could not name option {newName} because option with same filename {path} already exists." ); + Penumbra.Log.Warning( $"Could not name option {newName} because option with same filename {path} already exists." ); } return false; @@ -333,6 +336,11 @@ public sealed partial class Mod private static void OnModOptionChange( ModOptionChangeType type, Mod mod, int groupIdx, int _, int _2 ) { + if( type == ModOptionChangeType.PrepareChange ) + { + return; + } + // File deletion is handled in the actual function. if( type is ModOptionChangeType.GroupDeleted or ModOptionChangeType.GroupMoved ) { diff --git a/Penumbra/Mods/Manager/Mod.Manager.Root.cs b/Penumbra/Mods/Manager/Mod.Manager.Root.cs index 92a8c51e..2bf658c2 100644 --- a/Penumbra/Mods/Manager/Mod.Manager.Root.cs +++ b/Penumbra/Mods/Manager/Mod.Manager.Root.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using Dalamud.Logging; namespace Penumbra.Mods; @@ -53,7 +52,7 @@ public sealed partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not create specified mod directory {newDir.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Could not create specified mod directory {newDir.FullName}:\n{e}" ); } } @@ -68,8 +67,7 @@ public sealed partial class Mod private static void OnModDirectoryChange( string newPath, bool _ ) { - PluginLog.Information( "Set new mod base directory from {OldDirectory:l} to {NewDirectory:l}.", - Penumbra.Config.ModDirectory, newPath ); + Penumbra.Log.Information( $"Set new mod base directory from {Penumbra.Config.ModDirectory} to {newPath}." ); Penumbra.Config.ModDirectory = newPath; Penumbra.Config.Save(); } @@ -98,7 +96,12 @@ public sealed partial class Mod } ModDiscoveryFinished?.Invoke(); - PluginLog.Information( "Rediscovered mods." ); + Penumbra.Log.Information( "Rediscovered mods." ); + + if( MigrateModBackups ) + { + ModBackup.MigrateZipToPmp( this ); + } } } } \ No newline at end of file diff --git a/Penumbra/Mods/Manager/Mod.Manager.cs b/Penumbra/Mods/Manager/Mod.Manager.cs index ff800473..11f878ca 100644 --- a/Penumbra/Mods/Manager/Mod.Manager.cs +++ b/Penumbra/Mods/Manager/Mod.Manager.cs @@ -9,6 +9,9 @@ public sealed partial class Mod { public sealed partial class Manager : IReadOnlyList< Mod > { + // Set when reading Config and migrating from v4 to v5. + public static bool MigrateModBackups = false; + // An easily accessible set of new mods. // Mods are added when they are created or imported. // Mods are removed when they are deleted or when they are toggled in any collection. diff --git a/Penumbra/Mods/Mod.BasePath.cs b/Penumbra/Mods/Mod.BasePath.cs index 2e01396f..2456dec2 100644 --- a/Penumbra/Mods/Mod.BasePath.cs +++ b/Penumbra/Mods/Mod.BasePath.cs @@ -1,5 +1,4 @@ using System.IO; -using Dalamud.Logging; namespace Penumbra.Mods; @@ -32,7 +31,7 @@ public partial class Mod modPath.Refresh(); if( !modPath.Exists ) { - PluginLog.Error( $"Supplied mod directory {modPath} does not exist." ); + Penumbra.Log.Error( $"Supplied mod directory {modPath} does not exist." ); return null; } @@ -40,7 +39,7 @@ public partial class Mod if( !mod.Reload( out _ ) ) { // Can not be base path not existing because that is checked before. - PluginLog.Error( $"Mod at {modPath} without name is not supported." ); + Penumbra.Log.Error( $"Mod at {modPath} without name is not supported." ); return null; } diff --git a/Penumbra/Mods/Mod.Files.cs b/Penumbra/Mods/Mod.Files.cs index 87c69a82..c9c8683b 100644 --- a/Penumbra/Mods/Mod.Files.cs +++ b/Penumbra/Mods/Mod.Files.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using Dalamud.Logging; using Newtonsoft.Json.Linq; using OtterGui; using Penumbra.GameData.ByteString; @@ -88,7 +87,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not read mod group from {file.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Could not read mod group from {file.FullName}:\n{e}" ); } return null; @@ -133,7 +132,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not delete outdated group file {file}:\n{e}" ); + Penumbra.Log.Error( $"Could not delete outdated group file {file}:\n{e}" ); } } diff --git a/Penumbra/Mods/Mod.Meta.Migration.cs b/Penumbra/Mods/Mod.Meta.Migration.cs index 1587864f..f6bba3a3 100644 --- a/Penumbra/Mods/Mod.Meta.Migration.cs +++ b/Penumbra/Mods/Mod.Meta.Migration.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using Dalamud.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; @@ -37,7 +36,7 @@ public sealed partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not rename group file {group.Name} to {newName} during migration:\n{e}" ); + Penumbra.Log.Error( $"Could not rename group file {group.Name} to {newName} during migration:\n{e}" ); } } @@ -69,7 +68,7 @@ public sealed partial class Mod if( unusedFile.ToGamePath( mod.ModPath, out var gamePath ) && !mod._default.FileData.TryAdd( gamePath, unusedFile ) ) { - PluginLog.Error( $"Could not add {gamePath} because it already points to {mod._default.FileData[ gamePath ]}." ); + Penumbra.Log.Error( $"Could not add {gamePath} because it already points to {mod._default.FileData[ gamePath ]}." ); } } @@ -95,7 +94,7 @@ public sealed partial class Mod } catch( Exception e ) { - PluginLog.Warning( $"Could not delete meta file {file.FullName} during migration:\n{e}" ); + Penumbra.Log.Warning( $"Could not delete meta file {file.FullName} during migration:\n{e}" ); } } @@ -109,7 +108,7 @@ public sealed partial class Mod } catch( Exception e ) { - PluginLog.Warning( $"Could not delete old meta file {oldMetaFile} during migration:\n{e}" ); + Penumbra.Log.Warning( $"Could not delete old meta file {oldMetaFile} during migration:\n{e}" ); } } diff --git a/Penumbra/Mods/Mod.Meta.cs b/Penumbra/Mods/Mod.Meta.cs index 615e0dc1..21db4857 100644 --- a/Penumbra/Mods/Mod.Meta.cs +++ b/Penumbra/Mods/Mod.Meta.cs @@ -1,9 +1,7 @@ using System; using System.IO; -using Dalamud.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using OtterGui; using OtterGui.Classes; namespace Penumbra.Mods; @@ -48,7 +46,7 @@ public sealed partial class Mod var metaFile = MetaFile; if( !File.Exists( metaFile.FullName ) ) { - PluginLog.Debug( "No mod meta found for {ModLocation}.", ModPath.Name ); + Penumbra.Log.Debug( $"No mod meta found for {ModPath.Name}." ); return MetaChangeType.Deletion; } @@ -115,7 +113,7 @@ public sealed partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not load mod meta:\n{e}" ); + Penumbra.Log.Error( $"Could not load mod meta:\n{e}" ); return MetaChangeType.Deletion; } } @@ -142,7 +140,7 @@ public sealed partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not write meta file for mod {Name} to {metaFile.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Could not write meta file for mod {Name} to {metaFile.FullName}:\n{e}" ); } } diff --git a/Penumbra/Mods/Mod.TemporaryMod.cs b/Penumbra/Mods/Mod.TemporaryMod.cs index 10d90979..c41dcf57 100644 --- a/Penumbra/Mods/Mod.TemporaryMod.cs +++ b/Penumbra/Mods/Mod.TemporaryMod.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Linq; using OtterGui.Classes; +using Penumbra.Collections; using Penumbra.GameData.ByteString; using Penumbra.Meta.Manipulations; @@ -42,5 +45,67 @@ public sealed partial class Mod _default.FileData = dict; _default.ManipulationData = manips; } + + public static void SaveTempCollection( ModCollection collection, string? character = null ) + { + DirectoryInfo? dir = null; + try + { + dir = CreateModFolder( Penumbra.ModManager.BasePath, collection.Name ); + var fileDir = Directory.CreateDirectory( Path.Combine( dir.FullName, "files" ) ); + CreateMeta( dir, collection.Name, character ?? Penumbra.Config.DefaultModAuthor, + $"Mod generated from temporary collection {collection.Name} for {character ?? "Unknown Character"}.", null, null ); + var mod = new Mod( dir ); + var defaultMod = mod._default; + foreach( var (gamePath, fullPath) in collection.ResolvedFiles ) + { + if( gamePath.Path.EndsWith( '.', 'i', 'm', 'c' ) ) + { + continue; + } + + var targetPath = fullPath.Path.FullName; + if( fullPath.Path.Name.StartsWith( '|' ) ) + { + targetPath = targetPath.Split( '|', 3, StringSplitOptions.RemoveEmptyEntries ).Last(); + } + + if( Path.IsPathRooted(targetPath) ) + { + var target = Path.Combine( fileDir.FullName, Path.GetFileName(targetPath) ); + File.Copy( targetPath, target, true ); + defaultMod.FileData[ gamePath ] = new FullPath( target ); + } + else + { + defaultMod.FileSwapData[ gamePath ] = new FullPath(targetPath); + } + } + + foreach( var manip in collection.MetaCache?.Manipulations ?? Array.Empty< MetaManipulation >() ) + { + defaultMod.ManipulationData.Add( manip ); + } + + mod.SaveDefaultMod(); + Penumbra.ModManager.AddMod( dir ); + Penumbra.Log.Information( $"Successfully generated mod {mod.Name} at {mod.ModPath.FullName} for collection {collection.Name}." ); + } + catch( Exception e ) + { + Penumbra.Log.Error( $"Could not save temporary collection {collection.Name} to permanent Mod:\n{e}" ); + if( dir != null && Directory.Exists( dir.FullName ) ) + { + try + { + Directory.Delete( dir.FullName, true ); + } + catch + { + // ignored + } + } + } + } } } \ No newline at end of file diff --git a/Penumbra/Mods/ModFileSystem.cs b/Penumbra/Mods/ModFileSystem.cs index 0b186ea4..1060504c 100644 --- a/Penumbra/Mods/ModFileSystem.cs +++ b/Penumbra/Mods/ModFileSystem.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using Dalamud.Logging; using OtterGui.Filesystem; namespace Penumbra.Mods; @@ -19,7 +18,7 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable private void SaveFilesystem() { SaveToFile( new FileInfo( ModFileSystemFile ), SaveMod, true ); - PluginLog.Verbose( "Saved mod filesystem." ); + Penumbra.Log.Verbose( "Saved mod filesystem." ); } private void Save() @@ -79,7 +78,7 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable Save(); } - PluginLog.Debug( "Reloaded mod filesystem." ); + Penumbra.Log.Debug( "Reloaded mod filesystem." ); } // Save the filesystem on every filesystem change except full reloading. diff --git a/Penumbra/Mods/Subclasses/IModGroup.cs b/Penumbra/Mods/Subclasses/IModGroup.cs index 190ca399..9507b0f3 100644 --- a/Penumbra/Mods/Subclasses/IModGroup.cs +++ b/Penumbra/Mods/Subclasses/IModGroup.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using Dalamud.Logging; using Newtonsoft.Json; using OtterGui.Filesystem; @@ -50,11 +49,11 @@ public interface IModGroup : IEnumerable< ISubMod > try { File.Delete( file ); - PluginLog.Debug( "Deleted group file {File:l} for group {GroupIdx}: {GroupName:l}.", file, groupIdx + 1, Name ); + Penumbra.Log.Debug( $"Deleted group file {file} for group {groupIdx + 1}: {Name}." ); } catch( Exception e ) { - PluginLog.Error( $"Could not delete file {file}:\n{e}" ); + Penumbra.Log.Error( $"Could not delete file {file}:\n{e}" ); throw; } } @@ -92,7 +91,7 @@ public interface IModGroup : IEnumerable< ISubMod > j.WriteEndArray(); j.WriteEndObject(); - PluginLog.Debug( "Saved group file {File:l} for group {GroupIdx}: {GroupName:l}.", file, groupIdx + 1, group.Name ); + Penumbra.Log.Debug( $"Saved group file {file} for group {groupIdx + 1}: {group.Name}." ); } public IModGroup Convert( SelectType type ); diff --git a/Penumbra/Mods/Subclasses/Mod.Files.MultiModGroup.cs b/Penumbra/Mods/Subclasses/Mod.Files.MultiModGroup.cs index fc735981..3413cc6f 100644 --- a/Penumbra/Mods/Subclasses/Mod.Files.MultiModGroup.cs +++ b/Penumbra/Mods/Subclasses/Mod.Files.MultiModGroup.cs @@ -1,9 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; -using System.IO; using System.Linq; -using Dalamud.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; @@ -61,7 +59,7 @@ public partial class Mod { if( ret.PrioritizedOptions.Count == IModGroup.MaxMultiOptions ) { - PluginLog.Warning( + Penumbra.Log.Warning( $"Multi Group {ret.Name} has more than {IModGroup.MaxMultiOptions} options, ignoring excessive options." ); break; } diff --git a/Penumbra/Mods/Subclasses/Mod.Files.SingleModGroup.cs b/Penumbra/Mods/Subclasses/Mod.Files.SingleModGroup.cs index 8cfb775c..e37b1988 100644 --- a/Penumbra/Mods/Subclasses/Mod.Files.SingleModGroup.cs +++ b/Penumbra/Mods/Subclasses/Mod.Files.SingleModGroup.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.IO; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/Penumbra/Mods/Subclasses/Mod.Files.SubMod.cs b/Penumbra/Mods/Subclasses/Mod.Files.SubMod.cs index 9a13e642..07c752af 100644 --- a/Penumbra/Mods/Subclasses/Mod.Files.SubMod.cs +++ b/Penumbra/Mods/Subclasses/Mod.Files.SubMod.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using Dalamud.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Penumbra.GameData.ByteString; @@ -56,7 +55,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not parse default file for {Name}:\n{e}" ); + Penumbra.Log.Error( $"Could not parse default file for {Name}:\n{e}" ); } } @@ -196,8 +195,7 @@ public partial class Mod } catch( Exception e ) { - PluginLog.Error( $"Could not incorporate meta changes in mod {basePath} from file {file.FullName}:\n{e}" ); - continue; + Penumbra.Log.Error( $"Could not incorporate meta changes in mod {basePath} from file {file.FullName}:\n{e}" ); } } } diff --git a/Penumbra/Mods/Subclasses/ModSettings.cs b/Penumbra/Mods/Subclasses/ModSettings.cs index 6d6f2f3d..b79f1c9e 100644 --- a/Penumbra/Mods/Subclasses/ModSettings.cs +++ b/Penumbra/Mods/Subclasses/ModSettings.cs @@ -70,7 +70,7 @@ public class ModSettings var config = Settings[ groupIdx ]; Settings[ groupIdx ] = group.Type switch { - SelectType.Single => config >= optionIdx ? Math.Max( 0, config - 1 ) : config, + SelectType.Single => config >= optionIdx ? (config > 1 ? config - 1 : 0) : config, SelectType.Multi => RemoveBit( config, optionIdx ), _ => config, }; diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index e4081ba0..62e70d7a 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -6,7 +6,6 @@ using System.Reflection; using System.Text; using Dalamud.Game.Command; using Dalamud.Interface.Windowing; -using Dalamud.Logging; using Dalamud.Plugin; using EmbedIO; using EmbedIO.WebApi; @@ -14,6 +13,8 @@ using ImGuiNET; using Lumina.Excel.GeneratedSheets; using OtterGui; using OtterGui.Classes; +using OtterGui.Log; +using OtterGui.Widgets; using Penumbra.Api; using Penumbra.GameData.Enums; using Penumbra.Interop; @@ -43,6 +44,7 @@ public class Penumbra : IDalamudPlugin public static bool DevPenumbraExists; public static bool IsNotInstalledPenumbra; + public static Logger Log { get; private set; } = null!; public static Configuration Config { get; private set; } = null!; public static ResidentResourceManager ResidentResources { get; private set; } = null!; @@ -64,6 +66,7 @@ public class Penumbra : IDalamudPlugin private readonly ConfigWindow _configWindow; private readonly LaunchButton _launchButton; private readonly WindowSystem _windowSystem; + private readonly Changelog _changelog; internal WebServer? WebServer; @@ -72,6 +75,7 @@ public class Penumbra : IDalamudPlugin try { Dalamud.Initialize( pluginInterface ); + Log = new Logger(); GameData.GameData.GetIdentifier( Dalamud.GameData ); DevPenumbraExists = CheckDevPluginPenumbra(); IsNotInstalledPenumbra = CheckIsNotInstalled(); @@ -99,7 +103,7 @@ public class Penumbra : IDalamudPlugin HelpMessage = "/penumbra - toggle ui\n/penumbra reload - reload mod file lists & discover any new mods", } ); - SetupInterface( out _configWindow, out _launchButton, out _windowSystem ); + SetupInterface( out _configWindow, out _launchButton, out _windowSystem, out _changelog ); if( Config.EnableMods ) { @@ -133,17 +137,17 @@ public class Penumbra : IDalamudPlugin SubscribeItemLinks(); if( ImcExceptions > 0 ) { - PluginLog.Error( $"{ImcExceptions} IMC Exceptions thrown. Please repair your game files." ); + Log.Error( $"{ImcExceptions} IMC Exceptions thrown. Please repair your game files." ); } else { - PluginLog.Information( $"Penumbra Version {Version}, Commit #{CommitHash} successfully Loaded." ); + Log.Information( $"Penumbra Version {Version}, Commit #{CommitHash} successfully Loaded." ); } Dalamud.PluginInterface.UiBuilder.Draw += _windowSystem.Draw; OtterTex.NativeDll.Initialize( Dalamud.PluginInterface.AssemblyLocation.DirectoryName ); - PluginLog.Information( $"Loading native assembly from {OtterTex.NativeDll.Directory}." ); + Log.Information( $"Loading native OtterTex assembly from {OtterTex.NativeDll.Directory}." ); } catch { @@ -152,23 +156,31 @@ public class Penumbra : IDalamudPlugin } } - private void SetupInterface( out ConfigWindow cfg, out LaunchButton btn, out WindowSystem system ) + private void SetupInterface( out ConfigWindow cfg, out LaunchButton btn, out WindowSystem system, out Changelog changelog ) { - cfg = new ConfigWindow( this ); - btn = new LaunchButton( _configWindow ); - system = new WindowSystem( Name ); + cfg = new ConfigWindow( this ); + btn = new LaunchButton( _configWindow ); + system = new WindowSystem( Name ); + changelog = ConfigWindow.CreateChangelog(); system.AddWindow( _configWindow ); system.AddWindow( cfg.ModEditPopup ); - system.AddWindow( ConfigWindow.CreateChangelog() ); + system.AddWindow( changelog ); Dalamud.PluginInterface.UiBuilder.OpenConfigUi += cfg.Toggle; } private void DisposeInterface() { - Dalamud.PluginInterface.UiBuilder.Draw -= _windowSystem.Draw; - Dalamud.PluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle; + if( _windowSystem != null ) + { + Dalamud.PluginInterface.UiBuilder.Draw -= _windowSystem.Draw; + } + _launchButton?.Dispose(); - _configWindow?.Dispose(); + if( _configWindow != null ) + { + Dalamud.PluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle; + _configWindow.Dispose(); + } } public bool Enable() @@ -216,6 +228,9 @@ public class Penumbra : IDalamudPlugin public bool SetEnabled( bool enabled ) => enabled ? Enable() : Disable(); + public void ForceChangelogOpen() + => _changelog.ForceOpen = true; + private void SubscribeItemLinks() { Api.ChangedItemTooltip += it => @@ -248,7 +263,7 @@ public class Penumbra : IDalamudPlugin .WithController( () => new ModsController( this ) ) .WithController( () => new RedrawController( this ) ) ); - WebServer.StateChanged += ( _, e ) => PluginLog.Information( $"WebServer New State - {e.NewState}" ); + WebServer.StateChanged += ( _, e ) => Log.Information( $"WebServer New State - {e.NewState}" ); WebServer.RunAsync(); } @@ -502,7 +517,7 @@ public class Penumbra : IDalamudPlugin } catch( Exception e ) { - PluginLog.Error( $"Could not check for dev plugin Penumbra:\n{e}" ); + Log.Error( $"Could not check for dev plugin Penumbra:\n{e}" ); return true; } #else @@ -517,7 +532,7 @@ public class Penumbra : IDalamudPlugin var checkedDirectory = Dalamud.PluginInterface.AssemblyLocation.Directory?.Parent?.Parent?.Name; var ret = checkedDirectory?.Equals( "installedPlugins", StringComparison.OrdinalIgnoreCase ) ?? false; if (!ret) - PluginLog.Error($"Penumbra is not correctly installed. Application loaded from \"{Dalamud.PluginInterface.AssemblyLocation.Directory!.FullName}\"." ); + Log.Error($"Penumbra is not correctly installed. Application loaded from \"{Dalamud.PluginInterface.AssemblyLocation.Directory!.FullName}\"." ); return !ret; #else return false; diff --git a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs index cadae96e..99c25d26 100644 --- a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs +++ b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Numerics; using Dalamud.Interface; -using Dalamud.Logging; using ImGuiNET; using OtterGui; using OtterGui.Raii; @@ -134,7 +133,7 @@ public partial class ModEditWindow } catch( Exception e ) { - PluginLog.Error( $"Could not parse {_fileType} file {_currentPath.File.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Could not parse {_fileType} file {_currentPath.File.FullName}:\n{e}" ); _currentFile = null; } } diff --git a/Penumbra/UI/Classes/ModEditWindow.Files.cs b/Penumbra/UI/Classes/ModEditWindow.Files.cs index 8390850b..74a5b6e9 100644 --- a/Penumbra/UI/Classes/ModEditWindow.Files.cs +++ b/Penumbra/UI/Classes/ModEditWindow.Files.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; using Dalamud.Interface; -using Dalamud.Logging; using ImGuiNET; using OtterGui; using OtterGui.Classes; @@ -321,7 +320,7 @@ public partial class ModEditWindow var failedFiles = _editor!.ApplyFiles(); if( failedFiles > 0 ) { - PluginLog.Information( $"Failed to apply {failedFiles} file redirections to {_editor.CurrentOption.FullName}." ); + Penumbra.Log.Information( $"Failed to apply {failedFiles} file redirections to {_editor.CurrentOption.FullName}." ); } } diff --git a/Penumbra/UI/Classes/ModEditWindow.Textures.cs b/Penumbra/UI/Classes/ModEditWindow.Textures.cs index 1cebaa0e..b74aef07 100644 --- a/Penumbra/UI/Classes/ModEditWindow.Textures.cs +++ b/Penumbra/UI/Classes/ModEditWindow.Textures.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.Numerics; using Dalamud.Interface.ImGuiFileDialog; -using Dalamud.Logging; using ImGuiNET; using OtterGui; using OtterGui.Raii; @@ -123,7 +122,7 @@ public partial class ModEditWindow } catch( Exception e ) { - PluginLog.Error( $"Unknown Error while drawing textures:\n{e}" ); + Penumbra.Log.Error( $"Unknown Error while drawing textures:\n{e}" ); } } diff --git a/Penumbra/UI/Classes/ModFileSystemSelector.cs b/Penumbra/UI/Classes/ModFileSystemSelector.cs index be0d838b..77c7dea1 100644 --- a/Penumbra/UI/Classes/ModFileSystemSelector.cs +++ b/Penumbra/UI/Classes/ModFileSystemSelector.cs @@ -1,6 +1,5 @@ using Dalamud.Interface; using Dalamud.Interface.ImGuiFileDialog; -using Dalamud.Logging; using ImGuiNET; using OtterGui; using OtterGui.Filesystem; @@ -14,7 +13,6 @@ using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Numerics; -using Penumbra.Util; namespace Penumbra.UI.Classes; @@ -100,7 +98,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod } catch( Exception e ) { - PluginLog.Error( $"Could not create directory for new Mod {_newModName}:\n{e}" ); + Penumbra.Log.Error( $"Could not create directory for new Mod {_newModName}:\n{e}" ); } } @@ -200,7 +198,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod private void AddImportModButton( Vector2 size ) { var button = ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.FileImport.ToIconString(), size, - "Import one or multiple mods from Tex Tools Mod Pack Files.", !Penumbra.ModManager.Valid, true ); + "Import one or multiple mods from Tex Tools Mod Pack Files or Penumbra Mod Pack Files.", !Penumbra.ModManager.Valid, true ); ConfigWindow.OpenTutorial( ConfigWindow.BasicTutorialSteps.ModImport ); if( !button ) { @@ -213,7 +211,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod _hasSetFolder = true; _fileManager.OpenFileDialog( "Import Mod Pack", - "Mod Packs{.ttmp,.ttmp2,.zip,.7z,.rar},TexTools Mod Packs{.ttmp,.ttmp2},Archives{.zip,.7z,.rar}", ( s, f ) => + "Mod Packs{.ttmp,.ttmp2,.pmp},TexTools Mod Packs{.ttmp,.ttmp2},Penumbra Mod Packs{.pmp},Archives{.zip,.7z,.rar}", ( s, f ) => { if( s ) { @@ -273,13 +271,13 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod } catch( Exception e ) { - PluginLog.Error( $"Error cleaning up failed mod extraction of {file.FullName} to {dir.FullName}:\n{e}" ); + Penumbra.Log.Error( $"Error cleaning up failed mod extraction of {file.FullName} to {dir.FullName}:\n{e}" ); } } if( error is not OperationCanceledException ) { - PluginLog.Error( $"Error extracting {file.FullName}, mod skipped:\n{error}" ); + Penumbra.Log.Error( $"Error extracting {file.FullName}, mod skipped:\n{error}" ); } } else if( dir != null ) @@ -445,7 +443,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod } catch( Exception e ) { - PluginLog.Warning( + Penumbra.Log.Warning( $"Could not move newly imported mod {mod.Name} to default import folder {Penumbra.Config.DefaultImportFolder}:\n{e}" ); } } diff --git a/Penumbra/UI/ConfigWindow.Changelog.cs b/Penumbra/UI/ConfigWindow.Changelog.cs index c9dae1c2..d4c6cb04 100644 --- a/Penumbra/UI/ConfigWindow.Changelog.cs +++ b/Penumbra/UI/ConfigWindow.Changelog.cs @@ -1,4 +1,3 @@ -using Lumina.Excel.GeneratedSheets; using OtterGui.Widgets; namespace Penumbra.UI; @@ -9,23 +8,57 @@ public partial class ConfigWindow public static Changelog CreateChangelog() { - var ret = new Changelog( "Penumbra Changelog", () => Penumbra.Config.LastSeenVersion, version => - { - Penumbra.Config.LastSeenVersion = version; - Penumbra.Config.Save(); - } ); + var ret = new Changelog( "Penumbra Changelog", () => ( Penumbra.Config.LastSeenVersion, Penumbra.Config.ChangeLogDisplayType ), + ( version, type ) => + { + Penumbra.Config.LastSeenVersion = version; + Penumbra.Config.ChangeLogDisplayType = type; + Penumbra.Config.Save(); + } ); Add5_7_0( ret ); + Add5_7_1( ret ); return ret; } + private static void Add5_8_0( Changelog log ) + => log.NextVersion( "Version 0.5.8.0" ) + .RegisterEntry( "Added choices what Change Logs are to be displayed. It is recommended to just keep showing all." ) + .RegisterEntry( "Fixed an issue with Actor 201 using Your Character collections in cutscenes." ) + .RegisterEntry( "Fixed issues with and improved mod option editing." ) + .RegisterEntry( "Backend optimizations." ); + + private static void Add5_7_1( Changelog log ) + => log.NextVersion( "Version 0.5.7.1" ) + .RegisterEntry( "Fixed the Changelog window not considering UI Scale correctly." ) + .RegisterEntry( "Reworked Changelog display slightly." ); + private static void Add5_7_0( Changelog log ) => log.NextVersion( "Version 0.5.7.0" ) .RegisterEntry( "Added a Changelog!" ) .RegisterEntry( "Files in the UI category will no longer be deduplicated for the moment." ) .RegisterHighlight( "If you experience UI-related crashes, please re-import your UI mods.", 1 ) .RegisterEntry( "This is a temporary fix against those not-yet fully understood crashes and may be reworked later.", 1 ) + .RegisterHighlight( + "There is still a possibility of UI related mods crashing the game, we are still investigating - they behave very weirdly. If you continue to experience crashing, try disabling your UI mods.", + 1 ) + .RegisterEntry( + "On import, Penumbra will now show files with extensions '.ttmp', '.ttmp2' and '.pmp'. You can still select showing generic archive files." ) + .RegisterEntry( + "Penumbra Mod Pack ('.pmp') files are meant to be renames of any of the archive types that could already be imported that contain the necessary Penumbra meta files.", + 1 ) + .RegisterHighlight( + "If you distribute any mod as an archive specifically for Penumbra, you should change its extension to '.pmp'. Supported base archive types are ZIP, 7-Zip and RAR.", + 1 ) + .RegisterEntry( "Penumbra will now save mod backups with the file extension '.pmp'. They still are regular ZIP files.", 1 ) + .RegisterEntry( + "Existing backups in your current mod directory should be automatically renamed. If you manage multiple mod directories, you may need to migrate the other ones manually.", + 1 ) .RegisterEntry( "Fixed assigned collections not working correctly on adventurer plates." ) + .RegisterEntry( "Fixed a wrongly displayed folder line in some circumstances." ) + .RegisterEntry( "Fixed crash after deleting mod options." ) + .RegisterEntry( "Fixed Inspect Window collections not working correctly." ) + .RegisterEntry( "Made identically named options selectable in mod configuration. Do not name your options identically." ) .RegisterEntry( "Added some additional functionality for Mare Synchronos." ); } \ No newline at end of file diff --git a/Penumbra/UI/ConfigWindow.CollectionsTab.Inheritance.cs b/Penumbra/UI/ConfigWindow.CollectionsTab.Inheritance.cs index 366a5b4f..e344a303 100644 --- a/Penumbra/UI/ConfigWindow.CollectionsTab.Inheritance.cs +++ b/Penumbra/UI/ConfigWindow.CollectionsTab.Inheritance.cs @@ -8,7 +8,6 @@ using OtterGui; using OtterGui.Raii; using Penumbra.Collections; using Penumbra.UI.Classes; -using Penumbra.Util; namespace Penumbra.UI; diff --git a/Penumbra/UI/ConfigWindow.CollectionsTab.cs b/Penumbra/UI/ConfigWindow.CollectionsTab.cs index 1299f068..9c4a4547 100644 --- a/Penumbra/UI/ConfigWindow.CollectionsTab.cs +++ b/Penumbra/UI/ConfigWindow.CollectionsTab.cs @@ -6,7 +6,6 @@ using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.Collections; -using Penumbra.Util; namespace Penumbra.UI; diff --git a/Penumbra/UI/ConfigWindow.DebugTab.cs b/Penumbra/UI/ConfigWindow.DebugTab.cs index 68169211..fd36f308 100644 --- a/Penumbra/UI/ConfigWindow.DebugTab.cs +++ b/Penumbra/UI/ConfigWindow.DebugTab.cs @@ -11,7 +11,6 @@ using OtterGui; using OtterGui.Raii; using Penumbra.GameData.ByteString; using Penumbra.Interop.Loader; -using Penumbra.Interop.Resolver; using Penumbra.Interop.Structs; using CharacterUtility = Penumbra.Interop.CharacterUtility; diff --git a/Penumbra/UI/ConfigWindow.Misc.cs b/Penumbra/UI/ConfigWindow.Misc.cs index c6f1727f..c4141b73 100644 --- a/Penumbra/UI/ConfigWindow.Misc.cs +++ b/Penumbra/UI/ConfigWindow.Misc.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using System.Numerics; using Dalamud.Interface; @@ -13,7 +12,6 @@ using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; using Penumbra.Interop.Structs; using Penumbra.UI.Classes; -using Penumbra.Util; namespace Penumbra.UI; diff --git a/Penumbra/UI/ConfigWindow.ModPanel.Edit.cs b/Penumbra/UI/ConfigWindow.ModPanel.Edit.cs index b24a3f4e..4a3fec24 100644 --- a/Penumbra/UI/ConfigWindow.ModPanel.Edit.cs +++ b/Penumbra/UI/ConfigWindow.ModPanel.Edit.cs @@ -5,7 +5,6 @@ using System.IO; using System.Numerics; using Dalamud.Interface; using Dalamud.Interface.Components; -using Dalamud.Logging; using ImGuiNET; using OtterGui; using OtterGui.Raii; @@ -51,7 +50,7 @@ public partial class ConfigWindow } catch( Exception e ) { - PluginLog.Warning( e.Message ); + Penumbra.Log.Warning( e.Message ); } } @@ -478,7 +477,7 @@ public partial class ConfigWindow EditOption( panel, group, groupIdx, optionIdx ); } - DrawNewOption( panel._mod, groupIdx, panel._window._iconButtonSize ); + DrawNewOption( panel, groupIdx, panel._window._iconButtonSize ); } // Draw a line for a single option. @@ -519,9 +518,14 @@ public partial class ConfigWindow } // Draw the line to add a new option. - private static void DrawNewOption( Mod mod, int groupIdx, Vector2 iconButtonSize ) + private static void DrawNewOption( ModPanel panel, int groupIdx, Vector2 iconButtonSize ) { + var mod = panel._mod; + var group = mod.Groups[ groupIdx ]; ImGui.TableNextColumn(); + ImGui.AlignTextToFramePadding(); + ImGui.Selectable( $"Option #{group.Count + 1}" ); + Target( panel, group, groupIdx, group.Count ); ImGui.TableNextColumn(); ImGui.SetNextItemWidth( -1 ); var tmp = _newOptionNameIdx == groupIdx ? _newOptionName : string.Empty; @@ -565,14 +569,13 @@ public partial class ConfigWindow private static void Target( ModPanel panel, IModGroup group, int groupIdx, int optionIdx ) { - // TODO drag options to other groups without options. using var target = ImRaii.DragDropTarget(); if( !target.Success || !ImGuiUtil.IsDropping( DragDropLabel ) ) { return; } - if( _dragDropGroupIdx >= 0 && _dragDropOptionIdx >= 0 ) + if( _dragDropGroupIdx >= 0 && _dragDropOptionIdx >= 0 ) { if( _dragDropGroupIdx == groupIdx ) { @@ -581,15 +584,18 @@ public partial class ConfigWindow } else { - // Move from one group to another by deleting, then adding the option. - var sourceGroup = _dragDropGroupIdx; - var sourceOption = _dragDropOptionIdx; - var option = group[ _dragDropOptionIdx ]; - var priority = group.OptionPriority( _dragDropGroupIdx ); + // Move from one group to another by deleting, then adding, then moving the option. + var sourceGroupIdx = _dragDropGroupIdx; + var sourceOption = _dragDropOptionIdx; + var sourceGroup = panel._mod.Groups[ sourceGroupIdx ]; + var currentCount = group.Count; + var option = sourceGroup[sourceOption]; + var priority = sourceGroup.OptionPriority( _dragDropGroupIdx ); panel._delayedActions.Enqueue( () => { - Penumbra.ModManager.DeleteOption( panel._mod, sourceGroup, sourceOption ); + Penumbra.ModManager.DeleteOption( panel._mod, sourceGroupIdx, sourceOption ); Penumbra.ModManager.AddOption( panel._mod, groupIdx, option, priority ); + Penumbra.ModManager.MoveOption( panel._mod, groupIdx, currentCount, optionIdx ); } ); } } diff --git a/Penumbra/UI/ConfigWindow.ModPanel.Settings.cs b/Penumbra/UI/ConfigWindow.ModPanel.Settings.cs index 8fc57460..bb012be3 100644 --- a/Penumbra/UI/ConfigWindow.ModPanel.Settings.cs +++ b/Penumbra/UI/ConfigWindow.ModPanel.Settings.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using Dalamud.Interface; using ImGuiNET; @@ -168,10 +167,13 @@ public partial class ConfigWindow { for( var idx2 = 0; idx2 < group.Count; ++idx2 ) { + id.Push( idx2 ); if( ImGui.Selectable( group[ idx2 ].Name, idx2 == selectedOption ) ) { Penumbra.CollectionManager.Current.SetModSetting( _mod.Index, groupIdx, ( uint )idx2 ); } + + id.Pop(); } } @@ -201,6 +203,7 @@ public partial class ConfigWindow Widget.BeginFramedGroup( group.Name, group.Description ); for( var idx2 = 0; idx2 < group.Count; ++idx2 ) { + id.Push( idx2 ); var flag = 1u << idx2; var setting = ( flags & flag ) != 0; if( ImGui.Checkbox( group[ idx2 ].Name, ref setting ) ) @@ -208,6 +211,8 @@ public partial class ConfigWindow flags = setting ? flags | flag : flags & ~flag; Penumbra.CollectionManager.Current.SetModSetting( _mod.Index, groupIdx, flags ); } + + id.Pop(); } Widget.EndFramedGroup(); diff --git a/Penumbra/UI/ConfigWindow.ModsTab.cs b/Penumbra/UI/ConfigWindow.ModsTab.cs index fbafb806..c3288214 100644 --- a/Penumbra/UI/ConfigWindow.ModsTab.cs +++ b/Penumbra/UI/ConfigWindow.ModsTab.cs @@ -7,7 +7,6 @@ using Penumbra.UI.Classes; using System; using System.Linq; using System.Numerics; -using Dalamud.Logging; namespace Penumbra.UI; @@ -42,8 +41,8 @@ public partial class ConfigWindow } catch( Exception e ) { - PluginLog.Error( $"Exception thrown during ModPanel Render:\n{e}" ); - PluginLog.Error( $"{Penumbra.ModManager.Count} Mods\n" + Penumbra.Log.Error( $"Exception thrown during ModPanel Render:\n{e}" ); + Penumbra.Log.Error( $"{Penumbra.ModManager.Count} Mods\n" + $"{Penumbra.CollectionManager.Current.AnonymizedName} Current Collection\n" + $"{Penumbra.CollectionManager.Current.Settings.Count} Settings\n" + $"{_selector.SortMode.Name} Sort Mode\n" diff --git a/Penumbra/UI/ConfigWindow.SettingsTab.cs b/Penumbra/UI/ConfigWindow.SettingsTab.cs index 242e33b4..2cbd2c24 100644 --- a/Penumbra/UI/ConfigWindow.SettingsTab.cs +++ b/Penumbra/UI/ConfigWindow.SettingsTab.cs @@ -335,7 +335,7 @@ public partial class ConfigWindow + "Not directly affiliated and potentially, but not usually out of date." ); } - private static void DrawSupportButtons() + private void DrawSupportButtons() { var width = ImGui.CalcTextSize( SupportInfoButtonText ).X + ImGui.GetStyle().FramePadding.X * 2; var xPos = ImGui.GetWindowWidth() - width; @@ -363,7 +363,7 @@ public partial class ConfigWindow ImGui.SetCursorPos( new Vector2( xPos, 4 * ImGui.GetFrameHeightWithSpacing() ) ); if( ImGui.Button( "Show Changelogs", new Vector2( width, 0 ) ) ) { - Penumbra.Config.LastSeenVersion = 0; + _window._penumbra.ForceChangelogOpen(); } } } diff --git a/Penumbra/UI/ConfigWindow.cs b/Penumbra/UI/ConfigWindow.cs index 30465fb6..6a46ca1b 100644 --- a/Penumbra/UI/ConfigWindow.cs +++ b/Penumbra/UI/ConfigWindow.cs @@ -2,7 +2,6 @@ using System; using System.Numerics; using Dalamud.Interface; using Dalamud.Interface.Windowing; -using Dalamud.Logging; using ImGuiNET; using OtterGui.Raii; using Penumbra.UI.Classes; @@ -92,7 +91,7 @@ public sealed partial class ConfigWindow : Window, IDisposable } catch( Exception e ) { - PluginLog.Error( $"Exception thrown during UI Render:\n{e}" ); + Penumbra.Log.Error( $"Exception thrown during UI Render:\n{e}" ); } } diff --git a/Penumbra/Util/FrameworkManager.cs b/Penumbra/Util/FrameworkManager.cs index d19179da..5a52d340 100644 --- a/Penumbra/Util/FrameworkManager.cs +++ b/Penumbra/Util/FrameworkManager.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Dalamud.Game; -using Dalamud.Logging; namespace Penumbra.Util; @@ -58,7 +57,7 @@ public class FrameworkManager : IDisposable } catch( Exception e ) { - PluginLog.Error( $"Problem saving data:\n{e}" ); + Penumbra.Log.Error( $"Problem saving data:\n{e}" ); } } diff --git a/Penumbra/Util/PenumbraSqPackStream.cs b/Penumbra/Util/PenumbraSqPackStream.cs index 017d70c6..7bb0687d 100644 --- a/Penumbra/Util/PenumbraSqPackStream.cs +++ b/Penumbra/Util/PenumbraSqPackStream.cs @@ -334,14 +334,13 @@ public class PenumbraSqPackStream : IDisposable if( blockHeader.CompressedSize == 32000 ) { dest.Write( Reader.ReadBytes( ( int )blockHeader.UncompressedSize ) ); - return blockHeader.UncompressedSize; } - - var data = Reader.ReadBytes( ( int )blockHeader.CompressedSize ); - - using( var compressedStream = new MemoryStream( data ) ) + else { - using var zlibStream = new DeflateStream( compressedStream, CompressionMode.Decompress ); + var data = Reader.ReadBytes( ( int )blockHeader.CompressedSize ); + + using var compressedStream = new MemoryStream( data ); + using var zlibStream = new DeflateStream( compressedStream, CompressionMode.Decompress ); zlibStream.CopyTo( dest ); } diff --git a/repo.json b/repo.json index c32d148e..f6a1fc63 100644 --- a/repo.json +++ b/repo.json @@ -4,8 +4,8 @@ "Name": "Penumbra", "Description": "Runtime mod loader and manager.", "InternalName": "Penumbra", - "AssemblyVersion": "0.5.6.3", - "TestingAssemblyVersion": "0.5.6.3", + "AssemblyVersion": "0.5.7.1", + "TestingAssemblyVersion": "0.5.7.1", "RepoUrl": "https://github.com/xivdev/Penumbra", "ApplicableVersion": "any", "DalamudApiLevel": 7, @@ -16,9 +16,9 @@ "LoadPriority": 69420, "LoadRequiredState": 2, "LoadSync": true, - "DownloadLinkInstall": "https://github.com/xivdev/Penumbra/releases/download/0.5.6.3/Penumbra.zip", - "DownloadLinkTesting": "https://github.com/xivdev/Penumbra/releases/download/0.5.6.3/Penumbra.zip", - "DownloadLinkUpdate": "https://github.com/xivdev/Penumbra/releases/download/0.5.6.3/Penumbra.zip", + "DownloadLinkInstall": "https://github.com/xivdev/Penumbra/releases/download/0.5.7.1/Penumbra.zip", + "DownloadLinkTesting": "https://github.com/xivdev/Penumbra/releases/download/0.5.7.1/Penumbra.zip", + "DownloadLinkUpdate": "https://github.com/xivdev/Penumbra/releases/download/0.5.7.1/Penumbra.zip", "IconUrl": "https://raw.githubusercontent.com/xivdev/Penumbra/master/images/icon.png" } ]