idk
This commit is contained in:
@@ -660,7 +660,15 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
if (!fireAndForget)
|
if (!fireAndForget)
|
||||||
{
|
{
|
||||||
await _dalamudUtil.RunOnFrameworkThread(action).ConfigureAwait(false);
|
while (!await _dalamudUtil.RunOnFrameworkThread(() =>
|
||||||
|
{
|
||||||
|
if (obj.IsBeingDrawn()) return false;
|
||||||
|
action();
|
||||||
|
return true;
|
||||||
|
}).ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
await Task.Delay(250).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(1), _disposalCts.Token).ConfigureAwait(false);
|
await Task.Delay(TimeSpan.FromSeconds(1), _disposalCts.Token).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,6 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
public IntPtr Address { get; set; }
|
public IntPtr Address { get; set; }
|
||||||
public unsafe Character* Character => (Character*)Address;
|
public unsafe Character* Character => (Character*)Address;
|
||||||
public Lazy<Dalamud.Game.ClientState.Objects.Types.GameObject?> GameObjectLazy { get; private set; }
|
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
|
|
||||||
public ObjectKind ObjectKind { get; }
|
public ObjectKind ObjectKind { get; }
|
||||||
@@ -101,22 +99,33 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
return await _dalamudUtil.RunOnFrameworkThread(_getAddress.Invoke).ConfigureAwait(true);
|
return await _dalamudUtil.RunOnFrameworkThread(_getAddress.Invoke).ConfigureAwait(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Dalamud.Game.ClientState.Objects.Types.GameObject?> GetGameObject()
|
||||||
|
{
|
||||||
|
return await _dalamudUtil.CreateGameObject(Address).ConfigureAwait(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsBeingDrawn()
|
||||||
|
{
|
||||||
|
var curPtr = _getAddress();
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, CurPtr: {ptr}", this, curPtr.ToString("X"));
|
||||||
|
|
||||||
|
if (curPtr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, CurPtr is ZERO, returning", this);
|
||||||
|
|
||||||
|
Address = IntPtr.Zero;
|
||||||
|
DrawObjectAddress = IntPtr.Zero;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var drawObj = GetDrawObj(curPtr);
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, DrawObjPtr: {ptr}", this, drawObj.ToString("X"));
|
||||||
|
return IsBeingDrawn(drawObj, curPtr);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> IsBeingDrawnRunOnFramework()
|
public async Task<bool> IsBeingDrawnRunOnFramework()
|
||||||
{
|
{
|
||||||
return await _dalamudUtil.RunOnFrameworkThread(() =>
|
return await _dalamudUtil.RunOnFrameworkThread(IsBeingDrawn).ConfigureAwait(false);
|
||||||
{
|
|
||||||
var curPtr = _getAddress.Invoke();
|
|
||||||
|
|
||||||
if (curPtr == IntPtr.Zero)
|
|
||||||
{
|
|
||||||
Address = IntPtr.Zero;
|
|
||||||
DrawObjectAddress = IntPtr.Zero;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var drawObj = GetDrawObj(curPtr);
|
|
||||||
return IsBeingDrawn(drawObj, curPtr);
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@@ -137,23 +146,24 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
if (_haltProcessing) return;
|
if (_haltProcessing) return;
|
||||||
|
|
||||||
var curPtr = CurrentAddress().GetAwaiter().GetResult();
|
var prevAddr = Address;
|
||||||
bool drawObjDiff = false;
|
var prevDrawObj = DrawObjectAddress;
|
||||||
try
|
|
||||||
|
Address = _getAddress();
|
||||||
|
if (Address != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
if (curPtr != IntPtr.Zero)
|
var drawObjAddr = (IntPtr)((GameObject*)Address)->DrawObject;
|
||||||
{
|
DrawObjectAddress = drawObjAddr;
|
||||||
var drawObjAddr = (IntPtr)((GameObject*)curPtr)->DrawObject;
|
|
||||||
drawObjDiff = drawObjAddr != DrawObjectAddress;
|
|
||||||
DrawObjectAddress = drawObjAddr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Error during checking for draw object for {name}", this);
|
DrawObjectAddress = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curPtr != IntPtr.Zero && DrawObjectAddress != IntPtr.Zero)
|
bool drawObjDiff = DrawObjectAddress != prevDrawObj;
|
||||||
|
bool addrDiff = Address != prevAddr;
|
||||||
|
|
||||||
|
if (Address != IntPtr.Zero && DrawObjectAddress != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
if (_clearCts != null)
|
if (_clearCts != null)
|
||||||
{
|
{
|
||||||
@@ -161,13 +171,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
_clearCts?.Cancel();
|
_clearCts?.Cancel();
|
||||||
_clearCts = null;
|
_clearCts = null;
|
||||||
}
|
}
|
||||||
bool addrDiff = Address != curPtr;
|
var chara = (Character*)Address;
|
||||||
Address = curPtr;
|
|
||||||
if (addrDiff)
|
|
||||||
{
|
|
||||||
GameObjectLazy = new(() => _dalamudUtil.CreateGameObject(curPtr).GetAwaiter().GetResult());
|
|
||||||
}
|
|
||||||
var chara = (Character*)curPtr;
|
|
||||||
var name = new ByteString(chara->GameObject.Name).ToString();
|
var name = new ByteString(chara->GameObject.Name).ToString();
|
||||||
bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal);
|
bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal);
|
||||||
Name = name;
|
Name = name;
|
||||||
@@ -181,19 +185,15 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
var customizeDiff = CompareAndUpdateCustomizeData(chara->CustomizeData);
|
var customizeDiff = CompareAndUpdateCustomizeData(chara->CustomizeData);
|
||||||
|
|
||||||
if ((addrDiff || equipDiff || customizeDiff || drawObjDiff || nameChange) && _isOwnedObject)
|
if ((addrDiff || drawObjDiff || equipDiff || customizeDiff || nameChange) && _isOwnedObject)
|
||||||
{
|
{
|
||||||
Logger.LogTrace("[{this}] Changed", this);
|
Logger.LogDebug("[{this}] Changed, Sending CreateCacheObjectMessage", this);
|
||||||
|
|
||||||
Logger.LogDebug("[{this}] Sending CreateCacheObjectMessage", this);
|
|
||||||
Mediator.Publish(new CreateCacheForObjectMessage(this));
|
Mediator.Publish(new CreateCacheForObjectMessage(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Address != IntPtr.Zero || DrawObjectAddress != IntPtr.Zero)
|
else if (addrDiff || drawObjDiff)
|
||||||
{
|
{
|
||||||
Address = IntPtr.Zero;
|
Logger.LogTrace("[{this}] Changed", this);
|
||||||
DrawObjectAddress = IntPtr.Zero;
|
|
||||||
Logger.LogTrace("[{this}] Changed -> Null", this);
|
|
||||||
if (_isOwnedObject && ObjectKind != ObjectKind.Player)
|
if (_isOwnedObject && ObjectKind != ObjectKind.Player)
|
||||||
{
|
{
|
||||||
_clearCts?.Cancel();
|
_clearCts?.Cancel();
|
||||||
@@ -264,18 +264,29 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
private unsafe IntPtr GetDrawObj(nint curPtr)
|
private unsafe IntPtr GetDrawObj(nint curPtr)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Getting new DrawObject", this);
|
||||||
return (IntPtr)((GameObject*)curPtr)->DrawObject;
|
return (IntPtr)((GameObject*)curPtr)->DrawObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe bool IsBeingDrawn(IntPtr drawObj, IntPtr curPtr)
|
private unsafe bool IsBeingDrawn(IntPtr drawObj, IntPtr curPtr)
|
||||||
{
|
{
|
||||||
Logger.LogTrace("IsBeingDrawn for {kind} ptr {curPtr} : {drawObj}", ObjectKind, curPtr.ToString("X"), drawObj.ToString("X"));
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Checking IsBeingDrawn for Ptr {curPtr} : DrawObj {drawObj}", this, curPtr.ToString("X"), drawObj.ToString("X"));
|
||||||
if (ObjectKind == ObjectKind.Player)
|
if (ObjectKind == ObjectKind.Player)
|
||||||
{
|
{
|
||||||
return drawObj == IntPtr.Zero
|
var drawObjZero = drawObj == IntPtr.Zero;
|
||||||
|| (((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0)
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition IsDrawObjZero: {cond}", this, drawObjZero);
|
||||||
|| (((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0)
|
if (drawObjZero) return true;
|
||||||
|| (((GameObject*)curPtr)->RenderFlags & 0b100000000000) == 0b100000000000;
|
var renderFlags = (((GameObject*)curPtr)->RenderFlags) != 0x0;
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition RenderFlags: {cond}", this, renderFlags);
|
||||||
|
if (renderFlags) return true;
|
||||||
|
var modelInSlotLoaded = (((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0);
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition ModelInSlotLoaded: {cond}", this, modelInSlotLoaded);
|
||||||
|
if (modelInSlotLoaded) return true;
|
||||||
|
var modelFilesInSlotLoaded = (((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0);
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Condition ModelFilesInSlotLoaded: {cond}", this, modelFilesInSlotLoaded);
|
||||||
|
if (modelFilesInSlotLoaded) return true;
|
||||||
|
Logger.LogTrace("[{this}] IsBeingDrawnRunOnFramework, Is not being drawn", this);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return drawObj == IntPtr.Zero
|
return drawObj == IntPtr.Zero
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
Logger.LogDebug("Downloading and applying character for {name}", this);
|
Logger.LogDebug("Downloading and applying character for {name}", this);
|
||||||
|
|
||||||
DownloadAndApplyCharacter(characterData, charaDataToUpdate);
|
DownloadAndApplyCharacter(characterData.DeepClone(), charaDataToUpdate);
|
||||||
|
|
||||||
_cachedData = characterData;
|
_cachedData = characterData;
|
||||||
}
|
}
|
||||||
@@ -203,10 +203,12 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
private async Task ApplyBaseData(Guid applicationId, Dictionary<string, string> moddedPaths, string manipulationData, CancellationToken token)
|
private async Task ApplyBaseData(Guid applicationId, Dictionary<string, string> moddedPaths, string manipulationData, CancellationToken token)
|
||||||
{
|
{
|
||||||
await _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!).ConfigureAwait(false);
|
await _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!).ConfigureAwait(true);
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
var objTableIndex = await _dalamudUtil.RunOnFrameworkThread(() => _charaHandler!.GameObjectLazy!.Value.ObjectTableIndex()).ConfigureAwait(false);
|
var gameObj = await _charaHandler!.GetGameObject().ConfigureAwait(true);
|
||||||
await _ipcManager.PenumbraSetTemporaryMods(Logger, applicationId, PlayerName!, objTableIndex, moddedPaths, manipulationData).ConfigureAwait(false);
|
if (gameObj == null) return;
|
||||||
|
var objTableIndex = await _dalamudUtil.RunOnFrameworkThread(() => gameObj.ObjectTableIndex()).ConfigureAwait(true);
|
||||||
|
await _ipcManager.PenumbraSetTemporaryMods(Logger, applicationId, PlayerName!, objTableIndex, moddedPaths, manipulationData).ConfigureAwait(true);
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,16 +445,26 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_applicationId = Guid.NewGuid();
|
_applicationId = Guid.NewGuid();
|
||||||
Logger.LogDebug("[{applicationId}] Starting application task", _applicationId);
|
Logger.LogDebug("[{applicationId}] Starting application task for {this}", _applicationId, this);
|
||||||
|
|
||||||
Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler);
|
Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler);
|
||||||
await _dalamudUtil.WaitWhileCharacterIsDrawing(Logger, _charaHandler!, _applicationId, 30000, token).ConfigureAwait(false);
|
await _dalamudUtil.WaitWhileCharacterIsDrawing(Logger, _charaHandler!, _applicationId, 30000, token).ConfigureAwait(false);
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var applyBaseData = new Action(() => ApplyBaseData(_applicationId, moddedPaths, charaData.ManipulationData, token).ConfigureAwait(true).GetAwaiter().GetResult());
|
||||||
|
|
||||||
if (updateModdedPaths && (moddedPaths.Any() || !string.IsNullOrEmpty(charaData.ManipulationData)))
|
if (updateModdedPaths && (moddedPaths.Any() || !string.IsNullOrEmpty(charaData.ManipulationData)))
|
||||||
{
|
{
|
||||||
await ApplyBaseData(_applicationId, moddedPaths, charaData.ManipulationData, token).ConfigureAwait(false);
|
while (!await _dalamudUtil.RunOnFrameworkThread(() =>
|
||||||
|
{
|
||||||
|
if (_charaHandler!.IsBeingDrawn()) return false;
|
||||||
|
applyBaseData();
|
||||||
|
return true;
|
||||||
|
}).ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
await Task.Delay(250, token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ public class DalamudUtilService : IHostedService
|
|||||||
{
|
{
|
||||||
while ((!ct?.IsCancellationRequested ?? true)
|
while ((!ct?.IsCancellationRequested ?? true)
|
||||||
&& curWaitTime < timeOut
|
&& curWaitTime < timeOut
|
||||||
&& await handler.IsBeingDrawnRunOnFramework().ConfigureAwait(true)) // 0b100000000000 is "still rendering" or something
|
&& await handler.IsBeingDrawnRunOnFramework().ConfigureAwait(false)) // 0b100000000000 is "still rendering" or something
|
||||||
{
|
{
|
||||||
logger.LogTrace("[{redrawId}] Waiting for {handler} to finish drawing", redrawId, handler);
|
logger.LogTrace("[{redrawId}] Waiting for {handler} to finish drawing", redrawId, handler);
|
||||||
curWaitTime += tick;
|
curWaitTime += tick;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public record PenumbraResourceLoadMessage(IntPtr GameObject, string GamePath, st
|
|||||||
public record CustomizePlusMessage : MessageBase;
|
public record CustomizePlusMessage : MessageBase;
|
||||||
public record PalettePlusMessage(Character Character) : MessageBase;
|
public record PalettePlusMessage(Character Character) : MessageBase;
|
||||||
public record HonorificMessage(string NewHonorificTitle) : MessageBase;
|
public record HonorificMessage(string NewHonorificTitle) : MessageBase;
|
||||||
public record PlayerChangedMessage(API.Data.CharacterData Data) : MessageBase;
|
public record PlayerChangedMessage(CharacterData Data) : MessageBase;
|
||||||
public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : MessageBase;
|
public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : MessageBase;
|
||||||
public record TransientResourceChangedMessage(IntPtr Address) : MessageBase;
|
public record TransientResourceChangedMessage(IntPtr Address) : MessageBase;
|
||||||
public record AddWatchedGameObjectHandler(GameObjectHandler Handler) : MessageBase;
|
public record AddWatchedGameObjectHandler(GameObjectHandler Handler) : MessageBase;
|
||||||
@@ -47,7 +47,7 @@ public record NotificationMessage
|
|||||||
(string Title, string Message, NotificationType Type, uint TimeShownOnScreen = 3000) : MessageBase;
|
(string Title, string Message, NotificationType Type, uint TimeShownOnScreen = 3000) : MessageBase;
|
||||||
public record CreateCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) : MessageBase;
|
public record CreateCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) : MessageBase;
|
||||||
public record ClearCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) : MessageBase;
|
public record ClearCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) : MessageBase;
|
||||||
public record CharacterDataCreatedMessage(API.Data.CharacterData CharacterData) : MessageBase;
|
public record CharacterDataCreatedMessage(CharacterData CharacterData) : SameThreadMessage;
|
||||||
public record PenumbraStartRedrawMessage(IntPtr Address) : MessageBase;
|
public record PenumbraStartRedrawMessage(IntPtr Address) : MessageBase;
|
||||||
public record PenumbraEndRedrawMessage(IntPtr Address) : MessageBase;
|
public record PenumbraEndRedrawMessage(IntPtr Address) : MessageBase;
|
||||||
public record HubReconnectingMessage(Exception? Exception) : MessageBase;
|
public record HubReconnectingMessage(Exception? Exception) : MessageBase;
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public sealed class PerformanceCollectorService : IHostedService
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(e, "Error removing performance counter {counter}", entries.Key);
|
_logger.LogWarning(e, "Error removing performance counter {counter}", entries.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
foreach (var transfer in _currentDownloads.ToList())
|
foreach (var transfer in _currentDownloads.ToList())
|
||||||
{
|
{
|
||||||
var screenPos = _dalamudUtilService.WorldToScreen(transfer.Key.GameObjectLazy.Value);
|
var screenPos = _dalamudUtilService.WorldToScreen(transfer.Key.GetGameObject().ConfigureAwait(true).GetAwaiter().GetResult());
|
||||||
if (screenPos == Vector2.Zero) continue;
|
if (screenPos == Vector2.Zero) continue;
|
||||||
|
|
||||||
var totalBytes = transfer.Value.Sum(c => c.Value.TotalBytes);
|
var totalBytes = transfer.Value.Sum(c => c.Value.TotalBytes);
|
||||||
@@ -182,7 +182,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
foreach (var player in _uploadingPlayers.Select(p => p.Key).ToList())
|
foreach (var player in _uploadingPlayers.Select(p => p.Key).ToList())
|
||||||
{
|
{
|
||||||
var screenPos = _dalamudUtilService.WorldToScreen(player.GameObjectLazy.Value);
|
var screenPos = _dalamudUtilService.WorldToScreen(player.GetGameObject().GetAwaiter().GetResult());
|
||||||
if (screenPos == Vector2.Zero) continue;
|
if (screenPos == Vector2.Zero) continue;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user