From 42e4bcd4dd8b33f7a1cd0910ea45710ee6530464 Mon Sep 17 00:00:00 2001 From: Anna Date: Sun, 18 Feb 2024 15:41:27 -0500 Subject: [PATCH] feat: handle more objects for mod detection --- PenumbraIpc.cs | 10 ++++++++++ ScreenshotMetadata.cs | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/PenumbraIpc.cs b/PenumbraIpc.cs index f102320..2b65be4 100644 --- a/PenumbraIpc.cs +++ b/PenumbraIpc.cs @@ -5,6 +5,7 @@ namespace Screenie; internal class PenumbraIpc { private Plugin Plugin { get; } private FuncSubscriber GetModDirectorySubscriber { get; } + private ParamsFuncSubscriber?[]> GetGameObjectResourcePathsSubscriber { get; } private FuncSubscriber>> GetPlayerResourcePathsSubscriber { get; } private FuncSubscriber> GetModsSubscriber { get; } @@ -12,6 +13,7 @@ internal class PenumbraIpc { this.Plugin = plugin; this.GetModDirectorySubscriber = Penumbra.Api.Ipc.GetModDirectory.Subscriber(this.Plugin.Interface); + this.GetGameObjectResourcePathsSubscriber = Penumbra.Api.Ipc.GetGameObjectResourcePaths.Subscriber(this.Plugin.Interface); this.GetPlayerResourcePathsSubscriber = Penumbra.Api.Ipc.GetPlayerResourcePaths.Subscriber(this.Plugin.Interface); this.GetModsSubscriber = Penumbra.Api.Ipc.GetMods.Subscriber(this.Plugin.Interface); } @@ -24,6 +26,14 @@ internal class PenumbraIpc { } } + internal IReadOnlyDictionary?[]? GetGameObjectResourcePaths(params ushort[] objects) { + try { + return this.GetGameObjectResourcePathsSubscriber.Invoke(objects); + } catch { + return null; + } + } + internal IReadOnlyDictionary>? GetPlayerResourcePaths() { try { return this.GetPlayerResourcePathsSubscriber.Invoke(); diff --git a/ScreenshotMetadata.cs b/ScreenshotMetadata.cs index 24db425..160a3f2 100644 --- a/ScreenshotMetadata.cs +++ b/ScreenshotMetadata.cs @@ -1,4 +1,5 @@ using System.Numerics; +using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game.Housing; @@ -11,6 +12,7 @@ using Lumina.Excel.GeneratedSheets; using Newtonsoft.Json; using Screenie.Util; using Map = Lumina.Excel.GeneratedSheets.Map; +using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; namespace Screenie; @@ -95,8 +97,29 @@ public class ScreenshotMetadata { } var timeUtc = DateTime.UtcNow; + // var relevantModObjects = new List(); + var relevantModObjects = new List(); var visible = plugin.ObjectTable - .Where(obj => obj is PlayerCharacter) + .Where(obj => { + // pull a sneaky and populate the relevantModObjects list here + if ( + obj.ObjectKind is + ObjectKind.Player + or ObjectKind.Companion + or ObjectKind.BattleNpc + or ObjectKind.EventNpc + or ObjectKind.MountType + or ObjectKind.Retainer + ) { + if (obj.ObjectId > ushort.MaxValue) { + Plugin.Log.Warning($"cannot pass object with id {obj.ObjectId} to Penumbra: too large"); + } else { + relevantModObjects.Add((ushort) obj.ObjectId); + } + } + + return obj is PlayerCharacter; + }) .Cast() .Where(chara => { unsafe { @@ -114,12 +137,19 @@ public class ScreenshotMetadata { .ToArray(); var modDir = plugin.Penumbra.GetModDirectory(); - var paths = plugin.Penumbra.GetPlayerResourcePaths(); + var paths = plugin.Penumbra.GetGameObjectResourcePaths([.. relevantModObjects]); var mods = plugin.Penumbra.GetMods(); var modsInUse = new HashSet(); if (modDir != null && paths != null && mods != null) { var baseUri = new Uri($"{Path.TrimEndingDirectorySeparator(modDir)}/"); - foreach (var dict in paths.Values) { + var enumerable = paths + .Where(p => p != null) + .SelectMany(p => p!.Values); + foreach (var dict in paths) { + if (dict == null) { + continue; + } + foreach (var path in dict.Keys) { if (!Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out var pathUri)) { continue;