mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-09 09:24:37 +01:00
Merge branch 'master' into Textures
# Conflicts: # Penumbra/Import/TexToolsImporter.Archives.cs # Penumbra/UI/Classes/ModEditWindow.Textures.cs
This commit is contained in:
commit
19e5e94c64
97 changed files with 861 additions and 651 deletions
2
OtterGui
2
OtterGui
|
|
@ -1 +1 @@
|
|||
Subproject commit 9ec5e2ad2f2d35d62c2ac7c300b914fffbda2191
|
||||
Subproject commit b92dbe60887503a77a89aeae80729236fb2bfa10
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Penumbra.GameData.Util;
|
||||
|
||||
namespace Penumbra.GameData.ByteString;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using System;
|
||||
|
||||
namespace Penumbra.GameData.Enums;
|
||||
|
||||
public enum ObjectType : byte
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Dalamud;
|
||||
using Dalamud.Data;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Penumbra.GameData.Enums;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
|
|||
|
|
@ -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}." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 );
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using Penumbra.Mods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Penumbra.Mods;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Penumbra.Mods;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Penumbra.Mods;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using System.Text.RegularExpressions;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Util;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Penumbra.Import;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Penumbra.Util;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Import;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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" )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
147
Penumbra/Interop/CharacterUtility.List.cs
Normal file
147
Penumbra/Interop/CharacterUtility.List.cs
Normal file
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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." );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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" )}." );
|
||||
}
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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." )}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using Penumbra.Collections;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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<ExpandedEqdpFile>() )
|
||||
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 ) );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Structs;
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
using System.Collections.Generic;
|
||||
using Penumbra.GameData.ByteString;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public partial class Mod
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
// }
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<SubMod>().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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}." );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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." );
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ using OtterGui;
|
|||
using OtterGui.Raii;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
10
repo.json
10
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"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue