Make ResourceTrees work with UseNoMods.

This commit is contained in:
Ottermandias 2024-07-19 14:24:29 +02:00
parent 5abbd8b110
commit f978b35b76
7 changed files with 24 additions and 26 deletions

@ -1 +1 @@
Subproject commit c5ad1f3ae9818baa446327bdcf49fac65088c703 Subproject commit a1e637f835c1a42732825e8e0690aeef0024b101

View file

@ -103,10 +103,6 @@ public class MetaCache(MetaFileManager manager, ModCollection collection)
~MetaCache() ~MetaCache()
=> Dispose(); => Dispose();
/// <summary> Try to obtain a manipulated IMC file. </summary>
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out Meta.Files.ImcFile? file)
=> Imc.GetFile(path.Path, out file);
internal EqdpEntry GetEqdpEntry(GenderRace race, bool accessory, PrimaryId primaryId) internal EqdpEntry GetEqdpEntry(GenderRace race, bool accessory, PrimaryId primaryId)
=> Eqdp.ApplyFullEntry(primaryId, race, accessory, Meta.Files.ExpandedEqdpFile.GetDefault(manager, race, accessory, primaryId)); => Eqdp.ApplyFullEntry(primaryId, race, accessory, Meta.Files.ExpandedEqdpFile.GetDefault(manager, race, accessory, primaryId));

View file

@ -43,15 +43,6 @@ public partial class ModCollection
internal MetaCache? MetaCache internal MetaCache? MetaCache
=> _cache?.Meta; => _cache?.Meta;
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
{
if (_cache != null)
return _cache.Meta.GetImcFile(path, out file);
file = null;
return false;
}
internal IReadOnlyDictionary<Utf8GamePath, ModPath> ResolvedFiles internal IReadOnlyDictionary<Utf8GamePath, ModPath> ResolvedFiles
=> _cache?.ResolvedFiles ?? new ConcurrentDictionary<Utf8GamePath, ModPath>(); => _cache?.ResolvedFiles ?? new ConcurrentDictionary<Utf8GamePath, ModPath>();

View file

@ -12,6 +12,8 @@ using Penumbra.GameData.Structs;
using Penumbra.Import.Models.Export; using Penumbra.Import.Models.Export;
using Penumbra.Import.Models.Import; using Penumbra.Import.Models.Import;
using Penumbra.Import.Textures; using Penumbra.Import.Textures;
using Penumbra.Meta;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using SharpGLTF.Scenes; using SharpGLTF.Scenes;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
@ -22,7 +24,7 @@ namespace Penumbra.Import.Models;
using Schema2 = SharpGLTF.Schema2; using Schema2 = SharpGLTF.Schema2;
using LuminaMaterial = Lumina.Models.Materials.Material; using LuminaMaterial = Lumina.Models.Materials.Material;
public sealed class ModelManager(IFramework framework, ActiveCollections collections, GamePathParser parser) public sealed class ModelManager(IFramework framework, MetaFileManager metaFileManager, ActiveCollections collections, GamePathParser parser)
: SingleTaskQueue, IDisposable, IService : SingleTaskQueue, IDisposable, IService
{ {
private readonly IFramework _framework = framework; private readonly IFramework _framework = framework;
@ -97,7 +99,7 @@ public sealed class ModelManager(IFramework framework, ActiveCollections collect
// Try to use an entry from provided manipulations, falling back to the current collection. // Try to use an entry from provided manipulations, falling back to the current collection.
var targetId = modEst?.Value var targetId = modEst?.Value
?? collections.Current.MetaCache?.GetEstEntry(type, info.GenderRace, info.PrimaryId) ?? collections.Current.MetaCache?.GetEstEntry(type, info.GenderRace, info.PrimaryId)
?? EstEntry.Zero; ?? EstFile.GetDefault(metaFileManager, type, info.GenderRace, info.PrimaryId);
// If there's no entries, we can assume that there's no additional skeleton. // If there's no entries, we can assume that there's no additional skeleton.
if (targetId == EstEntry.Zero) if (targetId == EstEntry.Zero)

View file

@ -3,6 +3,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Meta;
using Penumbra.Meta.Files; using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using Penumbra.String; using Penumbra.String;
@ -51,10 +52,8 @@ internal partial record ResolveContext
return GenderRace.MidlanderMale; return GenderRace.MidlanderMale;
var metaCache = Global.Collection.MetaCache; var metaCache = Global.Collection.MetaCache;
if (metaCache == null) var entry = metaCache?.GetEqdpEntry(characterRaceCode, accessory, primaryId)
return GenderRace.MidlanderMale; ?? ExpandedEqdpFile.GetDefault(Global.MetaFileManager, characterRaceCode, accessory, primaryId);
var entry = metaCache.GetEqdpEntry(characterRaceCode, accessory, primaryId);
if (entry.ToBits(slot).Item2) if (entry.ToBits(slot).Item2)
return characterRaceCode; return characterRaceCode;
@ -62,7 +61,8 @@ internal partial record ResolveContext
if (fallbackRaceCode == GenderRace.MidlanderMale) if (fallbackRaceCode == GenderRace.MidlanderMale)
return GenderRace.MidlanderMale; return GenderRace.MidlanderMale;
entry = metaCache.GetEqdpEntry(fallbackRaceCode, accessory, primaryId); entry = metaCache?.GetEqdpEntry(fallbackRaceCode, accessory, primaryId)
?? ExpandedEqdpFile.GetDefault(Global.MetaFileManager, fallbackRaceCode, accessory, primaryId);
if (entry.ToBits(slot).Item2) if (entry.ToBits(slot).Item2)
return fallbackRaceCode; return fallbackRaceCode;
@ -271,8 +271,9 @@ internal partial record ResolveContext
private (GenderRace RaceCode, string Slot, PrimaryId Set) ResolveHumanExtraSkeletonData(GenderRace raceCode, EstType type, private (GenderRace RaceCode, string Slot, PrimaryId Set) ResolveHumanExtraSkeletonData(GenderRace raceCode, EstType type,
PrimaryId primary) PrimaryId primary)
{ {
var metaCache = Global.Collection.MetaCache; var metaCache = Global.Collection.MetaCache;
var skeletonSet = metaCache?.GetEstEntry(type, raceCode, primary) ?? default; var skeletonSet = metaCache?.GetEstEntry(type, raceCode, primary)
?? EstFile.GetDefault(Global.MetaFileManager, type, raceCode, primary);
return (raceCode, type.ToName(), skeletonSet.AsId); return (raceCode, type.ToName(), skeletonSet.AsId);
} }

View file

@ -11,6 +11,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Interop.Hooks.PostProcessing; using Penumbra.Interop.Hooks.PostProcessing;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Meta;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.UI; using Penumbra.UI;
@ -19,7 +20,12 @@ using ModelType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase.M
namespace Penumbra.Interop.ResourceTree; namespace Penumbra.Interop.ResourceTree;
internal record GlobalResolveContext(ObjectIdentification Identifier, ModCollection Collection, TreeBuildCache TreeBuildCache, bool WithUiData) internal record GlobalResolveContext(
MetaFileManager MetaFileManager,
ObjectIdentification Identifier,
ModCollection Collection,
TreeBuildCache TreeBuildCache,
bool WithUiData)
{ {
public readonly Dictionary<(Utf8GamePath, nint), ResourceNode> Nodes = new(128); public readonly Dictionary<(Utf8GamePath, nint), ResourceNode> Nodes = new(128);
@ -111,7 +117,7 @@ internal unsafe partial record ResolveContext(
if (resourceHandle == null) if (resourceHandle == null)
throw new ArgumentNullException(nameof(resourceHandle)); throw new ArgumentNullException(nameof(resourceHandle));
var fileName = (ReadOnlySpan<byte>) resourceHandle->FileName.AsSpan(); var fileName = (ReadOnlySpan<byte>)resourceHandle->FileName.AsSpan();
var additionalData = ByteString.Empty; var additionalData = ByteString.Empty;
if (PathDataHandler.Split(fileName, out fileName, out var data)) if (PathDataHandler.Split(fileName, out fileName, out var data))
additionalData = ByteString.FromSpanUnsafe(data, false).Clone(); additionalData = ByteString.FromSpanUnsafe(data, false).Clone();

View file

@ -8,6 +8,7 @@ using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Interop; using Penumbra.GameData.Interop;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Meta;
using Penumbra.String.Classes; using Penumbra.String.Classes;
namespace Penumbra.Interop.ResourceTree; namespace Penumbra.Interop.ResourceTree;
@ -15,6 +16,7 @@ namespace Penumbra.Interop.ResourceTree;
public class ResourceTreeFactory( public class ResourceTreeFactory(
IDataManager gameData, IDataManager gameData,
ObjectManager objects, ObjectManager objects,
MetaFileManager metaFileManager,
CollectionResolver resolver, CollectionResolver resolver,
ObjectIdentification identifier, ObjectIdentification identifier,
Configuration config, Configuration config,
@ -78,7 +80,7 @@ public class ResourceTreeFactory(
var networked = character.EntityId != 0xE0000000; var networked = character.EntityId != 0xE0000000;
var tree = new ResourceTree(name, anonymizedName, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related, var tree = new ResourceTree(name, anonymizedName, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related,
networked, collectionResolveData.ModCollection.Name, collectionResolveData.ModCollection.AnonymizedName); networked, collectionResolveData.ModCollection.Name, collectionResolveData.ModCollection.AnonymizedName);
var globalContext = new GlobalResolveContext(identifier, collectionResolveData.ModCollection, var globalContext = new GlobalResolveContext(metaFileManager, identifier, collectionResolveData.ModCollection,
cache, (flags & Flags.WithUiData) != 0); cache, (flags & Flags.WithUiData) != 0);
using (var _ = pathState.EnterInternalResolve()) using (var _ = pathState.EnterInternalResolve())
{ {