mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Merge remote-tracking branch 'Exter-N/72'
This commit is contained in:
commit
6cbc8bd58f
3 changed files with 45 additions and 33 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9ae4a97110fff005a54213815086ce950d4d8b2d
|
Subproject commit 1158cf404a16979d0b7e12f7bbcbbc651da16add
|
||||||
|
|
@ -23,24 +23,35 @@ public class ResourceTreeFactory(
|
||||||
Configuration config,
|
Configuration config,
|
||||||
ActorManager actors,
|
ActorManager actors,
|
||||||
PathState pathState,
|
PathState pathState,
|
||||||
|
IFramework framework,
|
||||||
ModManager modManager) : IService
|
ModManager modManager) : IService
|
||||||
{
|
{
|
||||||
private static readonly string ParentDirectoryPrefix = $"..{Path.DirectorySeparatorChar}";
|
private static readonly string ParentDirectoryPrefix = $"..{Path.DirectorySeparatorChar}";
|
||||||
|
|
||||||
private TreeBuildCache CreateTreeBuildCache()
|
private TreeBuildCache CreateTreeBuildCache()
|
||||||
=> new(objects, gameData, actors);
|
=> new(framework.IsInFrameworkUpdateThread ? objects : null, gameData, actors);
|
||||||
|
|
||||||
|
private TreeBuildCache CreateTreeBuildCache(Flags flags)
|
||||||
|
=> !framework.IsInFrameworkUpdateThread && flags.HasFlag(Flags.PopulateObjectTableData)
|
||||||
|
? framework.RunOnFrameworkThread(CreateTreeBuildCache).Result
|
||||||
|
: CreateTreeBuildCache();
|
||||||
|
|
||||||
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
||||||
{
|
=> framework.RunOnFrameworkThread(() =>
|
||||||
var cache = CreateTreeBuildCache();
|
{
|
||||||
return cache.GetLocalPlayerRelatedCharacters();
|
var cache = CreateTreeBuildCache();
|
||||||
}
|
return cache.GetLocalPlayerRelatedCharacters();
|
||||||
|
}).Result;
|
||||||
|
|
||||||
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromObjectTable(
|
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromObjectTable(
|
||||||
Flags flags)
|
Flags flags)
|
||||||
{
|
{
|
||||||
var cache = CreateTreeBuildCache();
|
var (cache, characters) = framework.RunOnFrameworkThread(() =>
|
||||||
var characters = (flags & Flags.LocalPlayerRelatedOnly) != 0 ? cache.GetLocalPlayerRelatedCharacters() : cache.GetCharacters();
|
{
|
||||||
|
var cache = CreateTreeBuildCache();
|
||||||
|
var characters = ((flags & Flags.LocalPlayerRelatedOnly) != 0 ? cache.GetLocalPlayerRelatedCharacters() : cache.GetCharacters()).ToArray();
|
||||||
|
return (cache, characters);
|
||||||
|
}).Result;
|
||||||
|
|
||||||
foreach (var character in characters)
|
foreach (var character in characters)
|
||||||
{
|
{
|
||||||
|
|
@ -53,7 +64,7 @@ public class ResourceTreeFactory(
|
||||||
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromCharacters(
|
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromCharacters(
|
||||||
IEnumerable<ICharacter> characters, Flags flags)
|
IEnumerable<ICharacter> characters, Flags flags)
|
||||||
{
|
{
|
||||||
var cache = CreateTreeBuildCache();
|
var cache = CreateTreeBuildCache(flags);
|
||||||
foreach (var character in characters)
|
foreach (var character in characters)
|
||||||
{
|
{
|
||||||
var tree = FromCharacter(character, cache, flags);
|
var tree = FromCharacter(character, cache, flags);
|
||||||
|
|
@ -63,7 +74,7 @@ public class ResourceTreeFactory(
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceTree? FromCharacter(ICharacter character, Flags flags)
|
public ResourceTree? FromCharacter(ICharacter character, Flags flags)
|
||||||
=> FromCharacter(character, CreateTreeBuildCache(), flags);
|
=> FromCharacter(character, CreateTreeBuildCache(flags), flags);
|
||||||
|
|
||||||
private unsafe ResourceTree? FromCharacter(ICharacter character, TreeBuildCache cache, Flags flags)
|
private unsafe ResourceTree? FromCharacter(ICharacter character, TreeBuildCache cache, Flags flags)
|
||||||
{
|
{
|
||||||
|
|
@ -80,7 +91,7 @@ public class ResourceTreeFactory(
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var localPlayerRelated = cache.IsLocalPlayerRelated(character);
|
var localPlayerRelated = cache.IsLocalPlayerRelated(character);
|
||||||
var (name, anonymizedName, related) = GetCharacterName(character);
|
var (name, anonymizedName, related) = GetCharacterName((GameObject*)character.Address);
|
||||||
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.Identity.Name, collectionResolveData.ModCollection.Identity.AnonymizedName);
|
networked, collectionResolveData.ModCollection.Identity.Name, collectionResolveData.ModCollection.Identity.AnonymizedName);
|
||||||
|
|
@ -183,36 +194,37 @@ public class ResourceTreeFactory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe (string Name, string AnonymizedName, bool PlayerRelated) GetCharacterName(ICharacter character)
|
private unsafe (string Name, string AnonymizedName, bool PlayerRelated) GetCharacterName(GameObject* character)
|
||||||
{
|
{
|
||||||
var identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false);
|
var identifier = actors.FromObject(character, out var owner, true, false, false);
|
||||||
var identifierStr = identifier.ToString();
|
var identifierStr = identifier.ToString();
|
||||||
return (identifierStr, identifier.Incognito(identifierStr), IsPlayerRelated(identifier, owner));
|
return (identifierStr, identifier.Incognito(identifierStr), IsPlayerRelated(identifier, owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe bool IsPlayerRelated(ICharacter? character)
|
private unsafe bool IsPlayerRelated(GameObject* character)
|
||||||
{
|
{
|
||||||
if (character == null)
|
if (character is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false);
|
var identifier = actors.FromObject(character, out var owner, true, false, false);
|
||||||
return IsPlayerRelated(identifier, owner);
|
return IsPlayerRelated(identifier, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsPlayerRelated(ActorIdentifier identifier, Actor owner)
|
private unsafe bool IsPlayerRelated(ActorIdentifier identifier, Actor owner)
|
||||||
=> identifier.Type switch
|
=> identifier.Type switch
|
||||||
{
|
{
|
||||||
IdentifierType.Player => true,
|
IdentifierType.Player => true,
|
||||||
IdentifierType.Owned => IsPlayerRelated(objects.Objects.CreateObjectReference(owner) as ICharacter),
|
IdentifierType.Owned => IsPlayerRelated(owner.AsObject),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum Flags
|
public enum Flags
|
||||||
{
|
{
|
||||||
RedactExternalPaths = 1,
|
RedactExternalPaths = 1,
|
||||||
WithUiData = 2,
|
WithUiData = 2,
|
||||||
LocalPlayerRelatedOnly = 4,
|
LocalPlayerRelatedOnly = 4,
|
||||||
WithOwnership = 8,
|
WithOwnership = 8,
|
||||||
|
PopulateObjectTableData = 16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,15 @@ using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Interop.ResourceTree;
|
namespace Penumbra.Interop.ResourceTree;
|
||||||
|
|
||||||
internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager dataManager, ActorManager actors)
|
internal readonly struct TreeBuildCache(ObjectManager? objects, IDataManager dataManager, ActorManager actors)
|
||||||
{
|
{
|
||||||
private readonly Dictionary<FullPath, IReadOnlyDictionary<uint, Name>?> _shaderPackageNames = [];
|
private readonly Dictionary<FullPath, IReadOnlyDictionary<uint, Name>?> _shaderPackageNames = [];
|
||||||
|
|
||||||
|
private readonly IGameObject? _player = objects?.GetDalamudObject(0);
|
||||||
|
|
||||||
public unsafe bool IsLocalPlayerRelated(ICharacter character)
|
public unsafe bool IsLocalPlayerRelated(ICharacter character)
|
||||||
{
|
{
|
||||||
var player = objects.GetDalamudObject(0);
|
if (_player is null)
|
||||||
if (player == null)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var gameObject = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)character.Address;
|
var gameObject = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)character.Address;
|
||||||
|
|
@ -28,27 +29,26 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
|
||||||
return actualIndex switch
|
return actualIndex switch
|
||||||
{
|
{
|
||||||
< 2 => true,
|
< 2 => true,
|
||||||
< (int)ScreenActor.CutsceneStart => gameObject->OwnerId == player.EntityId,
|
< (int)ScreenActor.CutsceneStart => gameObject->OwnerId == _player.EntityId,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ICharacter> GetCharacters()
|
public IEnumerable<ICharacter> GetCharacters()
|
||||||
=> objects.Objects.OfType<ICharacter>();
|
=> objects is not null ? objects.Objects.OfType<ICharacter>() : [];
|
||||||
|
|
||||||
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
||||||
{
|
{
|
||||||
var player = objects.GetDalamudObject(0);
|
if (_player is null)
|
||||||
if (player == null)
|
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
yield return (ICharacter)player;
|
yield return (ICharacter)_player;
|
||||||
|
|
||||||
var minion = objects.GetDalamudObject(1);
|
var minion = objects!.GetDalamudObject(1);
|
||||||
if (minion != null)
|
if (minion is not null)
|
||||||
yield return (ICharacter)minion;
|
yield return (ICharacter)minion;
|
||||||
|
|
||||||
var playerId = player.EntityId;
|
var playerId = _player.EntityId;
|
||||||
for (var i = 2; i < ObjectIndex.CutsceneStart.Index; i += 2)
|
for (var i = 2; i < ObjectIndex.CutsceneStart.Index; i += 2)
|
||||||
{
|
{
|
||||||
if (objects.GetDalamudObject(i) is ICharacter owned && owned.OwnerId == playerId)
|
if (objects.GetDalamudObject(i) is ICharacter owned && owned.OwnerId == playerId)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue