watafak
This commit is contained in:
@@ -324,7 +324,28 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
EnsureIsOnFramework();
|
||||
playerPointer ??= GetPlayerPtr();
|
||||
if (playerPointer == IntPtr.Zero) return IntPtr.Zero;
|
||||
return _objectTable.GetObjectAddress(((GameObject*)playerPointer)->ObjectIndex + 1);
|
||||
|
||||
var playerAddress = playerPointer.Value;
|
||||
var ownerEntityId = ((Character*)playerAddress)->EntityId;
|
||||
if (ownerEntityId == 0) return IntPtr.Zero;
|
||||
|
||||
if (playerAddress == _actorObjectService.LocalPlayerAddress)
|
||||
{
|
||||
var localOwned = _actorObjectService.LocalMinionOrMountAddress;
|
||||
if (localOwned != nint.Zero)
|
||||
{
|
||||
return localOwned;
|
||||
}
|
||||
}
|
||||
|
||||
var ownedObject = FindOwnedObject(ownerEntityId, playerAddress, static kind =>
|
||||
kind == DalamudObjectKind.MountType || kind == DalamudObjectKind.Companion);
|
||||
if (ownedObject != nint.Zero)
|
||||
{
|
||||
return ownedObject;
|
||||
}
|
||||
|
||||
return _objectTable.GetObjectAddress(((GameObject*)playerAddress)->ObjectIndex + 1);
|
||||
}
|
||||
|
||||
public async Task<IntPtr> GetMinionOrMountAsync(IntPtr? playerPointer = null)
|
||||
@@ -347,6 +368,62 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
return await RunOnFrameworkThread(() => GetPetPtr(playerPointer)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private unsafe nint FindOwnedObject(uint ownerEntityId, nint ownerAddress, Func<DalamudObjectKind, bool> matchesKind)
|
||||
{
|
||||
if (ownerEntityId == 0)
|
||||
{
|
||||
return nint.Zero;
|
||||
}
|
||||
|
||||
foreach (var obj in _objectTable)
|
||||
{
|
||||
if (obj is null || obj.Address == nint.Zero || obj.Address == ownerAddress)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!matchesKind(obj.ObjectKind))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var candidate = (GameObject*)obj.Address;
|
||||
if (ResolveOwnerId(candidate) == ownerEntityId)
|
||||
{
|
||||
return obj.Address;
|
||||
}
|
||||
}
|
||||
|
||||
return nint.Zero;
|
||||
}
|
||||
|
||||
private static unsafe uint ResolveOwnerId(GameObject* gameObject)
|
||||
{
|
||||
if (gameObject == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gameObject->OwnerId != 0)
|
||||
{
|
||||
return gameObject->OwnerId;
|
||||
}
|
||||
|
||||
var character = (Character*)gameObject;
|
||||
if (character == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (character->CompanionOwnerId != 0)
|
||||
{
|
||||
return character->CompanionOwnerId;
|
||||
}
|
||||
|
||||
var parent = character->GetParentCharacter();
|
||||
return parent != null ? parent->EntityId : 0;
|
||||
}
|
||||
|
||||
public async Task<IPlayerCharacter> GetPlayerCharacterAsync()
|
||||
{
|
||||
return await RunOnFrameworkThread(GetPlayerCharacter).ConfigureAwait(false);
|
||||
@@ -393,6 +470,24 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
return await RunOnFrameworkThread(() => _cid.Value.ToString().GetHash256()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static unsafe bool TryGetHashedCID(IPlayerCharacter? playerCharacter, out string hashedCid)
|
||||
{
|
||||
hashedCid = string.Empty;
|
||||
if (playerCharacter == null)
|
||||
return false;
|
||||
|
||||
var address = playerCharacter.Address;
|
||||
if (address == nint.Zero)
|
||||
return false;
|
||||
|
||||
var cid = ((BattleChara*)address)->Character.ContentId;
|
||||
if (cid == 0)
|
||||
return false;
|
||||
|
||||
hashedCid = cid.ToString().GetHash256();
|
||||
return true;
|
||||
}
|
||||
|
||||
public unsafe static string GetHashedCIDFromPlayerPointer(nint ptr)
|
||||
{
|
||||
return ((BattleChara*)ptr)->Character.ContentId.ToString().GetHash256();
|
||||
@@ -516,17 +611,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
var fileName = Path.GetFileNameWithoutExtension(callerFilePath);
|
||||
await _performanceCollector.LogPerformance(this, $"RunOnFramework:Act/{fileName}>{callerMember}:{callerLineNumber}", async () =>
|
||||
{
|
||||
if (!_framework.IsInFrameworkUpdateThread)
|
||||
if (_framework.IsInFrameworkUpdateThread)
|
||||
{
|
||||
await _framework.RunOnFrameworkThread(act).ContinueWith((_) => Task.CompletedTask).ConfigureAwait(false);
|
||||
while (_framework.IsInFrameworkUpdateThread) // yield the thread again, should technically never be triggered
|
||||
{
|
||||
_logger.LogTrace("Still on framework");
|
||||
await Task.Delay(1).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
act();
|
||||
return;
|
||||
}
|
||||
|
||||
await _framework.RunOnFrameworkThread(act).ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -535,18 +626,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
var fileName = Path.GetFileNameWithoutExtension(callerFilePath);
|
||||
return await _performanceCollector.LogPerformance(this, $"RunOnFramework:Func<{typeof(T)}>/{fileName}>{callerMember}:{callerLineNumber}", async () =>
|
||||
{
|
||||
if (!_framework.IsInFrameworkUpdateThread)
|
||||
if (_framework.IsInFrameworkUpdateThread)
|
||||
{
|
||||
var result = await _framework.RunOnFrameworkThread(func).ContinueWith((task) => task.Result).ConfigureAwait(false);
|
||||
while (_framework.IsInFrameworkUpdateThread) // yield the thread again, should technically never be triggered
|
||||
{
|
||||
_logger.LogTrace("Still on framework");
|
||||
await Task.Delay(1).ConfigureAwait(false);
|
||||
}
|
||||
return result;
|
||||
return func.Invoke();
|
||||
}
|
||||
|
||||
return func.Invoke();
|
||||
return await _framework.RunOnFrameworkThread(func).ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user