mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +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,
|
||||
ActorManager actors,
|
||||
PathState pathState,
|
||||
IFramework framework,
|
||||
ModManager modManager) : IService
|
||||
{
|
||||
private static readonly string ParentDirectoryPrefix = $"..{Path.DirectorySeparatorChar}";
|
||||
|
||||
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()
|
||||
=> framework.RunOnFrameworkThread(() =>
|
||||
{
|
||||
var cache = CreateTreeBuildCache();
|
||||
return cache.GetLocalPlayerRelatedCharacters();
|
||||
}
|
||||
}).Result;
|
||||
|
||||
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromObjectTable(
|
||||
Flags flags)
|
||||
{
|
||||
var (cache, characters) = framework.RunOnFrameworkThread(() =>
|
||||
{
|
||||
var cache = CreateTreeBuildCache();
|
||||
var characters = (flags & Flags.LocalPlayerRelatedOnly) != 0 ? cache.GetLocalPlayerRelatedCharacters() : cache.GetCharacters();
|
||||
var characters = ((flags & Flags.LocalPlayerRelatedOnly) != 0 ? cache.GetLocalPlayerRelatedCharacters() : cache.GetCharacters()).ToArray();
|
||||
return (cache, characters);
|
||||
}).Result;
|
||||
|
||||
foreach (var character in characters)
|
||||
{
|
||||
|
|
@ -53,7 +64,7 @@ public class ResourceTreeFactory(
|
|||
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromCharacters(
|
||||
IEnumerable<ICharacter> characters, Flags flags)
|
||||
{
|
||||
var cache = CreateTreeBuildCache();
|
||||
var cache = CreateTreeBuildCache(flags);
|
||||
foreach (var character in characters)
|
||||
{
|
||||
var tree = FromCharacter(character, cache, flags);
|
||||
|
|
@ -63,7 +74,7 @@ public class ResourceTreeFactory(
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -80,7 +91,7 @@ public class ResourceTreeFactory(
|
|||
return null;
|
||||
|
||||
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 tree = new ResourceTree(name, anonymizedName, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related,
|
||||
networked, collectionResolveData.ModCollection.Identity.Name, collectionResolveData.ModCollection.Identity.AnonymizedName);
|
||||
|
|
@ -183,27 +194,27 @@ 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();
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private bool IsPlayerRelated(ActorIdentifier identifier, Actor owner)
|
||||
private unsafe bool IsPlayerRelated(ActorIdentifier identifier, Actor owner)
|
||||
=> identifier.Type switch
|
||||
{
|
||||
IdentifierType.Player => true,
|
||||
IdentifierType.Owned => IsPlayerRelated(objects.Objects.CreateObjectReference(owner) as ICharacter),
|
||||
IdentifierType.Owned => IsPlayerRelated(owner.AsObject),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
@ -214,5 +225,6 @@ public class ResourceTreeFactory(
|
|||
WithUiData = 2,
|
||||
LocalPlayerRelatedOnly = 4,
|
||||
WithOwnership = 8,
|
||||
PopulateObjectTableData = 16,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,15 @@ using Penumbra.String.Classes;
|
|||
|
||||
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 IGameObject? _player = objects?.GetDalamudObject(0);
|
||||
|
||||
public unsafe bool IsLocalPlayerRelated(ICharacter character)
|
||||
{
|
||||
var player = objects.GetDalamudObject(0);
|
||||
if (player == null)
|
||||
if (_player is null)
|
||||
return false;
|
||||
|
||||
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
|
||||
{
|
||||
< 2 => true,
|
||||
< (int)ScreenActor.CutsceneStart => gameObject->OwnerId == player.EntityId,
|
||||
< (int)ScreenActor.CutsceneStart => gameObject->OwnerId == _player.EntityId,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<ICharacter> GetCharacters()
|
||||
=> objects.Objects.OfType<ICharacter>();
|
||||
=> objects is not null ? objects.Objects.OfType<ICharacter>() : [];
|
||||
|
||||
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
||||
{
|
||||
var player = objects.GetDalamudObject(0);
|
||||
if (player == null)
|
||||
if (_player is null)
|
||||
yield break;
|
||||
|
||||
yield return (ICharacter)player;
|
||||
yield return (ICharacter)_player;
|
||||
|
||||
var minion = objects.GetDalamudObject(1);
|
||||
if (minion != null)
|
||||
var minion = objects!.GetDalamudObject(1);
|
||||
if (minion is not null)
|
||||
yield return (ICharacter)minion;
|
||||
|
||||
var playerId = player.EntityId;
|
||||
var playerId = _player.EntityId;
|
||||
for (var i = 2; i < ObjectIndex.CutsceneStart.Index; i += 2)
|
||||
{
|
||||
if (objects.GetDalamudObject(i) is ICharacter owned && owned.OwnerId == playerId)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue