mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Rework around a saner import popup and decouple logic from interface.
This commit is contained in:
parent
bfb630d317
commit
bbfc9a0a6f
16 changed files with 478 additions and 411 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 13ade28e21bed02e16bbd081b2e6567382cf69bd
|
||||
Subproject commit d7e8c8c44d92bd50764394af51ac24cb07f362dc
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
using Dalamud.Game.ClientState.Keys;
|
||||
using OtterGui.Filesystem;
|
||||
using OtterGui.FileSystem.Selector;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.ModsTab;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Penumbra.Api {
|
||||
public class ExternalModImporter {
|
||||
private static ModFileSystemSelector modFileSystemSelectorInstance;
|
||||
|
||||
public static ModFileSystemSelector ModFileSystemSelectorInstance { get => modFileSystemSelectorInstance; set => modFileSystemSelectorInstance = value; }
|
||||
|
||||
public static void UnpackMod(string modPackagePath)
|
||||
{
|
||||
modFileSystemSelectorInstance.ImportStandaloneModPackage(modPackagePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,12 +12,12 @@ public class HttpApi : IDisposable
|
|||
private partial class Controller : WebApiController
|
||||
{
|
||||
// @formatter:off
|
||||
[Route( HttpVerbs.Get, "/mods" )] public partial object? GetMods();
|
||||
[Route( HttpVerbs.Post, "/redraw" )] public partial Task Redraw();
|
||||
[Route( HttpVerbs.Post, "/redrawAll" )] public partial void RedrawAll();
|
||||
[Route( HttpVerbs.Post, "/reloadmod" )] public partial Task ReloadMod();
|
||||
[Route( HttpVerbs.Post, "/unpackmod" )] public partial Task UnpackMod();
|
||||
[Route( HttpVerbs.Post, "/openwindow")] public partial Task OpenWindow();
|
||||
[Route( HttpVerbs.Get, "/mods" )] public partial object? GetMods();
|
||||
[Route( HttpVerbs.Post, "/redraw" )] public partial Task Redraw();
|
||||
[Route( HttpVerbs.Post, "/redrawAll" )] public partial void RedrawAll();
|
||||
[Route( HttpVerbs.Post, "/reloadmod" )] public partial Task ReloadMod();
|
||||
[Route( HttpVerbs.Post, "/installmod" )] public partial Task InstallMod();
|
||||
[Route( HttpVerbs.Post, "/openwindow" )] public partial void OpenWindow();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
|
|
@ -103,16 +103,15 @@ public class HttpApi : IDisposable
|
|||
_api.ReloadMod(data.Path, data.Name);
|
||||
}
|
||||
|
||||
public async partial Task UnpackMod()
|
||||
public async partial Task InstallMod()
|
||||
{
|
||||
var data = await HttpContext.GetRequestDataAsync<ModUnpackData>();
|
||||
Penumbra.Log.Debug($"[HTTP] {nameof(UnpackMod)} triggered with {data}.");
|
||||
// Unpack the mod package if its valid.
|
||||
var data = await HttpContext.GetRequestDataAsync<ModInstallData>();
|
||||
Penumbra.Log.Debug($"[HTTP] {nameof(InstallMod)} triggered with {data}.");
|
||||
if (data.Path.Length != 0)
|
||||
_api.UnpackMod(data.Path);
|
||||
_api.InstallMod(data.Path);
|
||||
}
|
||||
|
||||
public async partial Task OpenWindow()
|
||||
public partial void OpenWindow()
|
||||
{
|
||||
Penumbra.Log.Debug($"[HTTP] {nameof(OpenWindow)} triggered.");
|
||||
_api.OpenMainWindow(TabType.Mods, string.Empty, string.Empty);
|
||||
|
|
@ -125,9 +124,9 @@ public class HttpApi : IDisposable
|
|||
{ }
|
||||
}
|
||||
|
||||
private record ModUnpackData(string Path)
|
||||
private record ModInstallData(string Path)
|
||||
{
|
||||
public ModUnpackData()
|
||||
public ModInstallData()
|
||||
: this(string.Empty)
|
||||
{ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ using Penumbra.Meta.Manipulations;
|
|||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.Collections.Manager;
|
||||
|
||||
using Penumbra.Collections.Manager;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
public class IpcTester : IDisposable
|
||||
|
|
@ -847,13 +847,15 @@ public class IpcTester : IDisposable
|
|||
{
|
||||
private readonly DalamudPluginInterface _pi;
|
||||
|
||||
private string _modDirectory = string.Empty;
|
||||
private string _modName = string.Empty;
|
||||
private string _pathInput = string.Empty;
|
||||
private string _modDirectory = string.Empty;
|
||||
private string _modName = string.Empty;
|
||||
private string _pathInput = string.Empty;
|
||||
private string _newInstallPath = string.Empty;
|
||||
private PenumbraApiEc _lastReloadEc;
|
||||
private PenumbraApiEc _lastAddEc;
|
||||
private PenumbraApiEc _lastDeleteEc;
|
||||
private PenumbraApiEc _lastSetPathEc;
|
||||
private PenumbraApiEc _lastInstallEc;
|
||||
private IList<(string, string)> _mods = new List<(string, string)>();
|
||||
|
||||
public readonly EventSubscriber<string> DeleteSubscriber;
|
||||
|
|
@ -895,9 +897,10 @@ public class IpcTester : IDisposable
|
|||
if (!_)
|
||||
return;
|
||||
|
||||
ImGui.InputTextWithHint("##modDir", "Mod Directory Name...", ref _modDirectory, 100);
|
||||
ImGui.InputTextWithHint("##modName", "Mod Name...", ref _modName, 100);
|
||||
ImGui.InputTextWithHint("##path", "New Path...", ref _pathInput, 100);
|
||||
ImGui.InputTextWithHint("##install", "Install File Path...", ref _newInstallPath, 100);
|
||||
ImGui.InputTextWithHint("##modDir", "Mod Directory Name...", ref _modDirectory, 100);
|
||||
ImGui.InputTextWithHint("##modName", "Mod Name...", ref _modName, 100);
|
||||
ImGui.InputTextWithHint("##path", "New Path...", ref _pathInput, 100);
|
||||
using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit);
|
||||
if (!table)
|
||||
return;
|
||||
|
|
@ -916,6 +919,13 @@ public class IpcTester : IDisposable
|
|||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(_lastReloadEc.ToString());
|
||||
|
||||
DrawIntro(Ipc.InstallMod.Label, "Install Mod");
|
||||
if (ImGui.Button("Install"))
|
||||
_lastInstallEc = Ipc.InstallMod.Subscriber(_pi).Invoke(_newInstallPath);
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(_lastInstallEc.ToString());
|
||||
|
||||
DrawIntro(Ipc.AddMod.Label, "Add Mod");
|
||||
if (ImGui.Button("Add"))
|
||||
_lastAddEc = Ipc.AddMod.Subscriber(_pi).Invoke(_modDirectory);
|
||||
|
|
@ -1140,7 +1150,7 @@ public class IpcTester : IDisposable
|
|||
private class Temporary
|
||||
{
|
||||
private readonly DalamudPluginInterface _pi;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly ModManager _modManager;
|
||||
|
||||
public Temporary(DalamudPluginInterface pi, ModManager modManager)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -109,23 +109,25 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
private ActorService _actors;
|
||||
private CollectionResolver _collectionResolver;
|
||||
private CutsceneService _cutsceneService;
|
||||
private ModImportManager _modImportManager;
|
||||
|
||||
public unsafe PenumbraApi(CommunicatorService communicator, Penumbra penumbra, ModManager modManager, ResourceLoader resourceLoader,
|
||||
Configuration config, CollectionManager collectionManager, DalamudServices dalamud, TempCollectionManager tempCollections,
|
||||
TempModManager tempMods, ActorService actors, CollectionResolver collectionResolver, CutsceneService cutsceneService)
|
||||
TempModManager tempMods, ActorService actors, CollectionResolver collectionResolver, CutsceneService cutsceneService, ModImportManager modImportManager)
|
||||
{
|
||||
_communicator = communicator;
|
||||
_penumbra = penumbra;
|
||||
_modManager = modManager;
|
||||
_resourceLoader = resourceLoader;
|
||||
_config = config;
|
||||
_collectionManager = collectionManager;
|
||||
_dalamud = dalamud;
|
||||
_tempCollections = tempCollections;
|
||||
_tempMods = tempMods;
|
||||
_actors = actors;
|
||||
_collectionResolver = collectionResolver;
|
||||
_cutsceneService = cutsceneService;
|
||||
_communicator = communicator;
|
||||
_penumbra = penumbra;
|
||||
_modManager = modManager;
|
||||
_resourceLoader = resourceLoader;
|
||||
_config = config;
|
||||
_collectionManager = collectionManager;
|
||||
_dalamud = dalamud;
|
||||
_tempCollections = tempCollections;
|
||||
_tempMods = tempMods;
|
||||
_actors = actors;
|
||||
_collectionResolver = collectionResolver;
|
||||
_cutsceneService = cutsceneService;
|
||||
_modImportManager = modImportManager;
|
||||
|
||||
_lumina = (Lumina.GameData?)_dalamud.GameData.GetType()
|
||||
.GetField("gameData", BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
|
|
@ -602,11 +604,11 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return PenumbraApiEc.Success;
|
||||
}
|
||||
|
||||
public PenumbraApiEc UnpackMod(string modFilePackagePath)
|
||||
public PenumbraApiEc InstallMod(string modFilePackagePath)
|
||||
{
|
||||
if (File.Exists(modFilePackagePath))
|
||||
{
|
||||
ExternalModImporter.UnpackMod(modFilePackagePath);
|
||||
_modImportManager.AddUnpack(modFilePackagePath);
|
||||
return PenumbraApiEc.Success;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Penumbra.Mods.Manager;
|
|||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
using CurrentSettings = ValueTuple< PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)? >;
|
||||
using CurrentSettings = ValueTuple<PenumbraApiEc, (bool, int, IDictionary<string, IList<string>>, bool)?>;
|
||||
|
||||
public class PenumbraIpcProviders : IDisposable
|
||||
{
|
||||
|
|
@ -18,210 +18,215 @@ public class PenumbraIpcProviders : IDisposable
|
|||
internal readonly IpcTester Tester;
|
||||
|
||||
// Plugin State
|
||||
internal readonly EventProvider Initialized;
|
||||
internal readonly EventProvider Disposed;
|
||||
internal readonly FuncProvider< int > ApiVersion;
|
||||
internal readonly FuncProvider< (int Breaking, int Features) > ApiVersions;
|
||||
internal readonly FuncProvider< bool > GetEnabledState;
|
||||
internal readonly EventProvider< bool > EnabledChange;
|
||||
internal readonly EventProvider Initialized;
|
||||
internal readonly EventProvider Disposed;
|
||||
internal readonly FuncProvider<int> ApiVersion;
|
||||
internal readonly FuncProvider<(int Breaking, int Features)> ApiVersions;
|
||||
internal readonly FuncProvider<bool> GetEnabledState;
|
||||
internal readonly EventProvider<bool> EnabledChange;
|
||||
|
||||
// Configuration
|
||||
internal readonly FuncProvider< string > GetModDirectory;
|
||||
internal readonly FuncProvider< string > GetConfiguration;
|
||||
internal readonly EventProvider< string, bool > ModDirectoryChanged;
|
||||
internal readonly FuncProvider<string> GetModDirectory;
|
||||
internal readonly FuncProvider<string> GetConfiguration;
|
||||
internal readonly EventProvider<string, bool> ModDirectoryChanged;
|
||||
|
||||
// UI
|
||||
internal readonly EventProvider< string > PreSettingsDraw;
|
||||
internal readonly EventProvider< string > PostSettingsDraw;
|
||||
internal readonly EventProvider< ChangedItemType, uint > ChangedItemTooltip;
|
||||
internal readonly EventProvider< MouseButton, ChangedItemType, uint > ChangedItemClick;
|
||||
internal readonly FuncProvider< TabType, string, string, PenumbraApiEc > OpenMainWindow;
|
||||
internal readonly ActionProvider CloseMainWindow;
|
||||
internal readonly EventProvider<string> PreSettingsDraw;
|
||||
internal readonly EventProvider<string> PostSettingsDraw;
|
||||
internal readonly EventProvider<ChangedItemType, uint> ChangedItemTooltip;
|
||||
internal readonly EventProvider<MouseButton, ChangedItemType, uint> ChangedItemClick;
|
||||
internal readonly FuncProvider<TabType, string, string, PenumbraApiEc> OpenMainWindow;
|
||||
internal readonly ActionProvider CloseMainWindow;
|
||||
|
||||
// Redrawing
|
||||
internal readonly ActionProvider< RedrawType > RedrawAll;
|
||||
internal readonly ActionProvider< GameObject, RedrawType > RedrawObject;
|
||||
internal readonly ActionProvider< int, RedrawType > RedrawObjectByIndex;
|
||||
internal readonly ActionProvider< string, RedrawType > RedrawObjectByName;
|
||||
internal readonly EventProvider< nint, int > GameObjectRedrawn;
|
||||
internal readonly ActionProvider<RedrawType> RedrawAll;
|
||||
internal readonly ActionProvider<GameObject, RedrawType> RedrawObject;
|
||||
internal readonly ActionProvider<int, RedrawType> RedrawObjectByIndex;
|
||||
internal readonly ActionProvider<string, RedrawType> RedrawObjectByName;
|
||||
internal readonly EventProvider<nint, int> GameObjectRedrawn;
|
||||
|
||||
// Game State
|
||||
internal readonly FuncProvider< nint, (nint, string) > GetDrawObjectInfo;
|
||||
internal readonly FuncProvider< int, int > GetCutsceneParentIndex;
|
||||
internal readonly EventProvider< nint, string, nint, nint, nint > CreatingCharacterBase;
|
||||
internal readonly EventProvider< nint, string, nint > CreatedCharacterBase;
|
||||
internal readonly EventProvider< nint, string, string > GameObjectResourcePathResolved;
|
||||
internal readonly FuncProvider<nint, (nint, string)> GetDrawObjectInfo;
|
||||
internal readonly FuncProvider<int, int> GetCutsceneParentIndex;
|
||||
internal readonly EventProvider<nint, string, nint, nint, nint> CreatingCharacterBase;
|
||||
internal readonly EventProvider<nint, string, nint> CreatedCharacterBase;
|
||||
internal readonly EventProvider<nint, string, string> GameObjectResourcePathResolved;
|
||||
|
||||
// Resolve
|
||||
internal readonly FuncProvider< string, string > ResolveDefaultPath;
|
||||
internal readonly FuncProvider< string, string > ResolveInterfacePath;
|
||||
internal readonly FuncProvider< string, string > ResolvePlayerPath;
|
||||
internal readonly FuncProvider< string, int, string > ResolveGameObjectPath;
|
||||
internal readonly FuncProvider< string, string, string > ResolveCharacterPath;
|
||||
internal readonly FuncProvider< string, string, string[] > ReverseResolvePath;
|
||||
internal readonly FuncProvider< string, int, string[] > ReverseResolveGameObjectPath;
|
||||
internal readonly FuncProvider< string, string[] > ReverseResolvePlayerPath;
|
||||
internal readonly FuncProvider< string[], string[], (string[], string[][]) > ResolvePlayerPaths;
|
||||
internal readonly FuncProvider<string, string> ResolveDefaultPath;
|
||||
internal readonly FuncProvider<string, string> ResolveInterfacePath;
|
||||
internal readonly FuncProvider<string, string> ResolvePlayerPath;
|
||||
internal readonly FuncProvider<string, int, string> ResolveGameObjectPath;
|
||||
internal readonly FuncProvider<string, string, string> ResolveCharacterPath;
|
||||
internal readonly FuncProvider<string, string, string[]> ReverseResolvePath;
|
||||
internal readonly FuncProvider<string, int, string[]> ReverseResolveGameObjectPath;
|
||||
internal readonly FuncProvider<string, string[]> ReverseResolvePlayerPath;
|
||||
internal readonly FuncProvider<string[], string[], (string[], string[][])> ResolvePlayerPaths;
|
||||
|
||||
// Collections
|
||||
internal readonly FuncProvider< IList< string > > GetCollections;
|
||||
internal readonly FuncProvider< string > GetCurrentCollectionName;
|
||||
internal readonly FuncProvider< string > GetDefaultCollectionName;
|
||||
internal readonly FuncProvider< string > GetInterfaceCollectionName;
|
||||
internal readonly FuncProvider< string, (string, bool) > GetCharacterCollectionName;
|
||||
internal readonly FuncProvider< ApiCollectionType, string > GetCollectionForType;
|
||||
internal readonly FuncProvider< ApiCollectionType, string, bool, bool, (PenumbraApiEc, string) > SetCollectionForType;
|
||||
internal readonly FuncProvider< int, (bool, bool, string) > GetCollectionForObject;
|
||||
internal readonly FuncProvider< int, string, bool, bool, (PenumbraApiEc, string) > SetCollectionForObject;
|
||||
internal readonly FuncProvider< string, IReadOnlyDictionary< string, object? > > GetChangedItems;
|
||||
internal readonly FuncProvider<IList<string>> GetCollections;
|
||||
internal readonly FuncProvider<string> GetCurrentCollectionName;
|
||||
internal readonly FuncProvider<string> GetDefaultCollectionName;
|
||||
internal readonly FuncProvider<string> GetInterfaceCollectionName;
|
||||
internal readonly FuncProvider<string, (string, bool)> GetCharacterCollectionName;
|
||||
internal readonly FuncProvider<ApiCollectionType, string> GetCollectionForType;
|
||||
internal readonly FuncProvider<ApiCollectionType, string, bool, bool, (PenumbraApiEc, string)> SetCollectionForType;
|
||||
internal readonly FuncProvider<int, (bool, bool, string)> GetCollectionForObject;
|
||||
internal readonly FuncProvider<int, string, bool, bool, (PenumbraApiEc, string)> SetCollectionForObject;
|
||||
internal readonly FuncProvider<string, IReadOnlyDictionary<string, object?>> GetChangedItems;
|
||||
|
||||
// Meta
|
||||
internal readonly FuncProvider< string > GetPlayerMetaManipulations;
|
||||
internal readonly FuncProvider< string, string > GetMetaManipulations;
|
||||
internal readonly FuncProvider< int, string > GetGameObjectMetaManipulations;
|
||||
internal readonly FuncProvider<string> GetPlayerMetaManipulations;
|
||||
internal readonly FuncProvider<string, string> GetMetaManipulations;
|
||||
internal readonly FuncProvider<int, string> GetGameObjectMetaManipulations;
|
||||
|
||||
// Mods
|
||||
internal readonly FuncProvider< IList< (string, string) > > GetMods;
|
||||
internal readonly FuncProvider< string, string, PenumbraApiEc > ReloadMod;
|
||||
internal readonly FuncProvider< string, PenumbraApiEc > AddMod;
|
||||
internal readonly FuncProvider< string, string, PenumbraApiEc > DeleteMod;
|
||||
internal readonly FuncProvider< string, string, (PenumbraApiEc, string, bool) > GetModPath;
|
||||
internal readonly FuncProvider< string, string, string, PenumbraApiEc > SetModPath;
|
||||
internal readonly EventProvider< string > ModDeleted;
|
||||
internal readonly EventProvider< string > ModAdded;
|
||||
internal readonly EventProvider< string, string > ModMoved;
|
||||
internal readonly FuncProvider<IList<(string, string)>> GetMods;
|
||||
internal readonly FuncProvider<string, string, PenumbraApiEc> ReloadMod;
|
||||
internal readonly FuncProvider<string, PenumbraApiEc> InstallMod;
|
||||
internal readonly FuncProvider<string, PenumbraApiEc> AddMod;
|
||||
internal readonly FuncProvider<string, string, PenumbraApiEc> DeleteMod;
|
||||
internal readonly FuncProvider<string, string, (PenumbraApiEc, string, bool)> GetModPath;
|
||||
internal readonly FuncProvider<string, string, string, PenumbraApiEc> SetModPath;
|
||||
internal readonly EventProvider<string> ModDeleted;
|
||||
internal readonly EventProvider<string> ModAdded;
|
||||
internal readonly EventProvider<string, string> ModMoved;
|
||||
|
||||
// ModSettings
|
||||
internal readonly FuncProvider< string, string, IDictionary< string, (IList< string >, GroupType) >? > GetAvailableModSettings;
|
||||
internal readonly FuncProvider< string, string, string, bool, CurrentSettings > GetCurrentModSettings;
|
||||
internal readonly FuncProvider< string, string, string, bool, PenumbraApiEc > TryInheritMod;
|
||||
internal readonly FuncProvider< string, string, string, bool, PenumbraApiEc > TrySetMod;
|
||||
internal readonly FuncProvider< string, string, string, int, PenumbraApiEc > TrySetModPriority;
|
||||
internal readonly FuncProvider< string, string, string, string, string, PenumbraApiEc > TrySetModSetting;
|
||||
internal readonly FuncProvider< string, string, string, string, IReadOnlyList< string >, PenumbraApiEc > TrySetModSettings;
|
||||
internal readonly EventProvider< ModSettingChange, string, string, bool > ModSettingChanged;
|
||||
internal readonly FuncProvider< string, string, string, PenumbraApiEc > CopyModSettings;
|
||||
internal readonly FuncProvider<string, string, IDictionary<string, (IList<string>, GroupType)>?> GetAvailableModSettings;
|
||||
internal readonly FuncProvider<string, string, string, bool, CurrentSettings> GetCurrentModSettings;
|
||||
internal readonly FuncProvider<string, string, string, bool, PenumbraApiEc> TryInheritMod;
|
||||
internal readonly FuncProvider<string, string, string, bool, PenumbraApiEc> TrySetMod;
|
||||
internal readonly FuncProvider<string, string, string, int, PenumbraApiEc> TrySetModPriority;
|
||||
internal readonly FuncProvider<string, string, string, string, string, PenumbraApiEc> TrySetModSetting;
|
||||
internal readonly FuncProvider<string, string, string, string, IReadOnlyList<string>, PenumbraApiEc> TrySetModSettings;
|
||||
internal readonly EventProvider<ModSettingChange, string, string, bool> ModSettingChanged;
|
||||
internal readonly FuncProvider<string, string, string, PenumbraApiEc> CopyModSettings;
|
||||
|
||||
// Temporary
|
||||
internal readonly FuncProvider< string, string, bool, (PenumbraApiEc, string) > CreateTemporaryCollection;
|
||||
internal readonly FuncProvider< string, PenumbraApiEc > RemoveTemporaryCollection;
|
||||
internal readonly FuncProvider< string, PenumbraApiEc > CreateNamedTemporaryCollection;
|
||||
internal readonly FuncProvider< string, PenumbraApiEc > RemoveTemporaryCollectionByName;
|
||||
internal readonly FuncProvider< string, int, bool, PenumbraApiEc > AssignTemporaryCollection;
|
||||
internal readonly FuncProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc > AddTemporaryModAll;
|
||||
internal readonly FuncProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc > AddTemporaryMod;
|
||||
internal readonly FuncProvider< string, int, PenumbraApiEc > RemoveTemporaryModAll;
|
||||
internal readonly FuncProvider< string, string, int, PenumbraApiEc > RemoveTemporaryMod;
|
||||
internal readonly FuncProvider<string, string, bool, (PenumbraApiEc, string)> CreateTemporaryCollection;
|
||||
internal readonly FuncProvider<string, PenumbraApiEc> RemoveTemporaryCollection;
|
||||
internal readonly FuncProvider<string, PenumbraApiEc> CreateNamedTemporaryCollection;
|
||||
internal readonly FuncProvider<string, PenumbraApiEc> RemoveTemporaryCollectionByName;
|
||||
internal readonly FuncProvider<string, int, bool, PenumbraApiEc> AssignTemporaryCollection;
|
||||
internal readonly FuncProvider<string, Dictionary<string, string>, string, int, PenumbraApiEc> AddTemporaryModAll;
|
||||
internal readonly FuncProvider<string, string, Dictionary<string, string>, string, int, PenumbraApiEc> AddTemporaryMod;
|
||||
internal readonly FuncProvider<string, int, PenumbraApiEc> RemoveTemporaryModAll;
|
||||
internal readonly FuncProvider<string, string, int, PenumbraApiEc> RemoveTemporaryMod;
|
||||
|
||||
public PenumbraIpcProviders( DalamudPluginInterface pi, IPenumbraApi api, ModManager modManager )
|
||||
public PenumbraIpcProviders(DalamudPluginInterface pi, IPenumbraApi api, ModManager modManager)
|
||||
{
|
||||
Api = api;
|
||||
|
||||
// Plugin State
|
||||
Initialized = Ipc.Initialized.Provider( pi );
|
||||
Disposed = Ipc.Disposed.Provider( pi );
|
||||
ApiVersion = Ipc.ApiVersion.Provider( pi, DeprecatedVersion );
|
||||
ApiVersions = Ipc.ApiVersions.Provider( pi, () => Api.ApiVersion );
|
||||
GetEnabledState = Ipc.GetEnabledState.Provider( pi, Api.GetEnabledState );
|
||||
EnabledChange = Ipc.EnabledChange.Provider( pi, () => Api.EnabledChange += EnabledChangeEvent, () => Api.EnabledChange -= EnabledChangeEvent );
|
||||
Initialized = Ipc.Initialized.Provider(pi);
|
||||
Disposed = Ipc.Disposed.Provider(pi);
|
||||
ApiVersion = Ipc.ApiVersion.Provider(pi, DeprecatedVersion);
|
||||
ApiVersions = Ipc.ApiVersions.Provider(pi, () => Api.ApiVersion);
|
||||
GetEnabledState = Ipc.GetEnabledState.Provider(pi, Api.GetEnabledState);
|
||||
EnabledChange =
|
||||
Ipc.EnabledChange.Provider(pi, () => Api.EnabledChange += EnabledChangeEvent, () => Api.EnabledChange -= EnabledChangeEvent);
|
||||
|
||||
// Configuration
|
||||
GetModDirectory = Ipc.GetModDirectory.Provider( pi, Api.GetModDirectory );
|
||||
GetConfiguration = Ipc.GetConfiguration.Provider( pi, Api.GetConfiguration );
|
||||
ModDirectoryChanged = Ipc.ModDirectoryChanged.Provider( pi, a => Api.ModDirectoryChanged += a, a => Api.ModDirectoryChanged -= a );
|
||||
GetModDirectory = Ipc.GetModDirectory.Provider(pi, Api.GetModDirectory);
|
||||
GetConfiguration = Ipc.GetConfiguration.Provider(pi, Api.GetConfiguration);
|
||||
ModDirectoryChanged = Ipc.ModDirectoryChanged.Provider(pi, a => Api.ModDirectoryChanged += a, a => Api.ModDirectoryChanged -= a);
|
||||
|
||||
// UI
|
||||
PreSettingsDraw = Ipc.PreSettingsDraw.Provider( pi, a => Api.PreSettingsPanelDraw += a, a => Api.PreSettingsPanelDraw -= a );
|
||||
PostSettingsDraw = Ipc.PostSettingsDraw.Provider( pi, a => Api.PostSettingsPanelDraw += a, a => Api.PostSettingsPanelDraw -= a );
|
||||
ChangedItemTooltip = Ipc.ChangedItemTooltip.Provider( pi, () => Api.ChangedItemTooltip += OnTooltip, () => Api.ChangedItemTooltip -= OnTooltip );
|
||||
ChangedItemClick = Ipc.ChangedItemClick.Provider( pi, () => Api.ChangedItemClicked += OnClick, () => Api.ChangedItemClicked -= OnClick );
|
||||
OpenMainWindow = Ipc.OpenMainWindow.Provider( pi, Api.OpenMainWindow );
|
||||
CloseMainWindow = Ipc.CloseMainWindow.Provider( pi, Api.CloseMainWindow );
|
||||
PreSettingsDraw = Ipc.PreSettingsDraw.Provider(pi, a => Api.PreSettingsPanelDraw += a, a => Api.PreSettingsPanelDraw -= a);
|
||||
PostSettingsDraw = Ipc.PostSettingsDraw.Provider(pi, a => Api.PostSettingsPanelDraw += a, a => Api.PostSettingsPanelDraw -= a);
|
||||
ChangedItemTooltip =
|
||||
Ipc.ChangedItemTooltip.Provider(pi, () => Api.ChangedItemTooltip += OnTooltip, () => Api.ChangedItemTooltip -= OnTooltip);
|
||||
ChangedItemClick = Ipc.ChangedItemClick.Provider(pi, () => Api.ChangedItemClicked += OnClick, () => Api.ChangedItemClicked -= OnClick);
|
||||
OpenMainWindow = Ipc.OpenMainWindow.Provider(pi, Api.OpenMainWindow);
|
||||
CloseMainWindow = Ipc.CloseMainWindow.Provider(pi, Api.CloseMainWindow);
|
||||
|
||||
// Redrawing
|
||||
RedrawAll = Ipc.RedrawAll.Provider( pi, Api.RedrawAll );
|
||||
RedrawObject = Ipc.RedrawObject.Provider( pi, Api.RedrawObject );
|
||||
RedrawObjectByIndex = Ipc.RedrawObjectByIndex.Provider( pi, Api.RedrawObject );
|
||||
RedrawObjectByName = Ipc.RedrawObjectByName.Provider( pi, Api.RedrawObject );
|
||||
GameObjectRedrawn = Ipc.GameObjectRedrawn.Provider( pi, () => Api.GameObjectRedrawn += OnGameObjectRedrawn, () => Api.GameObjectRedrawn -= OnGameObjectRedrawn );
|
||||
RedrawAll = Ipc.RedrawAll.Provider(pi, Api.RedrawAll);
|
||||
RedrawObject = Ipc.RedrawObject.Provider(pi, Api.RedrawObject);
|
||||
RedrawObjectByIndex = Ipc.RedrawObjectByIndex.Provider(pi, Api.RedrawObject);
|
||||
RedrawObjectByName = Ipc.RedrawObjectByName.Provider(pi, Api.RedrawObject);
|
||||
GameObjectRedrawn = Ipc.GameObjectRedrawn.Provider(pi, () => Api.GameObjectRedrawn += OnGameObjectRedrawn,
|
||||
() => Api.GameObjectRedrawn -= OnGameObjectRedrawn);
|
||||
|
||||
// Game State
|
||||
GetDrawObjectInfo = Ipc.GetDrawObjectInfo.Provider( pi, Api.GetDrawObjectInfo );
|
||||
GetCutsceneParentIndex = Ipc.GetCutsceneParentIndex.Provider( pi, Api.GetCutsceneParentIndex );
|
||||
CreatingCharacterBase = Ipc.CreatingCharacterBase.Provider( pi,
|
||||
GetDrawObjectInfo = Ipc.GetDrawObjectInfo.Provider(pi, Api.GetDrawObjectInfo);
|
||||
GetCutsceneParentIndex = Ipc.GetCutsceneParentIndex.Provider(pi, Api.GetCutsceneParentIndex);
|
||||
CreatingCharacterBase = Ipc.CreatingCharacterBase.Provider(pi,
|
||||
() => Api.CreatingCharacterBase += CreatingCharacterBaseEvent,
|
||||
() => Api.CreatingCharacterBase -= CreatingCharacterBaseEvent );
|
||||
CreatedCharacterBase = Ipc.CreatedCharacterBase.Provider( pi,
|
||||
() => Api.CreatingCharacterBase -= CreatingCharacterBaseEvent);
|
||||
CreatedCharacterBase = Ipc.CreatedCharacterBase.Provider(pi,
|
||||
() => Api.CreatedCharacterBase += CreatedCharacterBaseEvent,
|
||||
() => Api.CreatedCharacterBase -= CreatedCharacterBaseEvent );
|
||||
GameObjectResourcePathResolved = Ipc.GameObjectResourcePathResolved.Provider( pi,
|
||||
() => Api.CreatedCharacterBase -= CreatedCharacterBaseEvent);
|
||||
GameObjectResourcePathResolved = Ipc.GameObjectResourcePathResolved.Provider(pi,
|
||||
() => Api.GameObjectResourceResolved += GameObjectResourceResolvedEvent,
|
||||
() => Api.GameObjectResourceResolved -= GameObjectResourceResolvedEvent );
|
||||
() => Api.GameObjectResourceResolved -= GameObjectResourceResolvedEvent);
|
||||
|
||||
// Resolve
|
||||
ResolveDefaultPath = Ipc.ResolveDefaultPath.Provider( pi, Api.ResolveDefaultPath );
|
||||
ResolveInterfacePath = Ipc.ResolveInterfacePath.Provider( pi, Api.ResolveInterfacePath );
|
||||
ResolvePlayerPath = Ipc.ResolvePlayerPath.Provider( pi, Api.ResolvePlayerPath );
|
||||
ResolveGameObjectPath = Ipc.ResolveGameObjectPath.Provider( pi, Api.ResolveGameObjectPath );
|
||||
ResolveCharacterPath = Ipc.ResolveCharacterPath.Provider( pi, Api.ResolvePath );
|
||||
ReverseResolvePath = Ipc.ReverseResolvePath.Provider( pi, Api.ReverseResolvePath );
|
||||
ReverseResolveGameObjectPath = Ipc.ReverseResolveGameObjectPath.Provider( pi, Api.ReverseResolveGameObjectPath );
|
||||
ReverseResolvePlayerPath = Ipc.ReverseResolvePlayerPath.Provider( pi, Api.ReverseResolvePlayerPath );
|
||||
ResolvePlayerPaths = Ipc.ResolvePlayerPaths.Provider( pi, Api.ResolvePlayerPaths );
|
||||
ResolveDefaultPath = Ipc.ResolveDefaultPath.Provider(pi, Api.ResolveDefaultPath);
|
||||
ResolveInterfacePath = Ipc.ResolveInterfacePath.Provider(pi, Api.ResolveInterfacePath);
|
||||
ResolvePlayerPath = Ipc.ResolvePlayerPath.Provider(pi, Api.ResolvePlayerPath);
|
||||
ResolveGameObjectPath = Ipc.ResolveGameObjectPath.Provider(pi, Api.ResolveGameObjectPath);
|
||||
ResolveCharacterPath = Ipc.ResolveCharacterPath.Provider(pi, Api.ResolvePath);
|
||||
ReverseResolvePath = Ipc.ReverseResolvePath.Provider(pi, Api.ReverseResolvePath);
|
||||
ReverseResolveGameObjectPath = Ipc.ReverseResolveGameObjectPath.Provider(pi, Api.ReverseResolveGameObjectPath);
|
||||
ReverseResolvePlayerPath = Ipc.ReverseResolvePlayerPath.Provider(pi, Api.ReverseResolvePlayerPath);
|
||||
ResolvePlayerPaths = Ipc.ResolvePlayerPaths.Provider(pi, Api.ResolvePlayerPaths);
|
||||
|
||||
// Collections
|
||||
GetCollections = Ipc.GetCollections.Provider( pi, Api.GetCollections );
|
||||
GetCurrentCollectionName = Ipc.GetCurrentCollectionName.Provider( pi, Api.GetCurrentCollection );
|
||||
GetDefaultCollectionName = Ipc.GetDefaultCollectionName.Provider( pi, Api.GetDefaultCollection );
|
||||
GetInterfaceCollectionName = Ipc.GetInterfaceCollectionName.Provider( pi, Api.GetInterfaceCollection );
|
||||
GetCharacterCollectionName = Ipc.GetCharacterCollectionName.Provider( pi, Api.GetCharacterCollection );
|
||||
GetCollectionForType = Ipc.GetCollectionForType.Provider( pi, Api.GetCollectionForType );
|
||||
SetCollectionForType = Ipc.SetCollectionForType.Provider( pi, Api.SetCollectionForType );
|
||||
GetCollectionForObject = Ipc.GetCollectionForObject.Provider( pi, Api.GetCollectionForObject );
|
||||
SetCollectionForObject = Ipc.SetCollectionForObject.Provider( pi, Api.SetCollectionForObject );
|
||||
GetChangedItems = Ipc.GetChangedItems.Provider( pi, Api.GetChangedItemsForCollection );
|
||||
GetCollections = Ipc.GetCollections.Provider(pi, Api.GetCollections);
|
||||
GetCurrentCollectionName = Ipc.GetCurrentCollectionName.Provider(pi, Api.GetCurrentCollection);
|
||||
GetDefaultCollectionName = Ipc.GetDefaultCollectionName.Provider(pi, Api.GetDefaultCollection);
|
||||
GetInterfaceCollectionName = Ipc.GetInterfaceCollectionName.Provider(pi, Api.GetInterfaceCollection);
|
||||
GetCharacterCollectionName = Ipc.GetCharacterCollectionName.Provider(pi, Api.GetCharacterCollection);
|
||||
GetCollectionForType = Ipc.GetCollectionForType.Provider(pi, Api.GetCollectionForType);
|
||||
SetCollectionForType = Ipc.SetCollectionForType.Provider(pi, Api.SetCollectionForType);
|
||||
GetCollectionForObject = Ipc.GetCollectionForObject.Provider(pi, Api.GetCollectionForObject);
|
||||
SetCollectionForObject = Ipc.SetCollectionForObject.Provider(pi, Api.SetCollectionForObject);
|
||||
GetChangedItems = Ipc.GetChangedItems.Provider(pi, Api.GetChangedItemsForCollection);
|
||||
|
||||
// Meta
|
||||
GetPlayerMetaManipulations = Ipc.GetPlayerMetaManipulations.Provider( pi, Api.GetPlayerMetaManipulations );
|
||||
GetMetaManipulations = Ipc.GetMetaManipulations.Provider( pi, Api.GetMetaManipulations );
|
||||
GetGameObjectMetaManipulations = Ipc.GetGameObjectMetaManipulations.Provider( pi, Api.GetGameObjectMetaManipulations );
|
||||
GetPlayerMetaManipulations = Ipc.GetPlayerMetaManipulations.Provider(pi, Api.GetPlayerMetaManipulations);
|
||||
GetMetaManipulations = Ipc.GetMetaManipulations.Provider(pi, Api.GetMetaManipulations);
|
||||
GetGameObjectMetaManipulations = Ipc.GetGameObjectMetaManipulations.Provider(pi, Api.GetGameObjectMetaManipulations);
|
||||
|
||||
// Mods
|
||||
GetMods = Ipc.GetMods.Provider( pi, Api.GetModList );
|
||||
ReloadMod = Ipc.ReloadMod.Provider( pi, Api.ReloadMod );
|
||||
AddMod = Ipc.AddMod.Provider( pi, Api.AddMod );
|
||||
DeleteMod = Ipc.DeleteMod.Provider( pi, Api.DeleteMod );
|
||||
GetModPath = Ipc.GetModPath.Provider( pi, Api.GetModPath );
|
||||
SetModPath = Ipc.SetModPath.Provider( pi, Api.SetModPath );
|
||||
ModDeleted = Ipc.ModDeleted.Provider( pi, () => Api.ModDeleted += ModDeletedEvent, () => Api.ModDeleted -= ModDeletedEvent );
|
||||
ModAdded = Ipc.ModAdded.Provider( pi, () => Api.ModAdded += ModAddedEvent, () => Api.ModAdded -= ModAddedEvent );
|
||||
ModMoved = Ipc.ModMoved.Provider( pi, () => Api.ModMoved += ModMovedEvent, () => Api.ModMoved -= ModMovedEvent );
|
||||
GetMods = Ipc.GetMods.Provider(pi, Api.GetModList);
|
||||
ReloadMod = Ipc.ReloadMod.Provider(pi, Api.ReloadMod);
|
||||
InstallMod = Ipc.InstallMod.Provider(pi, Api.InstallMod);
|
||||
AddMod = Ipc.AddMod.Provider(pi, Api.AddMod);
|
||||
DeleteMod = Ipc.DeleteMod.Provider(pi, Api.DeleteMod);
|
||||
GetModPath = Ipc.GetModPath.Provider(pi, Api.GetModPath);
|
||||
SetModPath = Ipc.SetModPath.Provider(pi, Api.SetModPath);
|
||||
ModDeleted = Ipc.ModDeleted.Provider(pi, () => Api.ModDeleted += ModDeletedEvent, () => Api.ModDeleted -= ModDeletedEvent);
|
||||
ModAdded = Ipc.ModAdded.Provider(pi, () => Api.ModAdded += ModAddedEvent, () => Api.ModAdded -= ModAddedEvent);
|
||||
ModMoved = Ipc.ModMoved.Provider(pi, () => Api.ModMoved += ModMovedEvent, () => Api.ModMoved -= ModMovedEvent);
|
||||
|
||||
// ModSettings
|
||||
GetAvailableModSettings = Ipc.GetAvailableModSettings.Provider( pi, Api.GetAvailableModSettings );
|
||||
GetCurrentModSettings = Ipc.GetCurrentModSettings.Provider( pi, Api.GetCurrentModSettings );
|
||||
TryInheritMod = Ipc.TryInheritMod.Provider( pi, Api.TryInheritMod );
|
||||
TrySetMod = Ipc.TrySetMod.Provider( pi, Api.TrySetMod );
|
||||
TrySetModPriority = Ipc.TrySetModPriority.Provider( pi, Api.TrySetModPriority );
|
||||
TrySetModSetting = Ipc.TrySetModSetting.Provider( pi, Api.TrySetModSetting );
|
||||
TrySetModSettings = Ipc.TrySetModSettings.Provider( pi, Api.TrySetModSettings );
|
||||
ModSettingChanged = Ipc.ModSettingChanged.Provider( pi,
|
||||
GetAvailableModSettings = Ipc.GetAvailableModSettings.Provider(pi, Api.GetAvailableModSettings);
|
||||
GetCurrentModSettings = Ipc.GetCurrentModSettings.Provider(pi, Api.GetCurrentModSettings);
|
||||
TryInheritMod = Ipc.TryInheritMod.Provider(pi, Api.TryInheritMod);
|
||||
TrySetMod = Ipc.TrySetMod.Provider(pi, Api.TrySetMod);
|
||||
TrySetModPriority = Ipc.TrySetModPriority.Provider(pi, Api.TrySetModPriority);
|
||||
TrySetModSetting = Ipc.TrySetModSetting.Provider(pi, Api.TrySetModSetting);
|
||||
TrySetModSettings = Ipc.TrySetModSettings.Provider(pi, Api.TrySetModSettings);
|
||||
ModSettingChanged = Ipc.ModSettingChanged.Provider(pi,
|
||||
() => Api.ModSettingChanged += ModSettingChangedEvent,
|
||||
() => Api.ModSettingChanged -= ModSettingChangedEvent );
|
||||
CopyModSettings = Ipc.CopyModSettings.Provider( pi, Api.CopyModSettings );
|
||||
() => Api.ModSettingChanged -= ModSettingChangedEvent);
|
||||
CopyModSettings = Ipc.CopyModSettings.Provider(pi, Api.CopyModSettings);
|
||||
|
||||
// Temporary
|
||||
CreateTemporaryCollection = Ipc.CreateTemporaryCollection.Provider( pi, Api.CreateTemporaryCollection );
|
||||
RemoveTemporaryCollection = Ipc.RemoveTemporaryCollection.Provider( pi, Api.RemoveTemporaryCollection );
|
||||
CreateNamedTemporaryCollection = Ipc.CreateNamedTemporaryCollection.Provider( pi, Api.CreateNamedTemporaryCollection );
|
||||
RemoveTemporaryCollectionByName = Ipc.RemoveTemporaryCollectionByName.Provider( pi, Api.RemoveTemporaryCollectionByName );
|
||||
AssignTemporaryCollection = Ipc.AssignTemporaryCollection.Provider( pi, Api.AssignTemporaryCollection );
|
||||
AddTemporaryModAll = Ipc.AddTemporaryModAll.Provider( pi, Api.AddTemporaryModAll );
|
||||
AddTemporaryMod = Ipc.AddTemporaryMod.Provider( pi, Api.AddTemporaryMod );
|
||||
RemoveTemporaryModAll = Ipc.RemoveTemporaryModAll.Provider( pi, Api.RemoveTemporaryModAll );
|
||||
RemoveTemporaryMod = Ipc.RemoveTemporaryMod.Provider( pi, Api.RemoveTemporaryMod );
|
||||
CreateTemporaryCollection = Ipc.CreateTemporaryCollection.Provider(pi, Api.CreateTemporaryCollection);
|
||||
RemoveTemporaryCollection = Ipc.RemoveTemporaryCollection.Provider(pi, Api.RemoveTemporaryCollection);
|
||||
CreateNamedTemporaryCollection = Ipc.CreateNamedTemporaryCollection.Provider(pi, Api.CreateNamedTemporaryCollection);
|
||||
RemoveTemporaryCollectionByName = Ipc.RemoveTemporaryCollectionByName.Provider(pi, Api.RemoveTemporaryCollectionByName);
|
||||
AssignTemporaryCollection = Ipc.AssignTemporaryCollection.Provider(pi, Api.AssignTemporaryCollection);
|
||||
AddTemporaryModAll = Ipc.AddTemporaryModAll.Provider(pi, Api.AddTemporaryModAll);
|
||||
AddTemporaryMod = Ipc.AddTemporaryMod.Provider(pi, Api.AddTemporaryMod);
|
||||
RemoveTemporaryModAll = Ipc.RemoveTemporaryModAll.Provider(pi, Api.RemoveTemporaryModAll);
|
||||
RemoveTemporaryMod = Ipc.RemoveTemporaryMod.Provider(pi, Api.RemoveTemporaryMod);
|
||||
|
||||
Tester = new IpcTester( pi, this, modManager );
|
||||
Tester = new IpcTester(pi, this, modManager);
|
||||
|
||||
Initialized.Invoke();
|
||||
}
|
||||
|
|
@ -295,6 +300,7 @@ public class PenumbraIpcProviders : IDisposable
|
|||
// Mods
|
||||
GetMods.Dispose();
|
||||
ReloadMod.Dispose();
|
||||
InstallMod.Dispose();
|
||||
AddMod.Dispose();
|
||||
DeleteMod.Dispose();
|
||||
GetModPath.Dispose();
|
||||
|
|
@ -332,46 +338,46 @@ public class PenumbraIpcProviders : IDisposable
|
|||
// Wrappers
|
||||
private int DeprecatedVersion()
|
||||
{
|
||||
Penumbra.Log.Warning( $"{Ipc.ApiVersion.Label} is outdated. Please use {Ipc.ApiVersions.Label} instead." );
|
||||
Penumbra.Log.Warning($"{Ipc.ApiVersion.Label} is outdated. Please use {Ipc.ApiVersions.Label} instead.");
|
||||
return Api.ApiVersion.Breaking;
|
||||
}
|
||||
|
||||
private void OnClick( MouseButton click, object? item )
|
||||
private void OnClick(MouseButton click, object? item)
|
||||
{
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId( item );
|
||||
ChangedItemClick.Invoke( click, type, id );
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId(item);
|
||||
ChangedItemClick.Invoke(click, type, id);
|
||||
}
|
||||
|
||||
private void OnTooltip( object? item )
|
||||
private void OnTooltip(object? item)
|
||||
{
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId( item );
|
||||
ChangedItemTooltip.Invoke( type, id );
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId(item);
|
||||
ChangedItemTooltip.Invoke(type, id);
|
||||
}
|
||||
|
||||
private void EnabledChangeEvent( bool value )
|
||||
=> EnabledChange.Invoke( value );
|
||||
private void EnabledChangeEvent(bool value)
|
||||
=> EnabledChange.Invoke(value);
|
||||
|
||||
private void OnGameObjectRedrawn( IntPtr objectAddress, int objectTableIndex )
|
||||
=> GameObjectRedrawn.Invoke( objectAddress, objectTableIndex );
|
||||
private void OnGameObjectRedrawn(IntPtr objectAddress, int objectTableIndex)
|
||||
=> GameObjectRedrawn.Invoke(objectAddress, objectTableIndex);
|
||||
|
||||
private void CreatingCharacterBaseEvent( IntPtr gameObject, string collectionName, IntPtr modelId, IntPtr customize, IntPtr equipData )
|
||||
=> CreatingCharacterBase.Invoke( gameObject, collectionName, modelId, customize, equipData );
|
||||
private void CreatingCharacterBaseEvent(IntPtr gameObject, string collectionName, IntPtr modelId, IntPtr customize, IntPtr equipData)
|
||||
=> CreatingCharacterBase.Invoke(gameObject, collectionName, modelId, customize, equipData);
|
||||
|
||||
private void CreatedCharacterBaseEvent( IntPtr gameObject, string collectionName, IntPtr drawObject )
|
||||
=> CreatedCharacterBase.Invoke( gameObject, collectionName, drawObject );
|
||||
private void CreatedCharacterBaseEvent(IntPtr gameObject, string collectionName, IntPtr drawObject)
|
||||
=> CreatedCharacterBase.Invoke(gameObject, collectionName, drawObject);
|
||||
|
||||
private void GameObjectResourceResolvedEvent( IntPtr gameObject, string gamePath, string localPath )
|
||||
=> GameObjectResourcePathResolved.Invoke( gameObject, gamePath, localPath );
|
||||
private void GameObjectResourceResolvedEvent(IntPtr gameObject, string gamePath, string localPath)
|
||||
=> GameObjectResourcePathResolved.Invoke(gameObject, gamePath, localPath);
|
||||
|
||||
private void ModSettingChangedEvent( ModSettingChange type, string collection, string mod, bool inherited )
|
||||
=> ModSettingChanged.Invoke( type, collection, mod, inherited );
|
||||
private void ModSettingChangedEvent(ModSettingChange type, string collection, string mod, bool inherited)
|
||||
=> ModSettingChanged.Invoke(type, collection, mod, inherited);
|
||||
|
||||
private void ModDeletedEvent( string name )
|
||||
=> ModDeleted.Invoke( name );
|
||||
private void ModDeletedEvent(string name)
|
||||
=> ModDeleted.Invoke(name);
|
||||
|
||||
private void ModAddedEvent( string name )
|
||||
=> ModAdded.Invoke( name );
|
||||
private void ModAddedEvent(string name)
|
||||
=> ModAdded.Invoke(name);
|
||||
|
||||
private void ModMovedEvent( string from, string to )
|
||||
=> ModMoved.Invoke( from, to );
|
||||
}
|
||||
private void ModMovedEvent(string from, string to)
|
||||
=> ModMoved.Invoke(from, to);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ public partial class TexToolsImporter : IDisposable
|
|||
private readonly ModEditor _editor;
|
||||
private readonly ModManager _modManager;
|
||||
|
||||
public TexToolsImporter( DirectoryInfo baseDirectory, int count, IEnumerable< FileInfo > modPackFiles,
|
||||
public TexToolsImporter( int count, IEnumerable< FileInfo > modPackFiles,
|
||||
Action< FileInfo, DirectoryInfo?, Exception? > handler, Configuration config, ModEditor editor, ModManager modManager)
|
||||
{
|
||||
_baseDirectory = baseDirectory;
|
||||
_baseDirectory = modManager.BasePath;
|
||||
_tmpFile = Path.Combine( _baseDirectory.FullName, TempFileName );
|
||||
_modPackFiles = modPackFiles;
|
||||
_config = config;
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ public class ModBackup
|
|||
public readonly string Name;
|
||||
public readonly bool Exists;
|
||||
|
||||
public ModBackup(ExportManager exportManager, Mod mod)
|
||||
public ModBackup(ModExportManager modExportManager, Mod mod)
|
||||
{
|
||||
_mod = mod;
|
||||
Name = Path.Combine(exportManager.ExportDirectory.FullName, _mod.ModPath.Name) + ".pmp";
|
||||
Name = Path.Combine(modExportManager.ExportDirectory.FullName, _mod.ModPath.Name) + ".pmp";
|
||||
Exists = File.Exists(Name);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Penumbra.Services;
|
|||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
||||
public class ExportManager : IDisposable
|
||||
public class ModExportManager : IDisposable
|
||||
{
|
||||
private readonly Configuration _config;
|
||||
private readonly CommunicatorService _communicator;
|
||||
|
|
@ -15,7 +15,7 @@ public class ExportManager : IDisposable
|
|||
public DirectoryInfo ExportDirectory
|
||||
=> _exportDirectory ?? _modManager.BasePath;
|
||||
|
||||
public ExportManager(Configuration config, CommunicatorService communicator, ModManager modManager)
|
||||
public ModExportManager(Configuration config, CommunicatorService communicator, ModManager modManager)
|
||||
{
|
||||
_config = config;
|
||||
_communicator = communicator;
|
||||
|
|
@ -89,4 +89,4 @@ public class ExportManager : IDisposable
|
|||
new ModBackup(this, mod).Move(null, newDirectory.Name);
|
||||
mod.ModPath = newDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
123
Penumbra/Mods/Manager/ModImportManager.cs
Normal file
123
Penumbra/Mods/Manager/ModImportManager.cs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Penumbra.Import;
|
||||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
||||
public class ModImportManager : IDisposable
|
||||
{
|
||||
private readonly ModManager _modManager;
|
||||
private readonly Configuration _config;
|
||||
private readonly ModEditor _modEditor;
|
||||
|
||||
private readonly ConcurrentQueue<string[]> _modsToUnpack = new();
|
||||
|
||||
/// <summary> Mods need to be added thread-safely outside of iteration. </summary>
|
||||
private readonly ConcurrentQueue<DirectoryInfo> _modsToAdd = new();
|
||||
|
||||
private TexToolsImporter? _import;
|
||||
|
||||
public ModImportManager(ModManager modManager, Configuration config, ModEditor modEditor)
|
||||
{
|
||||
_modManager = modManager;
|
||||
_config = config;
|
||||
_modEditor = modEditor;
|
||||
}
|
||||
|
||||
public void TryUnpacking()
|
||||
{
|
||||
if (Importing || !_modsToUnpack.TryDequeue(out var newMods))
|
||||
return;
|
||||
|
||||
var files = newMods.Where(s =>
|
||||
{
|
||||
if (File.Exists(s))
|
||||
return true;
|
||||
|
||||
Penumbra.ChatService.NotificationMessage($"Failed to import queued mod at {s}, the file does not exist.", "Warning",
|
||||
NotificationType.Warning);
|
||||
return false;
|
||||
|
||||
}).Select(s => new FileInfo(s)).ToArray();
|
||||
|
||||
if (files.Length == 0)
|
||||
return;
|
||||
|
||||
_import = new TexToolsImporter(files.Length, files, AddNewMod, _config, _modEditor, _modManager);
|
||||
}
|
||||
|
||||
public bool Importing
|
||||
=> _import != null;
|
||||
|
||||
public bool IsImporting([NotNullWhen(true)] out TexToolsImporter? importer)
|
||||
{
|
||||
importer = _import;
|
||||
return _import != null;
|
||||
}
|
||||
|
||||
public void AddUnpack(IEnumerable<string> paths)
|
||||
=> _modsToUnpack.Enqueue(paths.ToArray());
|
||||
|
||||
public void AddUnpack(params string[] paths)
|
||||
=> _modsToUnpack.Enqueue(paths);
|
||||
|
||||
public void ClearImport()
|
||||
{
|
||||
_import?.Dispose();
|
||||
_import = null;
|
||||
}
|
||||
|
||||
|
||||
public bool AddUnpackedMod([NotNullWhen(true)] out Mod? mod)
|
||||
{
|
||||
if (!_modsToAdd.TryDequeue(out var directory))
|
||||
{
|
||||
mod = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
_modManager.AddMod(directory);
|
||||
mod = _modManager.LastOrDefault();
|
||||
return mod != null && mod.ModPath == directory;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ClearImport();
|
||||
_modsToAdd.Clear();
|
||||
_modsToUnpack.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up invalid directory if necessary.
|
||||
/// Add successfully extracted mods.
|
||||
/// </summary>
|
||||
private void AddNewMod(FileInfo file, DirectoryInfo? dir, Exception? error)
|
||||
{
|
||||
if (error != null)
|
||||
{
|
||||
if (dir != null && Directory.Exists(dir.FullName))
|
||||
try
|
||||
{
|
||||
Directory.Delete(dir.FullName, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Error cleaning up failed mod extraction of {file.FullName} to {dir.FullName}:\n{e}");
|
||||
}
|
||||
|
||||
if (error is not OperationCanceledException)
|
||||
Penumbra.Log.Error($"Error extracting {file.FullName}, mod skipped:\n{error}");
|
||||
}
|
||||
else if (dir != null)
|
||||
{
|
||||
_modsToAdd.Enqueue(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,8 +21,8 @@ using Penumbra.UI.Tabs;
|
|||
using Penumbra.Util;
|
||||
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
|
||||
using ModFileSystemSelector = Penumbra.UI.ModsTab.ModFileSystemSelector;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
||||
using Penumbra.Mods.Manager;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
public class PenumbraNew
|
||||
|
|
@ -61,7 +61,7 @@ public class PenumbraNew
|
|||
.AddSingleton<StainService>()
|
||||
.AddSingleton<ItemService>()
|
||||
.AddSingleton<ActorService>();
|
||||
|
||||
|
||||
// Add Game Services
|
||||
services.AddSingleton<GameEventManager>()
|
||||
.AddSingleton<FrameworkManager>()
|
||||
|
|
@ -75,8 +75,8 @@ public class PenumbraNew
|
|||
.AddSingleton<CreateFileWHook>()
|
||||
.AddSingleton<ResidentResourceManager>()
|
||||
.AddSingleton<FontReloader>()
|
||||
.AddSingleton<RedrawService>();
|
||||
|
||||
.AddSingleton<RedrawService>();
|
||||
|
||||
// Add PathResolver
|
||||
services.AddSingleton<CutsceneService>()
|
||||
.AddSingleton<IdentifiedCollectionCache>();
|
||||
|
|
@ -98,7 +98,8 @@ public class PenumbraNew
|
|||
.AddSingleton<ModDataEditor>()
|
||||
.AddSingleton<ModOptionEditor>()
|
||||
.AddSingleton<ModManager>()
|
||||
.AddSingleton<ExportManager>()
|
||||
.AddSingleton<ModExportManager>()
|
||||
.AddSingleton<ModImportManager>()
|
||||
.AddSingleton<ModFileSystem>()
|
||||
.AddSingleton<ModCacheManager>();
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ public class PenumbraNew
|
|||
services.AddSingleton<ResourceLoader>()
|
||||
.AddSingleton<ResourceWatcher>()
|
||||
.AddSingleton<ResourceTreeFactory>();
|
||||
|
||||
|
||||
// Add Path Resolver
|
||||
services.AddSingleton<AnimationHookService>()
|
||||
.AddSingleton<CollectionResolver>()
|
||||
|
|
@ -116,7 +117,7 @@ public class PenumbraNew
|
|||
.AddSingleton<PathState>()
|
||||
.AddSingleton<SubfileHelper>()
|
||||
.AddSingleton<IdentifiedCollectionCache>()
|
||||
.AddSingleton<PathResolver>();
|
||||
.AddSingleton<PathResolver>();
|
||||
|
||||
// Add Interface
|
||||
services.AddSingleton<FileDialogService>()
|
||||
|
|
@ -131,6 +132,7 @@ public class PenumbraNew
|
|||
.AddSingleton<ModsTab>()
|
||||
.AddSingleton<ModPanel>()
|
||||
.AddSingleton<ModFileSystemSelector>()
|
||||
.AddSingleton<ImportPopup>()
|
||||
.AddSingleton<ModPanelDescriptionTab>()
|
||||
.AddSingleton<ModPanelSettingsTab>()
|
||||
.AddSingleton<ModPanelEditTab>()
|
||||
|
|
@ -147,7 +149,7 @@ public class PenumbraNew
|
|||
.AddSingleton<ConfigTabBar>()
|
||||
.AddSingleton<ResourceWatcher>()
|
||||
.AddSingleton<ItemSwapTab>();
|
||||
|
||||
|
||||
// Add Mod Editor
|
||||
services.AddSingleton<ModFileCollection>()
|
||||
.AddSingleton<DuplicateManager>()
|
||||
|
|
@ -156,7 +158,7 @@ public class PenumbraNew
|
|||
.AddSingleton<ModMetaEditor>()
|
||||
.AddSingleton<ModSwapEditor>()
|
||||
.AddSingleton<ModNormalizer>()
|
||||
.AddSingleton<ModEditor>();
|
||||
.AddSingleton<ModEditor>();
|
||||
|
||||
// Add API
|
||||
services.AddSingleton<PenumbraApi>()
|
||||
|
|
|
|||
64
Penumbra/UI/ImportPopup.cs
Normal file
64
Penumbra/UI/ImportPopup.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Import.Structs;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
/// <summary> Draw the progress information for import. </summary>
|
||||
public sealed class ImportPopup : Window
|
||||
{
|
||||
private readonly ModImportManager _modImportManager;
|
||||
|
||||
public ImportPopup(ModImportManager modImportManager)
|
||||
: base("Penumbra Import Status",
|
||||
ImGuiWindowFlags.Modal
|
||||
| ImGuiWindowFlags.Popup
|
||||
| ImGuiWindowFlags.NoCollapse
|
||||
| ImGuiWindowFlags.NoDecoration
|
||||
| ImGuiWindowFlags.NoBackground
|
||||
| ImGuiWindowFlags.NoMove
|
||||
| ImGuiWindowFlags.NoInputs
|
||||
| ImGuiWindowFlags.NoFocusOnAppearing
|
||||
| ImGuiWindowFlags.NoBringToFrontOnFocus, true)
|
||||
{
|
||||
_modImportManager = modImportManager;
|
||||
IsOpen = true;
|
||||
SizeConstraints = new WindowSizeConstraints
|
||||
{
|
||||
MinimumSize = Vector2.Zero,
|
||||
MaximumSize = Vector2.Zero,
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
_modImportManager.TryUnpacking();
|
||||
if (!_modImportManager.IsImporting(out var import))
|
||||
return;
|
||||
|
||||
ImGui.OpenPopup("##importPopup");
|
||||
|
||||
var display = ImGui.GetIO().DisplaySize;
|
||||
var height = Math.Max(display.Y / 4, 15 * ImGui.GetFrameHeightWithSpacing());
|
||||
var width = display.X / 8;
|
||||
var size = new Vector2(width * 2, height);
|
||||
ImGui.SetNextWindowPos(ImGui.GetMainViewport().GetCenter(), ImGuiCond.Always, Vector2.One / 2);
|
||||
ImGui.SetNextWindowSize(size);
|
||||
using var popup = ImRaii.Popup("##importPopup", ImGuiWindowFlags.Modal);
|
||||
using (var child = ImRaii.Child("##import", new Vector2(-1, size.Y - ImGui.GetFrameHeight() * 2)))
|
||||
{
|
||||
if (child)
|
||||
import.DrawProgressInfo(new Vector2(-1, ImGui.GetFrameHeight()));
|
||||
}
|
||||
|
||||
if ((import.State != ImporterState.Done || !ImGui.Button("Close", -Vector2.UnitX))
|
||||
&& (import.State == ImporterState.Done || !import.DrawCancelButton(-Vector2.UnitX)))
|
||||
return;
|
||||
|
||||
_modImportManager.ClearImport();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
|
@ -13,12 +10,9 @@ using OtterGui.Classes;
|
|||
using OtterGui.Filesystem;
|
||||
using OtterGui.FileSystem.Selector;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Import;
|
||||
using Penumbra.Import.Structs;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -27,7 +21,7 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSystemSelector.ModState>
|
||||
public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSystemSelector.ModState>
|
||||
{
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly ChatService _chat;
|
||||
|
|
@ -37,18 +31,13 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
private readonly ModCacheManager _modCaches;
|
||||
private readonly CollectionManager _collectionManager;
|
||||
private readonly TutorialService _tutorial;
|
||||
private readonly ModEditor _modEditor;
|
||||
private Queue<string> _modUnpackQueue = new Queue<string>();
|
||||
|
||||
private TexToolsImporter? _import;
|
||||
public ModSettings SelectedSettings { get; private set; } = ModSettings.Empty;
|
||||
public ModCollection SelectedSettingCollection { get; private set; } = ModCollection.Empty;
|
||||
|
||||
private uint _infoPopupId = 0;
|
||||
private readonly ModImportManager _modImportManager;
|
||||
public ModSettings SelectedSettings { get; private set; } = ModSettings.Empty;
|
||||
public ModCollection SelectedSettingCollection { get; private set; } = ModCollection.Empty;
|
||||
|
||||
public ModFileSystemSelector(CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager,
|
||||
CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat,
|
||||
ModEditor modEditor, ModCacheManager modCaches)
|
||||
ModCacheManager modCaches, ModImportManager modImportManager)
|
||||
: base(fileSystem, DalamudServices.KeyState, HandleException)
|
||||
{
|
||||
_communicator = communicator;
|
||||
|
|
@ -58,8 +47,8 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
_tutorial = tutorial;
|
||||
_fileDialog = fileDialog;
|
||||
_chat = chat;
|
||||
_modEditor = modEditor;
|
||||
_modCaches = modCaches;
|
||||
_modImportManager = modImportManager;
|
||||
|
||||
// @formatter:off
|
||||
SubscribeRightClickFolder(EnableDescendants, 10);
|
||||
|
|
@ -85,13 +74,12 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
|
||||
SelectionChanged += OnSelectionChange;
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_collectionManager.Active.Current.ModSettingChanged += OnSettingChange;
|
||||
_collectionManager.Active.Current.ModSettingChanged += OnSettingChange;
|
||||
_collectionManager.Active.Current.InheritanceChanged += OnInheritanceChange;
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(StoreCurrentSelection);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(RestoreLastSelection);
|
||||
OnCollectionChange(CollectionType.Current, null, _collectionManager.Active.Current, "");
|
||||
ExternalModImporter.ModFileSystemSelectorInstance = this;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
|
|
@ -100,11 +88,9 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
_communicator.ModDiscoveryStarted.Unsubscribe(StoreCurrentSelection);
|
||||
_communicator.ModDiscoveryFinished.Unsubscribe(RestoreLastSelection);
|
||||
_communicator.ModDataChanged.Unsubscribe(OnModDataChange);
|
||||
_collectionManager.Active.Current.ModSettingChanged -= OnSettingChange;
|
||||
_collectionManager.Active.Current.ModSettingChanged -= OnSettingChange;
|
||||
_collectionManager.Active.Current.InheritanceChanged -= OnInheritanceChange;
|
||||
_communicator.CollectionChange.Unsubscribe(OnCollectionChange);
|
||||
_import?.Dispose();
|
||||
_import = null;
|
||||
}
|
||||
|
||||
public new ModFileSystem.Leaf? SelectedLeaf
|
||||
|
|
@ -131,7 +117,6 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
protected override void DrawPopups()
|
||||
{
|
||||
DrawHelpPopup();
|
||||
DrawInfoPopup();
|
||||
|
||||
if (ImGuiUtil.OpenNameField("Create New Mod", ref _newModName))
|
||||
try
|
||||
|
|
@ -147,13 +132,8 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
Penumbra.Log.Error($"Could not create directory for new Mod {_newModName}:\n{e}");
|
||||
}
|
||||
|
||||
while (_modsToAdd.TryDequeue(out var dir))
|
||||
while (_modImportManager.AddUnpackedMod(out var mod))
|
||||
{
|
||||
_modManager.AddMod(dir);
|
||||
var mod = _modManager.LastOrDefault();
|
||||
if (mod == null)
|
||||
continue;
|
||||
|
||||
MoveModToDefaultDirectory(mod);
|
||||
SelectByValue(mod);
|
||||
}
|
||||
|
|
@ -234,8 +214,6 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
/// <summary> Add an import mods button that opens a file selector. </summary>
|
||||
private void AddImportModButton(Vector2 size)
|
||||
{
|
||||
_infoPopupId = ImGui.GetID("Import Status");
|
||||
ExternalImportListener();
|
||||
var button = ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.FileImport.ToIconString(), size,
|
||||
"Import one or multiple mods from Tex Tools Mod Pack Files or Penumbra Mod Pack Files.", !Penumbra.ModManager.Valid, true);
|
||||
_tutorial.OpenTutorial(BasicTutorialSteps.ModImport);
|
||||
|
|
@ -251,105 +229,11 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
{
|
||||
if (!s)
|
||||
return;
|
||||
_modsCurrentlyUnpacking = true;
|
||||
_import = new TexToolsImporter(_modManager.BasePath, f.Count, f.Select(file => new FileInfo(file)),
|
||||
AddNewMod, _config, _modEditor, _modManager);
|
||||
ImGui.OpenPopup(_infoPopupId);
|
||||
|
||||
_modImportManager.AddUnpack(f);
|
||||
}, 0, modPath, _config.AlwaysOpenDefaultImport);
|
||||
}
|
||||
|
||||
private void ExternalImportListener()
|
||||
{
|
||||
if (_modUnpackQueue.Count > 0)
|
||||
{
|
||||
// Attempt to avoid triggering if other mods are already unpacking
|
||||
if (!_modsCurrentlyUnpacking)
|
||||
{
|
||||
string modPackagePath = _modUnpackQueue.Dequeue();
|
||||
if (File.Exists(modPackagePath))
|
||||
{
|
||||
_modsCurrentlyUnpacking = true;
|
||||
var modPath = !_config.AlwaysOpenDefaultImport ? null
|
||||
: _config.DefaultModImportPath.Length > 0 ? _config.DefaultModImportPath
|
||||
: _config.ModDirectory.Length > 0 ? _config.ModDirectory : null;
|
||||
|
||||
_import = new TexToolsImporter(Penumbra.ModManager.BasePath, 1, new List<FileInfo>() { new FileInfo(modPackagePath) }, AddNewMod,
|
||||
_config, _modEditor, _modManager);
|
||||
ImGui.OpenPopup(_infoPopupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the specified standalone package
|
||||
/// </summary>
|
||||
/// <param name="modPackagePath">The package to unpack</param>
|
||||
public void ImportStandaloneModPackage(string modPackagePath)
|
||||
{
|
||||
_modUnpackQueue.Enqueue(modPackagePath);
|
||||
}
|
||||
|
||||
/// <summary> Draw the progress information for import. </summary>
|
||||
private void DrawInfoPopup()
|
||||
{
|
||||
var display = ImGui.GetIO().DisplaySize;
|
||||
var height = Math.Max(display.Y / 4, 15 * ImGui.GetFrameHeightWithSpacing());
|
||||
var width = display.X / 8;
|
||||
var size = new Vector2(width * 2, height);
|
||||
ImGui.SetNextWindowPos(ImGui.GetMainViewport().GetCenter(), ImGuiCond.Always, Vector2.One / 2);
|
||||
ImGui.SetNextWindowSize(size);
|
||||
var infoPopupId = ImGui.GetID("Import Status");
|
||||
using var popup = ImRaii.Popup("Import Status", ImGuiWindowFlags.Modal);
|
||||
if (_import == null || !popup.Success)
|
||||
return;
|
||||
|
||||
using (var child = ImRaii.Child("##import", new Vector2(-1, size.Y - ImGui.GetFrameHeight() * 2)))
|
||||
{
|
||||
if (child)
|
||||
_import.DrawProgressInfo(new Vector2(-1, ImGui.GetFrameHeight()));
|
||||
}
|
||||
|
||||
if ((_import.State != ImporterState.Done || !ImGui.Button("Close", -Vector2.UnitX))
|
||||
&& (_import.State == ImporterState.Done || !_import.DrawCancelButton(-Vector2.UnitX)))
|
||||
return;
|
||||
|
||||
_import?.Dispose();
|
||||
_import = null;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
/// <summary> Mods need to be added thread-safely outside of iteration. </summary>
|
||||
private readonly ConcurrentQueue<DirectoryInfo> _modsToAdd = new();
|
||||
|
||||
/// <summary>
|
||||
/// Clean up invalid directory if necessary.
|
||||
/// Add successfully extracted mods.
|
||||
/// </summary>
|
||||
private void AddNewMod(FileInfo file, DirectoryInfo? dir, Exception? error)
|
||||
{
|
||||
if (error != null)
|
||||
{
|
||||
if (dir != null && Directory.Exists(dir.FullName))
|
||||
try
|
||||
{
|
||||
Directory.Delete(dir.FullName, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Error cleaning up failed mod extraction of {file.FullName} to {dir.FullName}:\n{e}");
|
||||
}
|
||||
|
||||
if (error is not OperationCanceledException)
|
||||
Penumbra.Log.Error($"Error extracting {file.FullName}, mod skipped:\n{error}");
|
||||
}
|
||||
else if (dir != null)
|
||||
{
|
||||
_modsToAdd.Enqueue(dir);
|
||||
}
|
||||
_modsCurrentlyUnpacking = false;
|
||||
}
|
||||
|
||||
private void DeleteModButton(Vector2 size)
|
||||
{
|
||||
var keys = _config.DeleteModModifier.IsActive();
|
||||
|
|
@ -573,7 +457,6 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
|
|||
private LowerString _modFilter = LowerString.Empty;
|
||||
private int _filterType = -1;
|
||||
private ModFilter _stateFilter = ModFilterExtensions.UnfilteredStateMods;
|
||||
private bool _modsCurrentlyUnpacking;
|
||||
|
||||
private void SetFilterTooltip()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public class ModPanelEditTab : ITab
|
|||
private readonly ChatService _chat;
|
||||
private readonly FilenameService _filenames;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly ExportManager _exportManager;
|
||||
private readonly ModExportManager _modExportManager;
|
||||
private readonly ModFileSystem _fileSystem;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly ModEditWindow _editWindow;
|
||||
|
|
@ -38,16 +38,16 @@ public class ModPanelEditTab : ITab
|
|||
private Mod _mod = null!;
|
||||
|
||||
public ModPanelEditTab(ModManager modManager, ModFileSystemSelector selector, ModFileSystem fileSystem, ChatService chat,
|
||||
ModEditWindow editWindow, ModEditor editor, FilenameService filenames, ExportManager exportManager)
|
||||
ModEditWindow editWindow, ModEditor editor, FilenameService filenames, ModExportManager modExportManager)
|
||||
{
|
||||
_modManager = modManager;
|
||||
_selector = selector;
|
||||
_fileSystem = fileSystem;
|
||||
_chat = chat;
|
||||
_editWindow = editWindow;
|
||||
_editor = editor;
|
||||
_filenames = filenames;
|
||||
_exportManager = exportManager;
|
||||
_modManager = modManager;
|
||||
_selector = selector;
|
||||
_fileSystem = fileSystem;
|
||||
_chat = chat;
|
||||
_editWindow = editWindow;
|
||||
_editor = editor;
|
||||
_filenames = filenames;
|
||||
_modExportManager = modExportManager;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
|
|
@ -150,7 +150,7 @@ public class ModPanelEditTab : ITab
|
|||
|
||||
private void BackupButtons(Vector2 buttonSize)
|
||||
{
|
||||
var backup = new ModBackup(_exportManager, _mod);
|
||||
var backup = new ModBackup(_modExportManager, _mod);
|
||||
var tt = ModBackup.CreatingBackup
|
||||
? "Already exporting a mod."
|
||||
: backup.Exists
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class SettingsTab : ITab
|
|||
private readonly Penumbra _penumbra;
|
||||
private readonly FileDialogService _fileDialog;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly ExportManager _exportManager;
|
||||
private readonly ModExportManager _modExportManager;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly CharacterUtility _characterUtility;
|
||||
private readonly ResidentResourceManager _residentResources;
|
||||
|
|
@ -40,7 +40,7 @@ public class SettingsTab : ITab
|
|||
|
||||
public SettingsTab(Configuration config, FontReloader fontReloader, TutorialService tutorial, Penumbra penumbra,
|
||||
FileDialogService fileDialog, ModManager modManager, ModFileSystemSelector selector, CharacterUtility characterUtility,
|
||||
ResidentResourceManager residentResources, DalamudServices dalamud, ExportManager exportManager)
|
||||
ResidentResourceManager residentResources, DalamudServices dalamud, ModExportManager modExportManager)
|
||||
{
|
||||
_config = config;
|
||||
_fontReloader = fontReloader;
|
||||
|
|
@ -52,7 +52,7 @@ public class SettingsTab : ITab
|
|||
_characterUtility = characterUtility;
|
||||
_residentResources = residentResources;
|
||||
_dalamud = dalamud;
|
||||
_exportManager = exportManager;
|
||||
_modExportManager = modExportManager;
|
||||
}
|
||||
|
||||
public void DrawHeader()
|
||||
|
|
@ -116,7 +116,7 @@ public class SettingsTab : ITab
|
|||
|
||||
/// <summary> Check a potential new root directory for validity and return the button text and whether it is valid. </summary>
|
||||
private static (string Text, bool Valid) CheckRootDirectoryPath(string newName, string old, bool selected)
|
||||
{
|
||||
{
|
||||
static bool IsSubPathOf(string basePath, string subPath)
|
||||
{
|
||||
if (basePath.Length == 0)
|
||||
|
|
@ -555,7 +555,7 @@ public class SettingsTab : ITab
|
|||
_tempExportDirectory = tmp;
|
||||
|
||||
if (ImGui.IsItemDeactivatedAfterEdit())
|
||||
_exportManager.UpdateExportDirectory(_tempExportDirectory);
|
||||
_modExportManager.UpdateExportDirectory(_tempExportDirectory);
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Folder.ToIconString()}##export", UiHelpers.IconButtonSize,
|
||||
|
|
@ -569,7 +569,7 @@ public class SettingsTab : ITab
|
|||
_fileDialog.OpenFolderPicker("Choose Default Export Directory", (b, s) =>
|
||||
{
|
||||
if (b)
|
||||
_exportManager.UpdateExportDirectory(s);
|
||||
_modExportManager.UpdateExportDirectory(s);
|
||||
}, startDir, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,17 +16,17 @@ public class PenumbraWindowSystem : IDisposable
|
|||
public readonly PenumbraChangelog Changelog;
|
||||
|
||||
public PenumbraWindowSystem(DalamudPluginInterface pi, Configuration config, PenumbraChangelog changelog, ConfigWindow window,
|
||||
LaunchButton _,
|
||||
ModEditWindow editWindow, FileDialogService fileDialog)
|
||||
LaunchButton _, ModEditWindow editWindow, FileDialogService fileDialog, ImportPopup importPopup)
|
||||
{
|
||||
_uiBuilder = pi.UiBuilder;
|
||||
_fileDialog = fileDialog;
|
||||
Changelog = changelog;
|
||||
Window = window;
|
||||
_windowSystem = new WindowSystem("Penumbra");
|
||||
_uiBuilder = pi.UiBuilder;
|
||||
_fileDialog = fileDialog;
|
||||
Changelog = changelog;
|
||||
Window = window;
|
||||
_windowSystem = new WindowSystem("Penumbra");
|
||||
_windowSystem.AddWindow(changelog.Changelog);
|
||||
_windowSystem.AddWindow(window);
|
||||
_windowSystem.AddWindow(editWindow);
|
||||
_windowSystem.AddWindow(importPopup);
|
||||
_uiBuilder.OpenConfigUi += Window.Toggle;
|
||||
_uiBuilder.Draw += _windowSystem.Draw;
|
||||
_uiBuilder.Draw += _fileDialog.Draw;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue