fix glamourer not applying on zone changes for previously visible players

This commit is contained in:
rootdarkarchon
2023-05-07 17:40:41 +02:00
parent 186e70d0cf
commit 5d6df09779
2 changed files with 33 additions and 28 deletions

View File

@@ -85,6 +85,15 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
_dalamudUtil.RunOnFrameworkThread(CheckAndUpdateObject).GetAwaiter().GetResult(); _dalamudUtil.RunOnFrameworkThread(CheckAndUpdateObject).GetAwaiter().GetResult();
} }
private enum DrawCondition
{
None,
DrawObjectZero,
RenderFlags,
ModelInSlotLoaded,
ModelFilesInSlotLoaded
}
public IntPtr Address { get; private set; } public IntPtr Address { get; private set; }
public string Name { get; private set; } public string Name { get; private set; }
public ObjectKind ObjectKind { get; } public ObjectKind ObjectKind { get; }
@@ -265,20 +274,19 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
} }
} }
private unsafe IntPtr GetDrawObj(nint curPtr) private unsafe IntPtr GetDrawObjUnsafe(nint curPtr)
{ {
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Getting new DrawObject", this);
return (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->DrawObject; return (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->DrawObject;
} }
private bool IsBeingDrawn() private bool IsBeingDrawn()
{ {
var curPtr = _getAddress(); var curPtr = _getAddress();
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, CurPtr: {ptr}", this, curPtr.ToString("X")); Logger.LogTrace("[{this}] IsBeingDrawn, CurPtr: {ptr}", this, curPtr.ToString("X"));
if (curPtr == IntPtr.Zero) if (curPtr == IntPtr.Zero)
{ {
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, CurPtr is ZERO, returning", this); Logger.LogTrace("[{this}] IsBeingDrawn, CurPtr is ZERO, returning", this);
Address = IntPtr.Zero; Address = IntPtr.Zero;
DrawObjectAddress = IntPtr.Zero; DrawObjectAddress = IntPtr.Zero;
@@ -287,38 +295,34 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
if (_dalamudUtil.IsAnythingDrawing) if (_dalamudUtil.IsAnythingDrawing)
{ {
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Global draw block", this); Logger.LogTrace("[{this}] IsBeingDrawn, Global draw block", this);
return true; return true;
} }
var drawObj = GetDrawObj(curPtr); var drawObj = GetDrawObjUnsafe(curPtr);
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, DrawObjPtr: {ptr}", this, drawObj.ToString("X")); Logger.LogTrace("[{this}] IsBeingDrawn, DrawObjPtr: {ptr}", this, drawObj.ToString("X"));
return IsBeingDrawn(drawObj, curPtr); var isDrawn = IsBeingDrawnUnsafe(drawObj, curPtr);
Logger.LogTrace("[{this}] IsBeingDrawn, Condition: {cond}", this, isDrawn);
return isDrawn != DrawCondition.None;
} }
private unsafe bool IsBeingDrawn(IntPtr drawObj, IntPtr curPtr) private unsafe DrawCondition IsBeingDrawnUnsafe(IntPtr drawObj, IntPtr curPtr)
{ {
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Checking IsBeingDrawn for Ptr {curPtr} : DrawObj {drawObj}", this, curPtr.ToString("X"), drawObj.ToString("X")); var drawObjZero = drawObj == IntPtr.Zero;
if (drawObjZero) return DrawCondition.DrawObjectZero;
var renderFlags = (((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->RenderFlags) != 0x0;
if (renderFlags) return DrawCondition.RenderFlags;
if (ObjectKind == ObjectKind.Player) if (ObjectKind == ObjectKind.Player)
{ {
var drawObjZero = drawObj == IntPtr.Zero;
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition IsDrawObjZero: {cond}", this, drawObjZero);
if (drawObjZero) return true;
var renderFlags = (((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->RenderFlags) != 0x0;
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition RenderFlags: {cond}", this, renderFlags);
if (renderFlags) return true;
var modelInSlotLoaded = (((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0); var modelInSlotLoaded = (((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0);
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition ModelInSlotLoaded: {cond}", this, modelInSlotLoaded); if (modelInSlotLoaded) return DrawCondition.ModelInSlotLoaded;
if (modelInSlotLoaded) return true;
var modelFilesInSlotLoaded = (((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0); var modelFilesInSlotLoaded = (((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0);
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition ModelFilesInSlotLoaded: {cond}", this, modelFilesInSlotLoaded); if (modelFilesInSlotLoaded) return DrawCondition.ModelFilesInSlotLoaded;
if (modelFilesInSlotLoaded) return true; return DrawCondition.None;
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Is not being drawn", this);
return false;
} }
return drawObj == IntPtr.Zero return DrawCondition.None;
|| ((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->RenderFlags != 0x0;
} }
private void ZoneSwitchEnd() private void ZoneSwitchEnd()

View File

@@ -35,12 +35,12 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
private CharacterData? _cachedData = null; private CharacterData? _cachedData = null;
private GameObjectHandler? _charaHandler; private GameObjectHandler? _charaHandler;
private CancellationTokenSource? _downloadCancellationTokenSource = new(); private CancellationTokenSource? _downloadCancellationTokenSource = new();
private CharacterData? _firstTimeInitData;
private int _framesSinceNotVisible = 0; private int _framesSinceNotVisible = 0;
private string _lastGlamourerData = string.Empty; private string _lastGlamourerData = string.Empty;
private string _originalGlamourerData = string.Empty; private string _originalGlamourerData = string.Empty;
private CancellationTokenSource _redrawCts = new();
private string _penumbraCollection; private string _penumbraCollection;
private CharacterData? _firstTimeInitData; private CancellationTokenSource _redrawCts = new();
public CachedPlayer(ILogger<CachedPlayer> logger, OnlineUserIdentDto onlineUser, public CachedPlayer(ILogger<CachedPlayer> logger, OnlineUserIdentDto onlineUser,
GameObjectHandlerFactory gameObjectHandlerFactory, GameObjectHandlerFactory gameObjectHandlerFactory,
@@ -275,6 +275,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
await _ipcManager.GlamourerApplyAllAsync(Logger, handler, glamourerData, applicationId, token).ConfigureAwait(false); await _ipcManager.GlamourerApplyAllAsync(Logger, handler, glamourerData, applicationId, token).ConfigureAwait(false);
} }
break; break;
case PlayerChanges.ModFiles: case PlayerChanges.ModFiles:
case PlayerChanges.ModManip: case PlayerChanges.ModManip:
if (!changes.Value.Contains(PlayerChanges.Glamourer)) if (!changes.Value.Contains(PlayerChanges.Glamourer))
@@ -516,12 +517,12 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
Mediator.Publish(new CachedPlayerVisibleMessage(this)); Mediator.Publish(new CachedPlayerVisibleMessage(this));
Logger.LogTrace("{this} visibility changed, now: {visi}", this, IsVisible); Logger.LogTrace("{this} visibility changed, now: {visi}", this, IsVisible);
_framesSinceNotVisible = 0; _framesSinceNotVisible = 0;
if (_firstTimeInitData != null) if (_firstTimeInitData != null || _cachedData != null)
{ {
Task.Run(async () => Task.Run(async () =>
{ {
_lastGlamourerData = await _ipcManager.GlamourerGetCharacterCustomizationAsync(PlayerCharacter).ConfigureAwait(false); _lastGlamourerData = await _ipcManager.GlamourerGetCharacterCustomizationAsync(PlayerCharacter).ConfigureAwait(false);
ApplyCharacterData(_firstTimeInitData, true); ApplyCharacterData(_firstTimeInitData ?? _cachedData!, true);
}); });
} }
} }