Rework DalamudServices,

This commit is contained in:
Ottermandias 2023-12-20 18:47:30 +01:00
parent d8f5851e0c
commit f022d2be64
19 changed files with 230 additions and 250 deletions

@ -1 +1 @@
Subproject commit ac88abfe9eb0bb5d03aec092dc8f4db642ecbd6a
Subproject commit 197d23eee167c232000f22ef40a7a2bded913b6c

View file

@ -40,23 +40,24 @@ public class IpcTester : IDisposable
private readonly Temporary _temporary;
private readonly ResourceTree _resourceTree;
public IpcTester(Configuration config, DalamudServices dalamud, PenumbraIpcProviders ipcProviders, ModManager modManager,
CollectionManager collections, TempModManager tempMods, TempCollectionManager tempCollections, SaveService saveService)
public IpcTester(Configuration config, DalamudPluginInterface pi, IObjectTable objects, IClientState clientState,
PenumbraIpcProviders ipcProviders, ModManager modManager, CollectionManager collections, TempModManager tempMods,
TempCollectionManager tempCollections, SaveService saveService)
{
_ipcProviders = ipcProviders;
_pluginState = new PluginState(dalamud.PluginInterface);
_ipcConfiguration = new IpcConfiguration(dalamud.PluginInterface);
_ui = new Ui(dalamud.PluginInterface);
_redrawing = new Redrawing(dalamud);
_gameState = new GameState(dalamud.PluginInterface);
_resolve = new Resolve(dalamud.PluginInterface);
_collections = new Collections(dalamud.PluginInterface);
_meta = new Meta(dalamud.PluginInterface);
_mods = new Mods(dalamud.PluginInterface);
_modSettings = new ModSettings(dalamud.PluginInterface);
_editing = new Editing(dalamud.PluginInterface);
_temporary = new Temporary(dalamud.PluginInterface, modManager, collections, tempMods, tempCollections, saveService, config);
_resourceTree = new ResourceTree(dalamud.PluginInterface, dalamud.Objects);
_pluginState = new PluginState(pi);
_ipcConfiguration = new IpcConfiguration(pi);
_ui = new Ui(pi);
_redrawing = new Redrawing(pi, objects, clientState);
_gameState = new GameState(pi);
_resolve = new Resolve(pi);
_collections = new Collections(pi);
_meta = new Meta(pi);
_mods = new Mods(pi);
_modSettings = new ModSettings(pi);
_editing = new Editing(pi);
_temporary = new Temporary(pi, modManager, collections, tempMods, tempCollections, saveService, config);
_resourceTree = new ResourceTree(pi, objects);
UnsubscribeEvents();
}
@ -398,17 +399,21 @@ public class IpcTester : IDisposable
private class Redrawing
{
private readonly DalamudServices _dalamud;
private readonly DalamudPluginInterface _pi;
private readonly IClientState _clientState;
private readonly IObjectTable _objects;
public readonly EventSubscriber<IntPtr, int> Redrawn;
private string _redrawName = string.Empty;
private int _redrawIndex = 0;
private string _lastRedrawnString = "None";
public Redrawing(DalamudServices dalamud)
public Redrawing(DalamudPluginInterface pi, IObjectTable objects, IClientState clientState)
{
_dalamud = dalamud;
Redrawn = Ipc.GameObjectRedrawn.Subscriber(_dalamud.PluginInterface, SetLastRedrawn);
_pi = pi;
_objects = objects;
_clientState = clientState;
Redrawn = Ipc.GameObjectRedrawn.Subscriber(_pi, SetLastRedrawn);
}
public void Draw()
@ -426,25 +431,25 @@ public class IpcTester : IDisposable
ImGui.InputTextWithHint("##redrawName", "Name...", ref _redrawName, 32);
ImGui.SameLine();
if (ImGui.Button("Redraw##Name"))
Ipc.RedrawObjectByName.Subscriber(_dalamud.PluginInterface).Invoke(_redrawName, RedrawType.Redraw);
Ipc.RedrawObjectByName.Subscriber(_pi).Invoke(_redrawName, RedrawType.Redraw);
DrawIntro(Ipc.RedrawObject.Label, "Redraw Player Character");
if (ImGui.Button("Redraw##pc") && _dalamud.ClientState.LocalPlayer != null)
Ipc.RedrawObject.Subscriber(_dalamud.PluginInterface).Invoke(_dalamud.ClientState.LocalPlayer, RedrawType.Redraw);
if (ImGui.Button("Redraw##pc") && _clientState.LocalPlayer != null)
Ipc.RedrawObject.Subscriber(_pi).Invoke(_clientState.LocalPlayer, RedrawType.Redraw);
DrawIntro(Ipc.RedrawObjectByIndex.Label, "Redraw by Index");
var tmp = _redrawIndex;
ImGui.SetNextItemWidth(100 * UiHelpers.Scale);
if (ImGui.DragInt("##redrawIndex", ref tmp, 0.1f, 0, _dalamud.Objects.Length))
_redrawIndex = Math.Clamp(tmp, 0, _dalamud.Objects.Length);
if (ImGui.DragInt("##redrawIndex", ref tmp, 0.1f, 0, _objects.Length))
_redrawIndex = Math.Clamp(tmp, 0, _objects.Length);
ImGui.SameLine();
if (ImGui.Button("Redraw##Index"))
Ipc.RedrawObjectByIndex.Subscriber(_dalamud.PluginInterface).Invoke(_redrawIndex, RedrawType.Redraw);
Ipc.RedrawObjectByIndex.Subscriber(_pi).Invoke(_redrawIndex, RedrawType.Redraw);
DrawIntro(Ipc.RedrawAll.Label, "Redraw All");
if (ImGui.Button("Redraw##All"))
Ipc.RedrawAll.Subscriber(_dalamud.PluginInterface).Invoke(RedrawType.Redraw);
Ipc.RedrawAll.Subscriber(_pi).Invoke(RedrawType.Redraw);
DrawIntro(Ipc.GameObjectRedrawn.Label, "Last Redrawn Object:");
ImGui.TextUnformatted(_lastRedrawnString);
@ -453,12 +458,12 @@ public class IpcTester : IDisposable
private void SetLastRedrawn(IntPtr address, int index)
{
if (index < 0
|| index > _dalamud.Objects.Length
|| index > _objects.Length
|| address == IntPtr.Zero
|| _dalamud.Objects[index]?.Address != address)
|| _objects[index]?.Address != address)
_lastRedrawnString = "Invalid";
_lastRedrawnString = $"{_dalamud.Objects[index]!.Name} (0x{address:X}, {index})";
_lastRedrawnString = $"{_objects[index]!.Name} (0x{address:X}, {index})";
}
}
@ -1529,7 +1534,7 @@ public class IpcTester : IDisposable
if (ImGui.Button("Get##GameObjectResourceTrees"))
{
var gameObjects = GetSelectedGameObjects();
var subscriber = Ipc.GetGameObjectResourceTrees.Subscriber(_pi);
var subscriber = Ipc.GetGameObjectResourceTrees.Subscriber(_pi);
_stopwatch.Restart();
var trees = subscriber.Invoke(_withUIData, gameObjects);
@ -1563,7 +1568,7 @@ public class IpcTester : IDisposable
DrawPopup(nameof(Ipc.GetGameObjectResourcesOfType), ref _lastGameObjectResourcesOfType, DrawResourcesOfType, _lastCallDuration);
DrawPopup(nameof(Ipc.GetPlayerResourcesOfType), ref _lastPlayerResourcesOfType, DrawResourcesOfType, _lastCallDuration);
DrawPopup(nameof(Ipc.GetGameObjectResourceTrees), ref _lastGameObjectResourceTrees, DrawResourceTrees, _lastCallDuration);
DrawPopup(nameof(Ipc.GetGameObjectResourceTrees), ref _lastGameObjectResourceTrees, DrawResourceTrees, _lastCallDuration);
DrawPopup(nameof(Ipc.GetPlayerResourceTrees), ref _lastPlayerResourceTrees, DrawResourceTrees!, _lastCallDuration);
}
@ -1695,9 +1700,10 @@ public class IpcTester : IDisposable
{
ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthStretch, 0.5f);
}
ImGui.TableSetupColumn("Game Path", ImGuiTableColumnFlags.WidthStretch, 0.5f);
ImGui.TableSetupColumn("Actual Path", ImGuiTableColumnFlags.WidthStretch, 0.5f);
ImGui.TableSetupColumn("Object Address", ImGuiTableColumnFlags.WidthStretch, 0.2f);
ImGui.TableSetupColumn("Game Path", ImGuiTableColumnFlags.WidthStretch, 0.5f);
ImGui.TableSetupColumn("Actual Path", ImGuiTableColumnFlags.WidthStretch, 0.5f);
ImGui.TableSetupColumn("Object Address", ImGuiTableColumnFlags.WidthStretch, 0.2f);
ImGui.TableSetupColumn("Resource Handle", ImGuiTableColumnFlags.WidthStretch, 0.2f);
ImGui.TableHeadersRow();
@ -1707,10 +1713,10 @@ public class IpcTester : IDisposable
ImGui.TableNextColumn();
var hasChildren = node.Children.Any();
using var treeNode = ImRaii.TreeNode(
$"{(_withUIData ? (node.Name ?? "Unknown") : node.Type)}##{node.ObjectAddress:X8}",
hasChildren ?
ImGuiTreeNodeFlags.SpanFullWidth :
(ImGuiTreeNodeFlags.SpanFullWidth | ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.NoTreePushOnOpen));
$"{(_withUIData ? node.Name ?? "Unknown" : node.Type)}##{node.ObjectAddress:X8}",
hasChildren
? ImGuiTreeNodeFlags.SpanFullWidth
: ImGuiTreeNodeFlags.SpanFullWidth | ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.NoTreePushOnOpen);
if (_withUIData)
{
ImGui.TableNextColumn();
@ -1718,6 +1724,7 @@ public class IpcTester : IDisposable
ImGui.TableNextColumn();
TextUnformattedMono(node.Icon.ToString());
}
ImGui.TableNextColumn();
ImGui.TextUnformatted(node.GamePath ?? "Unknown");
ImGui.TableNextColumn();
@ -1728,10 +1735,8 @@ public class IpcTester : IDisposable
TextUnformattedMono($"0x{node.ResourceHandle:X8}");
if (treeNode)
{
foreach (var child in node.Children)
DrawNode(child);
}
}
foreach (var node in tree.Nodes)

View file

@ -1,4 +1,5 @@
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using Lumina.Data;
using Newtonsoft.Json;
using OtterGui;
@ -88,11 +89,13 @@ public class PenumbraApi : IDisposable, IPenumbraApi
private CommunicatorService _communicator;
private Lumina.GameData? _lumina;
private IDataManager _gameData;
private IFramework _framework;
private IObjectTable _objects;
private ModManager _modManager;
private ResourceLoader _resourceLoader;
private Configuration _config;
private CollectionManager _collectionManager;
private DalamudServices _dalamud;
private TempCollectionManager _tempCollections;
private TempModManager _tempMods;
private ActorManager _actors;
@ -106,18 +109,20 @@ public class PenumbraApi : IDisposable, IPenumbraApi
private TextureManager _textureManager;
private ResourceTreeFactory _resourceTreeFactory;
public unsafe PenumbraApi(CommunicatorService communicator, ModManager modManager, ResourceLoader resourceLoader,
Configuration config, CollectionManager collectionManager, DalamudServices dalamud, TempCollectionManager tempCollections,
TempModManager tempMods, ActorManager actors, CollectionResolver collectionResolver, CutsceneService cutsceneService,
ModImportManager modImportManager, CollectionEditor collectionEditor, RedrawService redrawService, ModFileSystem modFileSystem,
ConfigWindow configWindow, TextureManager textureManager, ResourceTreeFactory resourceTreeFactory)
public unsafe PenumbraApi(CommunicatorService communicator, IDataManager gameData, IFramework framework, IObjectTable objects,
ModManager modManager, ResourceLoader resourceLoader, Configuration config, CollectionManager collectionManager,
TempCollectionManager tempCollections, TempModManager tempMods, ActorManager actors, CollectionResolver collectionResolver,
CutsceneService cutsceneService, ModImportManager modImportManager, CollectionEditor collectionEditor, RedrawService redrawService,
ModFileSystem modFileSystem, ConfigWindow configWindow, TextureManager textureManager, ResourceTreeFactory resourceTreeFactory)
{
_communicator = communicator;
_gameData = gameData;
_framework = framework;
_objects = objects;
_modManager = modManager;
_resourceLoader = resourceLoader;
_config = config;
_collectionManager = collectionManager;
_dalamud = dalamud;
_tempCollections = tempCollections;
_tempMods = tempMods;
_actors = actors;
@ -130,7 +135,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
_configWindow = configWindow;
_textureManager = textureManager;
_resourceTreeFactory = resourceTreeFactory;
_lumina = _dalamud.GameData.GameData;
_lumina = gameData.GameData;
_resourceLoader.ResourceLoaded += OnResourceLoaded;
_communicator.ModPathChanged.Subscribe(ModPathChangeSubscriber, ModPathChanged.Priority.Api);
@ -153,7 +158,6 @@ public class PenumbraApi : IDisposable, IPenumbraApi
_resourceLoader = null!;
_config = null!;
_collectionManager = null!;
_dalamud = null!;
_tempCollections = null!;
_tempMods = null!;
_actors = null!;
@ -166,6 +170,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
_configWindow = null!;
_textureManager = null!;
_resourceTreeFactory = null!;
_framework = null!;
}
public event ChangedItemClick? ChangedItemClicked
@ -399,7 +404,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return await Task.Run(async () =>
{
var playerCollection = await _dalamud.Framework.RunOnFrameworkThread(_collectionResolver.PlayerCollection).ConfigureAwait(false);
var playerCollection = await _framework.RunOnFrameworkThread(_collectionResolver.PlayerCollection).ConfigureAwait(false);
var forwardTask = Task.Run(() =>
{
var forwardRet = new string[forward.Length];
@ -851,7 +856,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
{
CheckInitialized();
if (!ActorManager.VerifyPlayerName(character.AsSpan()) || tag.Length == 0)
if (!ActorIdentifierFactory.VerifyPlayerName(character.AsSpan()) || tag.Length == 0)
return (PenumbraApiEc.InvalidArgument, string.Empty);
var identifier = NameToIdentifier(character, ushort.MaxValue);
@ -889,10 +894,10 @@ public class PenumbraApi : IDisposable, IPenumbraApi
{
CheckInitialized();
if (actorIndex < 0 || actorIndex >= _dalamud.Objects.Length)
if (actorIndex < 0 || actorIndex >= _objects.Length)
return PenumbraApiEc.InvalidArgument;
var identifier = _actors.FromObject(_dalamud.Objects[actorIndex], false, false, true);
var identifier = _actors.FromObject(_objects[actorIndex], false, false, true);
if (!identifier.IsValid)
return PenumbraApiEc.InvalidArgument;
@ -1037,7 +1042,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
public IReadOnlyDictionary<string, string[]>?[] GetGameObjectResourcePaths(ushort[] gameObjects)
{
var characters = gameObjects.Select(index => _dalamud.Objects[index]).OfType<Character>();
var characters = gameObjects.Select(index => _objects[index]).OfType<Character>();
var resourceTrees = _resourceTreeFactory.FromCharacters(characters, 0);
var pathDictionaries = ResourceTreeApiHelper.GetResourcePathDictionaries(resourceTrees);
@ -1055,7 +1060,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
public IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>?[] GetGameObjectResourcesOfType(ResourceType type, bool withUIData,
params ushort[] gameObjects)
{
var characters = gameObjects.Select(index => _dalamud.Objects[index]).OfType<Character>();
var characters = gameObjects.Select(index => _objects[index]).OfType<Character>();
var resourceTrees = _resourceTreeFactory.FromCharacters(characters, withUIData ? ResourceTreeFactory.Flags.WithUiData : 0);
var resDictionaries = ResourceTreeApiHelper.GetResourcesOfType(resourceTrees, type);
@ -1074,7 +1079,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
public Ipc.ResourceTree?[] GetGameObjectResourceTrees(bool withUIData, params ushort[] gameObjects)
{
var characters = gameObjects.Select(index => _dalamud.Objects[index]).OfType<Character>();
var characters = gameObjects.Select(index => _objects[index]).OfType<Character>();
var resourceTrees = _resourceTreeFactory.FromCharacters(characters, withUIData ? ResourceTreeFactory.Flags.WithUiData : 0);
var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);
@ -1126,10 +1131,10 @@ public class PenumbraApi : IDisposable, IPenumbraApi
private unsafe bool AssociatedCollection(int gameObjectIdx, out ModCollection collection)
{
collection = _collectionManager.Active.Default;
if (gameObjectIdx < 0 || gameObjectIdx >= _dalamud.Objects.Length)
if (gameObjectIdx < 0 || gameObjectIdx >= _objects.Length)
return false;
var ptr = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_dalamud.Objects.GetObjectAddress(gameObjectIdx);
var ptr = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_objects.GetObjectAddress(gameObjectIdx);
var data = _collectionResolver.IdentifyCollection(ptr, false);
if (data.Valid)
collection = data.ModCollection;
@ -1140,10 +1145,10 @@ public class PenumbraApi : IDisposable, IPenumbraApi
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private unsafe ActorIdentifier AssociatedIdentifier(int gameObjectIdx)
{
if (gameObjectIdx < 0 || gameObjectIdx >= _dalamud.Objects.Length)
if (gameObjectIdx < 0 || gameObjectIdx >= _objects.Length)
return ActorIdentifier.Invalid;
var ptr = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_dalamud.Objects.GetObjectAddress(gameObjectIdx);
var ptr = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_objects.GetObjectAddress(gameObjectIdx);
return _actors.FromObject(ptr, out _, false, true, true);
}
@ -1168,7 +1173,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
if (Path.IsPathRooted(resolvedPath))
return _lumina?.GetFileFromDisk<T>(resolvedPath);
return _dalamud.GameData.GetFile<T>(resolvedPath);
return _gameData.GetFile<T>(resolvedPath);
}
catch (Exception e)
{

View file

@ -15,7 +15,6 @@ using CurrentSettings = ValueTuple<PenumbraApiEc, (bool, int, IDictionary<string
public class PenumbraIpcProviders : IDisposable
{
internal readonly IPenumbraApi Api;
internal readonly IpcTester Tester;
// Plugin State
internal readonly EventProvider Initialized;
@ -133,10 +132,9 @@ public class PenumbraIpcProviders : IDisposable
internal readonly FuncProvider<bool, ushort[], Ipc.ResourceTree?[]> GetGameObjectResourceTrees;
internal readonly FuncProvider<bool, IReadOnlyDictionary<ushort, Ipc.ResourceTree>> GetPlayerResourceTrees;
public PenumbraIpcProviders(DalamudServices dalamud, IPenumbraApi api, ModManager modManager, CollectionManager collections,
public PenumbraIpcProviders(DalamudPluginInterface pi, IPenumbraApi api, ModManager modManager, CollectionManager collections,
TempModManager tempMods, TempCollectionManager tempCollections, SaveService saveService, Configuration config)
{
var pi = dalamud.PluginInterface;
Api = api;
// Plugin State
@ -260,15 +258,11 @@ public class PenumbraIpcProviders : IDisposable
GetGameObjectResourceTrees = Ipc.GetGameObjectResourceTrees.Provider(pi, Api.GetGameObjectResourceTrees);
GetPlayerResourceTrees = Ipc.GetPlayerResourceTrees.Provider(pi, Api.GetPlayerResourceTrees);
Tester = new IpcTester(config, dalamud, this, modManager, collections, tempMods, tempCollections, saveService);
Initialized.Invoke();
}
public void Dispose()
{
Tester.Dispose();
// Plugin State
Initialized.Dispose();
ApiVersion.Dispose();

View file

@ -44,8 +44,8 @@ public static class TexFileParser
if (offset == 0)
return i;
var requiredSize = width * height * bits / 8;
if (offset + requiredSize > data.Length)
var Size = width * height * bits / 8;
if (offset + Size > data.Length)
return i;
var diff = offset - lastOffset;
@ -55,7 +55,7 @@ public static class TexFileParser
width = Math.Max(width / 2, minSize);
height = Math.Max(height / 2, minSize);
lastOffset = offset;
lastSize = requiredSize;
lastSize = Size;
}
return 13;

View file

@ -13,7 +13,7 @@ namespace Penumbra.Interop.ResourceLoading;
/// </summary>
public unsafe class CreateFileWHook : IDisposable
{
public const int RequiredSize = 28;
public const int Size = 28;
public CreateFileWHook(IGameInteropProvider interop)
{
@ -57,8 +57,8 @@ public unsafe class CreateFileWHook : IDisposable
ptr[22] = (byte)(l >> 16);
ptr[24] = (byte)(l >> 24);
ptr[RequiredSize - 2] = 0;
ptr[RequiredSize - 1] = 0;
ptr[Size - 2] = 0;
ptr[Size - 1] = 0;
}
public void Dispose()

View file

@ -1,10 +1,9 @@
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.DependencyInjection;
using OtterGui;
using OtterGui.Log;
using OtterGui.Services;
using Penumbra.Api;
using Penumbra.Api.Enums;
using Penumbra.Collections;
@ -19,7 +18,6 @@ using Penumbra.UI.Tabs;
using ChangedItemClick = Penumbra.Communication.ChangedItemClick;
using ChangedItemHover = Penumbra.Communication.ChangedItemHover;
using OtterGui.Tasks;
using Penumbra.GameData.Data;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.UI;
@ -48,40 +46,40 @@ public class Penumbra : IDalamudPlugin
private PenumbraWindowSystem? _windowSystem;
private bool _disposed;
private readonly ServiceProvider _services;
private readonly ServiceManager _services;
public Penumbra(DalamudPluginInterface pluginInterface)
{
try
{
_services = ServiceManager.CreateProvider(this, pluginInterface, Log);
Messager = _services.GetRequiredService<MessageService>();
_validityChecker = _services.GetRequiredService<ValidityChecker>();
var startup = _services.GetRequiredService<DalamudServices>().GetDalamudConfig(DalamudServices.WaitingForPluginsOption, out bool s)
_services = ServiceManagerA.CreateProvider(this, pluginInterface, Log);
Messager = _services.GetService<MessageService>();
_validityChecker = _services.GetService<ValidityChecker>();
var startup = _services.GetService<DalamudConfigService>().GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool s)
? s.ToString()
: "Unknown";
Log.Information(
$"Loading Penumbra Version {_validityChecker.Version}, Commit #{_validityChecker.CommitHash} with Waiting For Plugins: {startup}...");
_services.GetRequiredService<BackupService>(); // Initialize because not required anywhere else.
_config = _services.GetRequiredService<Configuration>();
_characterUtility = _services.GetRequiredService<CharacterUtility>();
_tempMods = _services.GetRequiredService<TempModManager>();
_residentResources = _services.GetRequiredService<ResidentResourceManager>();
_services.GetRequiredService<ResourceManagerService>(); // Initialize because not required anywhere else.
_modManager = _services.GetRequiredService<ModManager>();
_collectionManager = _services.GetRequiredService<CollectionManager>();
_tempCollections = _services.GetRequiredService<TempCollectionManager>();
_redrawService = _services.GetRequiredService<RedrawService>();
_communicatorService = _services.GetRequiredService<CommunicatorService>();
_services.GetRequiredService<ResourceService>(); // Initialize because not required anywhere else.
_services.GetRequiredService<ModCacheManager>(); // Initialize because not required anywhere else.
_services.GetRequiredService<ModelResourceHandleUtility>(); // Initialize because not required anywhere else.
_services.GetService<BackupService>(); // Initialize because not required anywhere else.
_config = _services.GetService<Configuration>();
_characterUtility = _services.GetService<CharacterUtility>();
_tempMods = _services.GetService<TempModManager>();
_residentResources = _services.GetService<ResidentResourceManager>();
_services.GetService<ResourceManagerService>(); // Initialize because not required anywhere else.
_modManager = _services.GetService<ModManager>();
_collectionManager = _services.GetService<CollectionManager>();
_tempCollections = _services.GetService<TempCollectionManager>();
_redrawService = _services.GetService<RedrawService>();
_communicatorService = _services.GetService<CommunicatorService>();
_services.GetService<ResourceService>(); // Initialize because not required anywhere else.
_services.GetService<ModCacheManager>(); // Initialize because not required anywhere else.
_services.GetService<ModelResourceHandleUtility>(); // Initialize because not required anywhere else.
_collectionManager.Caches.CreateNecessaryCaches();
_services.GetRequiredService<PathResolver>();
_services.GetService<PathResolver>();
_services.GetRequiredService<SkinFixer>();
_services.GetService<SkinFixer>();
_services.GetRequiredService<DalamudSubstitutionProvider>(); // Initialize before Interface.
_services.GetService<DalamudSubstitutionProvider>(); // Initialize before Interface.
SetupInterface();
SetupApi();
@ -104,8 +102,8 @@ public class Penumbra : IDalamudPlugin
private void SetupApi()
{
var api = _services.GetRequiredService<IPenumbraApi>();
_services.GetRequiredService<PenumbraIpcProviders>();
var api = _services.GetService<IPenumbraApi>();
_services.GetService<PenumbraIpcProviders>();
_communicatorService.ChangedItemHover.Subscribe(it =>
{
if (it is (Item, FullEquipType))
@ -123,9 +121,9 @@ public class Penumbra : IDalamudPlugin
{
AsyncTask.Run(() =>
{
var system = _services.GetRequiredService<PenumbraWindowSystem>();
system.Window.Setup(this, _services.GetRequiredService<ConfigTabBar>());
_services.GetRequiredService<CommandHandler>();
var system = _services.GetService<PenumbraWindowSystem>();
system.Window.Setup(this, _services.GetService<ConfigTabBar>());
_services.GetService<CommandHandler>();
if (!_disposed)
_windowSystem = system;
else
@ -194,7 +192,7 @@ public class Penumbra : IDalamudPlugin
sb.Append($"> **`Auto-Deduplication: `** {_config.AutoDeduplicateOnImport}\n");
sb.Append($"> **`Debug Mode: `** {_config.DebugMode}\n");
sb.Append(
$"> **`Synchronous Load (Dalamud): `** {(_services.GetRequiredService<DalamudServices>().GetDalamudConfig(DalamudServices.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")}\n");
$"> **`Synchronous Load (Dalamud): `** {(_services.GetService<DalamudConfigService>().GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")}\n");
sb.Append(
$"> **`Logging: `** Log: {_config.Ephemeral.EnableResourceLogging}, Watcher: {_config.Ephemeral.EnableResourceWatcher} ({_config.MaxResourceWatcherRecords})\n");
sb.Append($"> **`Use Ownership: `** {_config.UseOwnerNameForCharacterCollection}\n");

View file

@ -9,7 +9,7 @@
"Tags": [ "modding" ],
"DalamudApiLevel": 9,
"LoadPriority": 69420,
"LoadRequiredState": 2,
"LoadState": 2,
"LoadSync": true,
"IconUrl": "https://raw.githubusercontent.com/xivdev/Penumbra/master/images/icon.png"
}

View file

@ -5,15 +5,15 @@ using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Interface.DragDrop;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection;
using OtterGui.Services;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
namespace Penumbra.Services;
public class DalamudServices
public class DalamudConfigService
{
public DalamudServices(DalamudPluginInterface pluginInterface)
public DalamudConfigService(DalamudPluginInterface pluginInterface)
{
pluginInterface.Inject(this);
try
@ -52,55 +52,6 @@ public class DalamudServices
}
}
public void AddServices(IServiceCollection services)
{
services.AddSingleton(PluginInterface);
services.AddSingleton(Commands);
services.AddSingleton(GameData);
services.AddSingleton(ClientState);
services.AddSingleton(Chat);
services.AddSingleton(Framework);
services.AddSingleton(Conditions);
services.AddSingleton(Targets);
services.AddSingleton(Objects);
services.AddSingleton(TitleScreenMenu);
services.AddSingleton(GameGui);
services.AddSingleton(KeyState);
services.AddSingleton(SigScanner);
services.AddSingleton(this);
services.AddSingleton(UiBuilder);
services.AddSingleton(DragDropManager);
services.AddSingleton(TextureProvider);
services.AddSingleton(TextureSubstitutionProvider);
services.AddSingleton(Interop);
services.AddSingleton(Log);
}
// TODO remove static
// @formatter:off
[PluginService][RequiredVersion("1.0")] public DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ICommandManager Commands { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IDataManager GameData { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IClientState ClientState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IChatGui Chat { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IFramework Framework { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ICondition Conditions { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ITargetManager Targets { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IObjectTable Objects { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ITitleScreenMenu TitleScreenMenu { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IGameGui GameGui { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IKeyState KeyState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ISigScanner SigScanner { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IDragDropManager DragDropManager { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ITextureProvider TextureProvider { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ITextureSubstitutionProvider TextureSubstitutionProvider { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IGameInteropProvider Interop { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public IPluginLog Log { get; private set; } = null!;
// @formatter:on
public UiBuilder UiBuilder
=> PluginInterface.UiBuilder;
public const string WaitingForPluginsOption = "IsResumeGameAfterPluginLoad";
private readonly object? _dalamudConfig;
@ -164,3 +115,29 @@ public class DalamudServices
}
}
}
public static class DalamudServices
{
public static void AddServices(ServiceManager services, DalamudPluginInterface pi)
{
services.AddExistingService(pi);
services.AddExistingService(pi.UiBuilder);
services.AddDalamudService<ICommandManager>(pi);
services.AddDalamudService<IDataManager>(pi);
services.AddDalamudService<IClientState>(pi);
services.AddDalamudService<IChatGui>(pi);
services.AddDalamudService<IFramework>(pi);
services.AddDalamudService<ICondition>(pi);
services.AddDalamudService<ITargetManager>(pi);
services.AddDalamudService<IObjectTable>(pi);
services.AddDalamudService<ITitleScreenMenu>(pi);
services.AddDalamudService<IGameGui>(pi);
services.AddDalamudService<IKeyState>(pi);
services.AddDalamudService<ISigScanner>(pi);
services.AddDalamudService<IDragDropManager>(pi);
services.AddDalamudService<ITextureProvider>(pi);
services.AddDalamudService<ITextureSubstitutionProvider>(pi);
services.AddDalamudService<IGameInteropProvider>(pi);
services.AddDalamudService<IPluginLog>(pi);
}
}

View file

@ -7,11 +7,10 @@ using OtterGui.Services;
using Penumbra.Api;
using Penumbra.Collections.Cache;
using Penumbra.Collections.Manager;
using Penumbra.GameData;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Data;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.DataContainers.Bases;
using Penumbra.GameData.Structs;
using Penumbra.Import.Textures;
using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceLoading;
@ -33,14 +32,13 @@ using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManage
namespace Penumbra.Services;
public static class ServiceManager
public static class ServiceManagerA
{
public static ServiceProvider CreateProvider(Penumbra penumbra, DalamudPluginInterface pi, Logger log)
public static ServiceManager CreateProvider(Penumbra penumbra, DalamudPluginInterface pi, Logger log)
{
var services = new ServiceCollection()
.AddSingleton(log)
.AddSingleton(penumbra)
.AddDalamud(pi)
var services = new ServiceManager(log)
.AddExistingService(log)
.AddExistingService(penumbra)
.AddMeta()
.AddGameData()
.AddInterop()
@ -51,37 +49,15 @@ public static class ServiceManager
.AddResolvers()
.AddInterface()
.AddModEditor()
.AddApi()
.AddDataContainers()
.AddAsyncServices();
return services.BuildServiceProvider(new ServiceProviderOptions { ValidateOnBuild = true });
}
private static IServiceCollection AddDalamud(this IServiceCollection services, DalamudPluginInterface pi)
{
var dalamud = new DalamudServices(pi);
dalamud.AddServices(services);
.AddApi();
services.AddIServices(typeof(EquipItem).Assembly);
services.AddIServices(typeof(Penumbra).Assembly);
DalamudServices.AddServices(services, pi);
services.CreateProvider();
return services;
}
private static IServiceCollection AddDataContainers(this IServiceCollection services)
{
foreach (var type in typeof(IDataContainer).Assembly.GetExportedTypes()
.Where(t => t is { IsAbstract: false, IsInterface: false } && t.IsAssignableTo(typeof(IDataContainer))))
services.AddSingleton(type);
return services;
}
private static IServiceCollection AddAsyncServices(this IServiceCollection services)
{
foreach (var type in typeof(ActorManager).Assembly.GetExportedTypes()
.Where(t => t is { IsAbstract: false, IsInterface: false } && t.IsAssignableTo(typeof(IService))))
services.AddSingleton(type);
return services;
}
private static IServiceCollection AddMeta(this IServiceCollection services)
private static ServiceManager AddMeta(this ServiceManager services)
=> services.AddSingleton<ValidityChecker>()
.AddSingleton<PerformanceTracker>()
.AddSingleton<FilenameService>()
@ -89,15 +65,16 @@ public static class ServiceManager
.AddSingleton<CommunicatorService>()
.AddSingleton<MessageService>()
.AddSingleton<SaveService>()
.AddSingleton<FileCompactor>();
.AddSingleton<FileCompactor>()
.AddSingleton<DalamudConfigService>();
private static IServiceCollection AddGameData(this IServiceCollection services)
private static ServiceManager AddGameData(this ServiceManager services)
=> services.AddSingleton<GamePathParser>()
.AddSingleton<StainService>()
.AddSingleton<HumanModelList>();
private static IServiceCollection AddInterop(this IServiceCollection services)
private static ServiceManager AddInterop(this ServiceManager services)
=> services.AddSingleton<GameEventManager>()
.AddSingleton<FrameworkManager>()
.AddSingleton<CutsceneService>()
@ -117,12 +94,12 @@ public static class ServiceManager
.AddSingleton<RedrawService>()
.AddSingleton<ModelResourceHandleUtility>();
private static IServiceCollection AddConfiguration(this IServiceCollection services)
=> services.AddTransient<ConfigMigrationService>()
private static ServiceManager AddConfiguration(this ServiceManager services)
=> services.AddSingleton<ConfigMigrationService>()
.AddSingleton<Configuration>()
.AddSingleton<EphemeralConfig>();
private static IServiceCollection AddCollections(this IServiceCollection services)
private static ServiceManager AddCollections(this ServiceManager services)
=> services.AddSingleton<CollectionStorage>()
.AddSingleton<ActiveCollectionData>()
.AddSingleton<ActiveCollections>()
@ -132,7 +109,7 @@ public static class ServiceManager
.AddSingleton<CollectionEditor>()
.AddSingleton<CollectionManager>();
private static IServiceCollection AddMods(this IServiceCollection services)
private static ServiceManager AddMods(this ServiceManager services)
=> services.AddSingleton<TempModManager>()
.AddSingleton<ModDataEditor>()
.AddSingleton<ModOptionEditor>()
@ -144,14 +121,14 @@ public static class ServiceManager
.AddSingleton<ModCacheManager>()
.AddSingleton(s => (ModStorage)s.GetRequiredService<ModManager>());
private static IServiceCollection AddResources(this IServiceCollection services)
private static ServiceManager AddResources(this ServiceManager services)
=> services.AddSingleton<ResourceLoader>()
.AddSingleton<ResourceWatcher>()
.AddSingleton<ResourceTreeFactory>()
.AddSingleton<MetaFileManager>()
.AddSingleton<SkinFixer>();
private static IServiceCollection AddResolvers(this IServiceCollection services)
private static ServiceManager AddResolvers(this ServiceManager services)
=> services.AddSingleton<AnimationHookService>()
.AddSingleton<CollectionResolver>()
.AddSingleton<CutsceneService>()
@ -162,7 +139,7 @@ public static class ServiceManager
.AddSingleton<IdentifiedCollectionCache>()
.AddSingleton<PathResolver>();
private static IServiceCollection AddInterface(this IServiceCollection services)
private static ServiceManager AddInterface(this ServiceManager services)
=> services.AddSingleton<FileDialogService>()
.AddSingleton<TutorialService>()
.AddSingleton<PenumbraChangelog>()
@ -200,7 +177,7 @@ public static class ServiceManager
.AddSingleton<ChangedItemDrawer>()
.AddSingleton(p => new Diagnostics(p));
private static IServiceCollection AddModEditor(this IServiceCollection services)
private static ServiceManager AddModEditor(this ServiceManager services)
=> services.AddSingleton<ModFileCollection>()
.AddSingleton<DuplicateManager>()
.AddSingleton<MdlMaterialEditor>()
@ -212,10 +189,11 @@ public static class ServiceManager
.AddSingleton<ModEditor>()
.AddSingleton<TextureManager>();
private static IServiceCollection AddApi(this IServiceCollection services)
private static ServiceManager AddApi(this ServiceManager services)
=> services.AddSingleton<PenumbraApi>()
.AddSingleton<IPenumbraApi>(x => x.GetRequiredService<PenumbraApi>())
.AddSingleton<PenumbraIpcProviders>()
.AddSingleton<HttpApi>()
.AddSingleton<IpcTester>()
.AddSingleton<DalamudSubstitutionProvider>();
}

View file

@ -15,7 +15,7 @@ public class ValidityChecker
public readonly bool IsNotInstalledPenumbra;
public readonly bool IsValidSourceRepo;
public readonly List<Exception> ImcExceptions = new();
public readonly List<Exception> ImcExceptions = [];
public readonly string Version;
public readonly string CommitHash;

View file

@ -103,7 +103,7 @@ public partial class ModEditWindow
LoadedShpkPath = path;
var data = LoadedShpkPath.IsRooted
? File.ReadAllBytes(LoadedShpkPath.FullName)
: _edit._dalamud.GameData.GetFile(LoadedShpkPath.InternalName.ToString())?.Data;
: _edit._gameData.GetFile(LoadedShpkPath.InternalName.ToString())?.Data;
AssociatedShpk = data?.Length > 0 ? new ShpkFile(data) : throw new Exception("Failure to load file data.");
LoadedShpkPathName = path.ToPath();
}
@ -457,13 +457,13 @@ public partial class ModEditWindow
var foundMaterials = new HashSet<nint>();
foreach (var materialInfo in instances)
{
var material = materialInfo.GetDrawObjectMaterial(_edit._dalamud.Objects);
var material = materialInfo.GetDrawObjectMaterial(_edit._objects);
if (foundMaterials.Contains((nint)material))
continue;
try
{
MaterialPreviewers.Add(new LiveMaterialPreviewer(_edit._dalamud.Objects, materialInfo));
MaterialPreviewers.Add(new LiveMaterialPreviewer(_edit._objects, materialInfo));
foundMaterials.Add((nint)material);
}
catch (InvalidOperationException)
@ -481,7 +481,7 @@ public partial class ModEditWindow
{
try
{
ColorTablePreviewers.Add(new LiveColorTablePreviewer(_edit._dalamud.Objects, _edit._dalamud.Framework, materialInfo));
ColorTablePreviewers.Add(new LiveColorTablePreviewer(_edit._objects, _edit._framework, materialInfo));
}
catch (InvalidOperationException)
{

View file

@ -71,7 +71,7 @@ public partial class ModEditWindow
}
else
{
var file = _dalamud.GameData.GetFile(path);
var file = _gameData.GetFile(path);
writable = file == null ? null : new RawGameFileWritable(file);
}

View file

@ -219,7 +219,7 @@ public partial class ModEditWindow
if (tex.Path != path)
return;
_dalamud.Framework.RunOnFrameworkThread(() => tex.Reload(_textures));
_framework.RunOnFrameworkThread(() => tex.Reload(_textures));
});
}

View file

@ -36,7 +36,6 @@ public partial class ModEditWindow : Window, IDisposable
private readonly ModEditor _editor;
private readonly Configuration _config;
private readonly ItemSwapTab _itemSwapTab;
private readonly DalamudServices _dalamud;
private readonly MetaFileManager _metaFileManager;
private readonly ActiveCollections _activeCollections;
private readonly StainService _stainService;
@ -44,6 +43,9 @@ public partial class ModEditWindow : Window, IDisposable
private readonly CommunicatorService _communicator;
private readonly IDragDropManager _dragDropManager;
private readonly GameEventManager _gameEvents;
private readonly IDataManager _gameData;
private readonly IFramework _framework;
private readonly IObjectTable _objects;
private Mod? _mod;
private Vector2 _iconSize = Vector2.Zero;
@ -562,37 +564,41 @@ public partial class ModEditWindow : Window, IDisposable
public ModEditWindow(PerformanceTracker performance, FileDialogService fileDialog, ItemSwapTab itemSwapTab, IDataManager gameData,
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager,
StainService stainService, ActiveCollections activeCollections, DalamudServices dalamud, ModMergeTab modMergeTab,
StainService stainService, ActiveCollections activeCollections, ModMergeTab modMergeTab,
CommunicatorService communicator, TextureManager textures, IDragDropManager dragDropManager, GameEventManager gameEvents,
ChangedItemDrawer changedItemDrawer)
ChangedItemDrawer changedItemDrawer, IObjectTable objects, IFramework framework)
: base(WindowBaseLabel)
{
_performance = performance;
_itemSwapTab = itemSwapTab;
_gameData = gameData;
_config = config;
_editor = editor;
_metaFileManager = metaFileManager;
_stainService = stainService;
_activeCollections = activeCollections;
_dalamud = dalamud;
_modMergeTab = modMergeTab;
_communicator = communicator;
_dragDropManager = dragDropManager;
_textures = textures;
_fileDialog = fileDialog;
_gameEvents = gameEvents;
_objects = objects;
_framework = framework;
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Materials", ".mtrl",
() => PopulateIsOnPlayer(_editor.Files.Mtrl, ResourceType.Mtrl), DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable));
_modelTab = new FileEditor<MdlFile>(this, gameData, config, _editor.Compactor, _fileDialog, "Models", ".mdl",
() => PopulateIsOnPlayer(_editor.Files.Mdl, ResourceType.Mdl), DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, (bytes, _, _) => new MdlFile(bytes));
() => PopulateIsOnPlayer(_editor.Files.Mdl, ResourceType.Mdl), DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, _, _) => new MdlFile(bytes));
_shaderPackageTab = new FileEditor<ShpkTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Shaders", ".shpk",
() => PopulateIsOnPlayer(_editor.Files.Shpk, ResourceType.Shpk), DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
() => PopulateIsOnPlayer(_editor.Files.Shpk, ResourceType.Shpk), DrawShaderPackagePanel,
() => _mod?.ModPath.FullName ?? string.Empty,
(bytes, _, _) => new ShpkTab(_fileDialog, bytes));
_center = new CombinedTexture(_left, _right);
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor, () => GetPlayerResourcesOfType(ResourceType.Tex));
_resourceTreeFactory = resourceTreeFactory;
_quickImportViewer =
_quickImportViewer =
new ResourceTreeViewer(_config, resourceTreeFactory, changedItemDrawer, 2, OnQuickImportRefresh, DrawQuickImportActions);
_communicator.ModPathChanged.Subscribe(OnModPathChanged, ModPathChanged.Priority.ModEditWindow);
}

View file

@ -190,9 +190,9 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
var itemPos = ImGui.GetItemRectMax().X;
var maxWidth = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X;
var priorityString = $"[{state.Priority}]";
var requiredSize = ImGui.CalcTextSize(priorityString).X;
var Size = ImGui.CalcTextSize(priorityString).X;
var remainingSpace = maxWidth - itemPos;
var offset = remainingSpace - requiredSize;
var offset = remainingSpace - Size;
if (ImGui.GetScrollMaxY() == 0)
offset -= ImGui.GetStyle().ItemInnerSpacing.X;

View file

@ -2,6 +2,7 @@ using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Group;
@ -70,7 +71,6 @@ public class DebugTab : Window, ITab
private readonly ValidityChecker _validityChecker;
private readonly HttpApi _httpApi;
private readonly ActorManager _actors;
private readonly DalamudServices _dalamud;
private readonly StainService _stains;
private readonly CharacterUtility _characterUtility;
private readonly ResidentResourceManager _residentResources;
@ -90,14 +90,16 @@ public class DebugTab : Window, ITab
private readonly RedrawService _redraws;
private readonly DictEmotes _emotes;
private readonly Diagnostics _diagnostics;
private readonly IObjectTable _objects;
private readonly IClientState _clientState;
private readonly IpcTester _ipcTester;
public DebugTab(PerformanceTracker performance, Configuration config, CollectionManager collectionManager,
ValidityChecker validityChecker, ModManager modManager, HttpApi httpApi, ActorManager actors,
DalamudServices dalamud, StainService stains, CharacterUtility characterUtility, ResidentResourceManager residentResources,
public DebugTab(PerformanceTracker performance, Configuration config, CollectionManager collectionManager, IObjectTable objects, IClientState clientState,
ValidityChecker validityChecker, ModManager modManager, HttpApi httpApi, ActorManager actors, StainService stains, CharacterUtility characterUtility, ResidentResourceManager residentResources,
ResourceManagerService resourceManager, PenumbraIpcProviders ipc, CollectionResolver collectionResolver,
DrawObjectState drawObjectState, PathState pathState, SubfileHelper subfileHelper, IdentifiedCollectionCache identifiedCollectionCache,
CutsceneService cutsceneService, ModImportManager modImporter, ImportPopup importPopup, FrameworkManager framework,
TextureManager textureManager, SkinFixer skinFixer, RedrawService redraws, DictEmotes emotes, Diagnostics diagnostics)
TextureManager textureManager, SkinFixer skinFixer, RedrawService redraws, DictEmotes emotes, Diagnostics diagnostics, IpcTester ipcTester)
: base("Penumbra Debug Window", ImGuiWindowFlags.NoCollapse)
{
IsOpen = true;
@ -113,7 +115,6 @@ public class DebugTab : Window, ITab
_modManager = modManager;
_httpApi = httpApi;
_actors = actors;
_dalamud = dalamud;
_stains = stains;
_characterUtility = characterUtility;
_residentResources = residentResources;
@ -133,6 +134,9 @@ public class DebugTab : Window, ITab
_redraws = redraws;
_emotes = emotes;
_diagnostics = diagnostics;
_ipcTester = ipcTester;
_objects = objects;
_clientState = clientState;
}
public ReadOnlySpan<byte> Label
@ -417,7 +421,7 @@ public class DebugTab : Window, ITab
DrawSpecial("Current Card", _actors.GetCardPlayer());
DrawSpecial("Current Glamour", _actors.GetGlamourPlayer());
foreach (var obj in _dalamud.Objects)
foreach (var obj in _objects)
{
ImGuiUtil.DrawTableColumn($"{((GameObject*)obj.Address)->ObjectIndex}");
ImGuiUtil.DrawTableColumn($"0x{obj.Address:X}");
@ -827,7 +831,7 @@ public class DebugTab : Window, ITab
/// <summary> Draw information about the models, materials and resources currently loaded by the local player. </summary>
private unsafe void DrawPlayerModelInfo()
{
var player = _dalamud.ClientState.LocalPlayer;
var player = _clientState.LocalPlayer;
var name = player?.Name.ToString() ?? "NULL";
if (!ImGui.CollapsingHeader($"Player Model Info: {name}##Draw") || player == null)
return;
@ -952,11 +956,11 @@ public class DebugTab : Window, ITab
{
if (!ImGui.CollapsingHeader("IPC"))
{
_ipc.Tester.UnsubscribeEvents();
_ipcTester.UnsubscribeEvents();
return;
}
_ipc.Tester.Draw();
_ipcTester.Draw();
}
/// <summary> Helper to print a property and its value in a 2-column table. </summary>

View file

@ -1,5 +1,7 @@
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using ImGuiNET;
using OtterGui;
@ -33,19 +35,23 @@ public class SettingsTab : ITab
private readonly ModFileSystemSelector _selector;
private readonly CharacterUtility _characterUtility;
private readonly ResidentResourceManager _residentResources;
private readonly DalamudServices _dalamud;
private readonly HttpApi _httpApi;
private readonly DalamudSubstitutionProvider _dalamudSubstitutionProvider;
private readonly FileCompactor _compactor;
private readonly DalamudConfigService _dalamudConfig;
private readonly DalamudPluginInterface _pluginInterface;
private readonly IDataManager _gameData;
private int _minimumX = int.MaxValue;
private int _minimumY = int.MaxValue;
public SettingsTab(Configuration config, FontReloader fontReloader, TutorialService tutorial, Penumbra penumbra,
FileDialogService fileDialog, ModManager modManager, ModFileSystemSelector selector, CharacterUtility characterUtility,
ResidentResourceManager residentResources, DalamudServices dalamud, ModExportManager modExportManager, HttpApi httpApi,
DalamudSubstitutionProvider dalamudSubstitutionProvider, FileCompactor compactor)
public SettingsTab(DalamudPluginInterface pluginInterface, Configuration config, FontReloader fontReloader, TutorialService tutorial,
Penumbra penumbra, FileDialogService fileDialog, ModManager modManager, ModFileSystemSelector selector,
CharacterUtility characterUtility, ResidentResourceManager residentResources, ModExportManager modExportManager, HttpApi httpApi,
DalamudSubstitutionProvider dalamudSubstitutionProvider, FileCompactor compactor, DalamudConfigService dalamudConfig,
IDataManager gameData)
{
_pluginInterface = pluginInterface;
_config = config;
_fontReloader = fontReloader;
_tutorial = tutorial;
@ -55,11 +61,12 @@ public class SettingsTab : ITab
_selector = selector;
_characterUtility = characterUtility;
_residentResources = residentResources;
_dalamud = dalamud;
_modExportManager = modExportManager;
_httpApi = httpApi;
_dalamudSubstitutionProvider = dalamudSubstitutionProvider;
_compactor = compactor;
_dalamudConfig = dalamudConfig;
_gameData = gameData;
if (_compactor.CanCompact)
_compactor.Enabled = _config.UseFileSystemCompression;
}
@ -164,14 +171,14 @@ public class SettingsTab : ITab
if (IsSubPathOf(programFiles, newName) || IsSubPathOf(programFilesX86, newName))
return ("Path is not allowed to be in ProgramFiles.", false);
var dalamud = _dalamud.PluginInterface.ConfigDirectory.Parent!.Parent!;
var dalamud = _pluginInterface.ConfigDirectory.Parent!.Parent!;
if (IsSubPathOf(dalamud.FullName, newName))
return ("Path is not allowed to be inside your Dalamud directories.", false);
if (Functions.GetDownloadsFolder(out var downloads) && IsSubPathOf(downloads, newName))
return ("Path is not allowed to be inside your Downloads folder.", false);
var gameDir = _dalamud.GameData.GameData.DataPath.Parent!.Parent!.FullName;
var gameDir = _gameData.GameData.DataPath.Parent!.Parent!.FullName;
if (IsSubPathOf(gameDir, newName))
return ("Path is not allowed to be inside your game folder.", false);
@ -368,21 +375,21 @@ public class SettingsTab : ITab
v =>
{
_config.HideUiWhenUiHidden = v;
_dalamud.UiBuilder.DisableUserUiHide = !v;
_pluginInterface.UiBuilder.DisableUserUiHide = !v;
});
Checkbox("Hide Config Window when in Cutscenes",
"Hide the Penumbra main window when you are currently watching a cutscene.", _config.HideUiInCutscenes,
v =>
{
_config.HideUiInCutscenes = v;
_dalamud.UiBuilder.DisableCutsceneUiHide = !v;
_config.HideUiInCutscenes = v;
_pluginInterface.UiBuilder.DisableCutsceneUiHide = !v;
});
Checkbox("Hide Config Window when in GPose",
"Hide the Penumbra main window when you are currently in GPose mode.", _config.HideUiInGPose,
v =>
{
_config.HideUiInGPose = v;
_dalamud.UiBuilder.DisableGposeUiHide = !v;
_config.HideUiInGPose = v;
_pluginInterface.UiBuilder.DisableGposeUiHide = !v;
});
}
@ -847,7 +854,7 @@ public class SettingsTab : ITab
/// <summary> Draw a checkbox that toggles the dalamud setting to wait for plugins on open. </summary>
private void DrawWaitForPluginsReflection()
{
if (!_dalamud.GetDalamudConfig(DalamudServices.WaitingForPluginsOption, out bool value))
if (!_dalamudConfig.GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool value))
{
using var disabled = ImRaii.Disabled();
Checkbox("Wait for Plugins on Startup (Disabled, can not access Dalamud Configuration)", string.Empty, false, v => { });
@ -855,9 +862,12 @@ public class SettingsTab : ITab
else
{
Checkbox("Wait for Plugins on Startup",
"Some mods need to change files that are loaded once when the game starts and never afterwards.\nThis can cause issues with Penumbra loading after the files are already loaded.\nThis setting causes the game to wait until certain plugins have finished loading, making those mods work (in the base collection).\n\nThis changes a setting in the Dalamud Configuration found at /xlsettings -> General.",
"Some mods need to change files that are loaded once when the game starts and never afterwards.\n"
+ "This can cause issues with Penumbra loading after the files are already loaded.\n"
+ "This setting causes the game to wait until certain plugins have finished loading, making those mods work (in the base collection).\n\n"
+ "This changes a setting in the Dalamud Configuration found at /xlsettings -> General.",
value,
v => _dalamud.SetDalamudConfig(DalamudServices.WaitingForPluginsOption, v, "doWaitForPluginsOnStartup"));
v => _dalamudConfig.SetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, v, "doWaitForPluginsOnStartup"));
}
}

View file

@ -73,7 +73,10 @@
}
},
"ottergui": {
"type": "Project"
"type": "Project",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[7.0.0, )"
}
},
"penumbra.api": {
"type": "Project"