Added documentation, support of log out and log on added.
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
using LightlessSync.Services;
|
using LightlessSync.Services;
|
||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using ObjectKind = LightlessSync.API.Data.Enum.ObjectKind;
|
using ObjectKind = LightlessSync.API.Data.Enum.ObjectKind;
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
|
||||||
using Dalamud.Plugin.Services;
|
|
||||||
|
|
||||||
namespace LightlessSync.PlayerData.Handlers;
|
namespace LightlessSync.PlayerData.Handlers;
|
||||||
|
|
||||||
@@ -15,30 +15,51 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
private readonly Func<IntPtr> _getAddress;
|
private readonly Func<IntPtr> _getAddress;
|
||||||
private readonly bool _isOwnedObject;
|
private readonly bool _isOwnedObject;
|
||||||
private readonly PerformanceCollectorService _performanceCollector;
|
private readonly PerformanceCollectorService _performanceCollector;
|
||||||
private readonly object _frameworkUpdateGate = new();
|
private readonly Lock _frameworkUpdateGate = new();
|
||||||
private bool _frameworkUpdateSubscribed;
|
private bool _frameworkUpdateSubscribed;
|
||||||
private byte _classJob = 0;
|
private byte _classJob = 0;
|
||||||
private Task? _delayedZoningTask;
|
private Task? _delayedZoningTask;
|
||||||
private bool _haltProcessing = false;
|
private bool _haltProcessing = false;
|
||||||
private CancellationTokenSource _zoningCts = new();
|
private CancellationTokenSource _zoningCts = new();
|
||||||
|
|
||||||
public GameObjectHandler(ILogger<GameObjectHandler> logger, PerformanceCollectorService performanceCollector,
|
/// <summary>
|
||||||
LightlessMediator mediator, DalamudUtilService dalamudUtil, ObjectKind objectKind, Func<IntPtr> getAddress, IObjectTable objectTable, bool ownedObject = true) : base(logger, mediator)
|
/// Constructor for GameObjectHandler
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Logger</param>
|
||||||
|
/// <param name="performanceCollector">Performance Collector</param>
|
||||||
|
/// <param name="mediator">Lightless Mediator</param>
|
||||||
|
/// <param name="dalamudUtil">Dalamud Utilties Service</param>
|
||||||
|
/// <param name="objectKind">Object kind of Object</param>
|
||||||
|
/// <param name="getAddress">Get Adress</param>
|
||||||
|
/// <param name="objectTable">Object table of Dalamud</param>
|
||||||
|
/// <param name="ownedObject">Object is owned by user</param>
|
||||||
|
public GameObjectHandler(
|
||||||
|
ILogger<GameObjectHandler> logger,
|
||||||
|
PerformanceCollectorService performanceCollector,
|
||||||
|
LightlessMediator mediator,
|
||||||
|
DalamudUtilService dalamudUtil,
|
||||||
|
ObjectKind objectKind,
|
||||||
|
Func<IntPtr> getAddress,
|
||||||
|
IObjectTable objectTable,
|
||||||
|
bool ownedObject = true) : base(logger, mediator)
|
||||||
{
|
{
|
||||||
_performanceCollector = performanceCollector;
|
_performanceCollector = performanceCollector;
|
||||||
ObjectKind = objectKind;
|
ObjectKind = objectKind;
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
|
_objectTable = objectTable;
|
||||||
|
|
||||||
_getAddress = () =>
|
_getAddress = () =>
|
||||||
{
|
{
|
||||||
_dalamudUtil.EnsureIsOnFramework();
|
_dalamudUtil.EnsureIsOnFramework();
|
||||||
return getAddress.Invoke();
|
return getAddress.Invoke();
|
||||||
};
|
};
|
||||||
|
|
||||||
_isOwnedObject = ownedObject;
|
_isOwnedObject = ownedObject;
|
||||||
Name = string.Empty;
|
Name = string.Empty;
|
||||||
|
|
||||||
if (ownedObject)
|
if (ownedObject)
|
||||||
{
|
{
|
||||||
Mediator.Subscribe<TransientResourceChangedMessage>(this, (msg) =>
|
Mediator.Subscribe<TransientResourceChangedMessage>(this, msg =>
|
||||||
{
|
{
|
||||||
if (_delayedZoningTask?.IsCompleted ?? true)
|
if (_delayedZoningTask?.IsCompleted ?? true)
|
||||||
{
|
{
|
||||||
@@ -48,44 +69,36 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isOwnedObject)
|
EnableFrameworkUpdates();
|
||||||
{
|
|
||||||
EnableFrameworkUpdates();
|
|
||||||
}
|
|
||||||
|
|
||||||
Mediator.Subscribe<ZoneSwitchEndMessage>(this, (_) => ZoneSwitchEnd());
|
Mediator.Subscribe<ZoneSwitchEndMessage>(this, _ => ZoneSwitchEnd());
|
||||||
Mediator.Subscribe<ZoneSwitchStartMessage>(this, (_) => ZoneSwitchStart());
|
Mediator.Subscribe<ZoneSwitchStartMessage>(this, _ => ZoneSwitchStart());
|
||||||
|
|
||||||
Mediator.Subscribe<CutsceneStartMessage>(this, (_) =>
|
Mediator.Subscribe<CutsceneStartMessage>(this, _ => _haltProcessing = true);
|
||||||
{
|
Mediator.Subscribe<CutsceneEndMessage>(this, _ =>
|
||||||
_haltProcessing = true;
|
|
||||||
});
|
|
||||||
Mediator.Subscribe<CutsceneEndMessage>(this, (_) =>
|
|
||||||
{
|
{
|
||||||
_haltProcessing = false;
|
_haltProcessing = false;
|
||||||
ZoneSwitchEnd();
|
ZoneSwitchEnd();
|
||||||
});
|
});
|
||||||
Mediator.Subscribe<PenumbraStartRedrawMessage>(this, (msg) =>
|
|
||||||
|
Mediator.Subscribe<PenumbraStartRedrawMessage>(this, msg =>
|
||||||
{
|
{
|
||||||
if (msg.Address == Address)
|
if (msg.Address == Address) _haltProcessing = true;
|
||||||
{
|
|
||||||
_haltProcessing = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
Mediator.Subscribe<PenumbraEndRedrawMessage>(this, (msg) =>
|
Mediator.Subscribe<PenumbraEndRedrawMessage>(this, msg =>
|
||||||
{
|
{
|
||||||
if (msg.Address == Address)
|
if (msg.Address == Address) _haltProcessing = false;
|
||||||
{
|
|
||||||
_haltProcessing = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Mediator.Publish(new GameObjectHandlerCreatedMessage(this, _isOwnedObject));
|
Mediator.Publish(new GameObjectHandlerCreatedMessage(this, _isOwnedObject));
|
||||||
_objectTable = objectTable;
|
|
||||||
|
|
||||||
_dalamudUtil.RunOnFrameworkThread(CheckAndUpdateObject).GetAwaiter().GetResult();
|
_dalamudUtil.EnsureIsOnFramework();
|
||||||
|
CheckAndUpdateObject(allowPublish: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw Condition Enum
|
||||||
|
/// </summary>
|
||||||
public enum DrawCondition
|
public enum DrawCondition
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
@@ -96,6 +109,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
ModelFilesInSlotLoaded
|
ModelFilesInSlotLoaded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Properties
|
||||||
public IntPtr Address { get; private set; }
|
public IntPtr Address { get; private set; }
|
||||||
public DrawCondition CurrentDrawCondition { get; set; } = DrawCondition.None;
|
public DrawCondition CurrentDrawCondition { get; set; } = DrawCondition.None;
|
||||||
public byte Gender { get; private set; }
|
public byte Gender { get; private set; }
|
||||||
@@ -106,10 +120,13 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
public byte TribeId { get; private set; }
|
public byte TribeId { get; private set; }
|
||||||
private byte[] CustomizeData { get; set; } = new byte[26];
|
private byte[] CustomizeData { get; set; } = new byte[26];
|
||||||
private IntPtr DrawObjectAddress { get; set; }
|
private IntPtr DrawObjectAddress { get; set; }
|
||||||
private byte[] EquipSlotData { get; set; } = new byte[40];
|
|
||||||
private ushort[] MainHandData { get; set; } = new ushort[3];
|
|
||||||
private ushort[] OffHandData { get; set; } = new ushort[3];
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Act on framework thread after ensuring no draw condition
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="act">Action of Character</param>
|
||||||
|
/// <param name="token">Cancellation Token</param>
|
||||||
|
/// <returns>Task Completion</returns>
|
||||||
public async Task ActOnFrameworkAfterEnsureNoDrawAsync(Action<ICharacter> act, CancellationToken token)
|
public async Task ActOnFrameworkAfterEnsureNoDrawAsync(Action<ICharacter> act, CancellationToken token)
|
||||||
{
|
{
|
||||||
while (await _dalamudUtil.RunOnFrameworkThread(() =>
|
while (await _dalamudUtil.RunOnFrameworkThread(() =>
|
||||||
@@ -128,6 +145,11 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compare Name And Throw if not equal
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name that will be compared to Object Handler.</param>
|
||||||
|
/// <exception cref="InvalidOperationException">Not equal if thrown</exception>
|
||||||
public void CompareNameAndThrow(string name)
|
public void CompareNameAndThrow(string name)
|
||||||
{
|
{
|
||||||
if (!string.Equals(Name, name, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(Name, name, StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -140,11 +162,18 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IGameObject? GetGameObject()
|
/// <summary>
|
||||||
|
/// Gets the game object from the address
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Gane object</returns>
|
||||||
|
public IGameObject? GetGameObject()
|
||||||
{
|
{
|
||||||
return _dalamudUtil.CreateGameObject(Address);
|
return _dalamudUtil.CreateGameObject(Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalidate the object handler
|
||||||
|
/// </summary>
|
||||||
public void Invalidate()
|
public void Invalidate()
|
||||||
{
|
{
|
||||||
Address = IntPtr.Zero;
|
Address = IntPtr.Zero;
|
||||||
@@ -153,26 +182,43 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
_haltProcessing = false;
|
_haltProcessing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Refresh the object handler state
|
||||||
|
/// </summary>
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
_dalamudUtil.RunOnFrameworkThread(CheckAndUpdateObject).GetAwaiter().GetResult();
|
_dalamudUtil.RunOnFrameworkThread(CheckAndUpdateObject).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is Being Drawn Run On Framework Asyncronously
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Object is being run in framework</returns>
|
||||||
public async Task<bool> IsBeingDrawnRunOnFrameworkAsync()
|
public async Task<bool> IsBeingDrawnRunOnFrameworkAsync()
|
||||||
{
|
{
|
||||||
return await _dalamudUtil.RunOnFrameworkThread(IsBeingDrawn).ConfigureAwait(false);
|
return await _dalamudUtil.RunOnFrameworkThread(IsBeingDrawn).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override ToString method for GameObjectHandler
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>String</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
var owned = _isOwnedObject ? "Self" : "Other";
|
var owned = _isOwnedObject ? "Self" : "Other";
|
||||||
return $"{owned}/{ObjectKind}:{Name} ({Address:X},{DrawObjectAddress:X})";
|
return $"{owned}/{ObjectKind}:{Name} ({Address:X},{DrawObjectAddress:X})";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try Get Object By Address from Object Table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Object address</param>
|
||||||
|
/// <returns>Game Object of adress</returns>
|
||||||
private IGameObject? TryGetObjectByAddress(nint address)
|
private IGameObject? TryGetObjectByAddress(nint address)
|
||||||
{
|
{
|
||||||
if (address == nint.Zero) return null;
|
if (address == nint.Zero) return null;
|
||||||
|
|
||||||
|
// Search object table
|
||||||
foreach (var obj in _objectTable)
|
foreach (var obj in _objectTable)
|
||||||
{
|
{
|
||||||
if (obj is null) continue;
|
if (obj is null) continue;
|
||||||
@@ -182,8 +228,15 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks and updates the object state
|
||||||
|
/// </summary>
|
||||||
private void CheckAndUpdateObject() => CheckAndUpdateObject(allowPublish: true);
|
private void CheckAndUpdateObject() => CheckAndUpdateObject(allowPublish: true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks and updates the object state with option to allow publish
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="allowPublish">Allows to publish the object</param>
|
||||||
private void CheckAndUpdateObject(bool allowPublish)
|
private void CheckAndUpdateObject(bool allowPublish)
|
||||||
{
|
{
|
||||||
var prevAddr = Address;
|
var prevAddr = Address;
|
||||||
@@ -197,6 +250,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
|
|
||||||
if (Address != nint.Zero)
|
if (Address != nint.Zero)
|
||||||
{
|
{
|
||||||
|
// Try get object
|
||||||
obj = TryGetObjectByAddress(Address);
|
obj = TryGetObjectByAddress(Address);
|
||||||
|
|
||||||
if (obj is not null)
|
if (obj is not null)
|
||||||
@@ -205,6 +259,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
|
|
||||||
DrawObjectAddress = Address;
|
DrawObjectAddress = Address;
|
||||||
|
|
||||||
|
// Name update
|
||||||
nameString = obj.Name.TextValue ?? string.Empty;
|
nameString = obj.Name.TextValue ?? string.Empty;
|
||||||
if (!string.IsNullOrEmpty(nameString) && !string.Equals(nameString, Name, StringComparison.Ordinal))
|
if (!string.IsNullOrEmpty(nameString) && !string.Equals(nameString, Name, StringComparison.Ordinal))
|
||||||
Name = nameString;
|
Name = nameString;
|
||||||
@@ -223,13 +278,16 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
EntityId = uint.MaxValue;
|
EntityId = uint.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update draw condition
|
||||||
CurrentDrawCondition = IsBeingDrawnSafe(obj, chara);
|
CurrentDrawCondition = IsBeingDrawnSafe(obj, chara);
|
||||||
|
|
||||||
if (_haltProcessing || !allowPublish) return;
|
if (_haltProcessing || !allowPublish) return;
|
||||||
|
|
||||||
|
// Determine differences
|
||||||
bool drawObjDiff = DrawObjectAddress != prevDrawObj;
|
bool drawObjDiff = DrawObjectAddress != prevDrawObj;
|
||||||
bool addrDiff = Address != prevAddr;
|
bool addrDiff = Address != prevAddr;
|
||||||
|
|
||||||
|
// Name change check
|
||||||
bool nameChange = false;
|
bool nameChange = false;
|
||||||
if (nameString is not null)
|
if (nameString is not null)
|
||||||
{
|
{
|
||||||
@@ -237,10 +295,11 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
if (nameChange) Name = nameString;
|
if (nameChange) Name = nameString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Customize data change check
|
||||||
bool customizeDiff = false;
|
bool customizeDiff = false;
|
||||||
|
|
||||||
if (chara is not null)
|
if (chara is not null)
|
||||||
{
|
{
|
||||||
|
// Class job change check
|
||||||
var classJob = chara.ClassJob.RowId;
|
var classJob = chara.ClassJob.RowId;
|
||||||
if (classJob != _classJob)
|
if (classJob != _classJob)
|
||||||
{
|
{
|
||||||
@@ -249,8 +308,10 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
Mediator.Publish(new ClassJobChangedMessage(this));
|
Mediator.Publish(new ClassJobChangedMessage(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Customize data comparison
|
||||||
customizeDiff = CompareAndUpdateCustomizeData(chara.Customize);
|
customizeDiff = CompareAndUpdateCustomizeData(chara.Customize);
|
||||||
|
|
||||||
|
// Census update publish
|
||||||
if (_isOwnedObject && ObjectKind == ObjectKind.Player && chara.Customize.Length > (int)CustomizeIndex.Tribe)
|
if (_isOwnedObject && ObjectKind == ObjectKind.Player && chara.Customize.Length > (int)CustomizeIndex.Tribe)
|
||||||
{
|
{
|
||||||
var gender = chara.Customize[(int)CustomizeIndex.Gender];
|
var gender = chara.Customize[(int)CustomizeIndex.Gender];
|
||||||
@@ -287,21 +348,35 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is object being drawn safe check
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Object thats being checked</param>
|
||||||
|
/// <param name="chara">Character of the object</param>
|
||||||
|
/// <returns>Draw Condition of character</returns>
|
||||||
private DrawCondition IsBeingDrawnSafe(IGameObject? obj, ICharacter? chara)
|
private DrawCondition IsBeingDrawnSafe(IGameObject? obj, ICharacter? chara)
|
||||||
{
|
{
|
||||||
|
// Object zero check
|
||||||
if (Address == nint.Zero) return DrawCondition.ObjectZero;
|
if (Address == nint.Zero) return DrawCondition.ObjectZero;
|
||||||
if (obj is null) return DrawCondition.DrawObjectZero;
|
if (obj is null) return DrawCondition.DrawObjectZero;
|
||||||
|
|
||||||
|
// Draw Object check
|
||||||
if (chara is not null && (chara.Customize is null || chara.Customize.Length == 0))
|
if (chara is not null && (chara.Customize is null || chara.Customize.Length == 0))
|
||||||
return DrawCondition.DrawObjectZero;
|
return DrawCondition.DrawObjectZero;
|
||||||
|
|
||||||
return DrawCondition.None;
|
return DrawCondition.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compare and update customize data of character
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="customizeData">Customize+ data of object</param>
|
||||||
|
/// <returns>Successfully applied or not</returns>
|
||||||
private bool CompareAndUpdateCustomizeData(ReadOnlySpan<byte> customizeData)
|
private bool CompareAndUpdateCustomizeData(ReadOnlySpan<byte> customizeData)
|
||||||
{
|
{
|
||||||
bool hasChanges = false;
|
bool hasChanges = false;
|
||||||
|
|
||||||
|
// Resize if needed
|
||||||
var len = Math.Min(customizeData.Length, CustomizeData.Length);
|
var len = Math.Min(customizeData.Length, CustomizeData.Length);
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
@@ -316,6 +391,9 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
return hasChanges;
|
return hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Framework update method
|
||||||
|
/// </summary>
|
||||||
private void FrameworkUpdate()
|
private void FrameworkUpdate()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -329,6 +407,10 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is object being drawn check
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Is being drawn</returns>
|
||||||
private bool IsBeingDrawn()
|
private bool IsBeingDrawn()
|
||||||
{
|
{
|
||||||
EnsureLatestObjectState();
|
EnsureLatestObjectState();
|
||||||
@@ -343,6 +425,9 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
return CurrentDrawCondition != DrawCondition.None;
|
return CurrentDrawCondition != DrawCondition.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensures the latest object state
|
||||||
|
/// </summary>
|
||||||
private void EnsureLatestObjectState()
|
private void EnsureLatestObjectState()
|
||||||
{
|
{
|
||||||
if (_haltProcessing || !_frameworkUpdateSubscribed)
|
if (_haltProcessing || !_frameworkUpdateSubscribed)
|
||||||
@@ -351,6 +436,9 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables framework updates for the object handler
|
||||||
|
/// </summary>
|
||||||
private void EnableFrameworkUpdates()
|
private void EnableFrameworkUpdates()
|
||||||
{
|
{
|
||||||
lock (_frameworkUpdateGate)
|
lock (_frameworkUpdateGate)
|
||||||
@@ -365,6 +453,9 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zone switch end handling
|
||||||
|
/// </summary>
|
||||||
private void ZoneSwitchEnd()
|
private void ZoneSwitchEnd()
|
||||||
{
|
{
|
||||||
if (!_isOwnedObject) return;
|
if (!_isOwnedObject) return;
|
||||||
@@ -375,7 +466,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
catch (ObjectDisposedException)
|
catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
// ignore
|
// ignore canelled after disposed
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -383,6 +474,9 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zone switch start handling
|
||||||
|
/// </summary>
|
||||||
private void ZoneSwitchStart()
|
private void ZoneSwitchStart()
|
||||||
{
|
{
|
||||||
if (!_isOwnedObject) return;
|
if (!_isOwnedObject) return;
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using LightlessSync.API.Data;
|
using LightlessSync.API.Data;
|
||||||
using LightlessSync.API.Data.Enum;
|
|
||||||
using LightlessSync.Interop.Ipc;
|
using LightlessSync.Interop.Ipc;
|
||||||
using LightlessSync.PlayerData.Factories;
|
using LightlessSync.PlayerData.Factories;
|
||||||
using LightlessSync.PlayerData.Pairs;
|
using LightlessSync.PlayerData.Pairs;
|
||||||
using LightlessSync.Services;
|
using LightlessSync.Services;
|
||||||
using LightlessSync.Services.ActorTracking;
|
using LightlessSync.Services.ActorTracking;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
|
||||||
using DalamudObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
|
using DalamudObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
|
||||||
using ObjectKind = LightlessSync.API.Data.Enum.ObjectKind;
|
using ObjectKind = LightlessSync.API.Data.Enum.ObjectKind;
|
||||||
|
|
||||||
|
|||||||
@@ -816,9 +816,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
{
|
{
|
||||||
_logger.LogInformation("Starting DalamudUtilService");
|
_logger.LogInformation("Starting DalamudUtilService");
|
||||||
_framework.Update += FrameworkOnUpdate;
|
_framework.Update += FrameworkOnUpdate;
|
||||||
if (IsLoggedIn)
|
_clientState.Login += OnClientLogin;
|
||||||
|
_clientState.Logout += OnClientLogout;
|
||||||
|
|
||||||
|
if (_clientState.IsLoggedIn)
|
||||||
{
|
{
|
||||||
_classJobId = _objectTable.LocalPlayer!.ClassJob.RowId;
|
OnClientLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("Started DalamudUtilService");
|
_logger.LogInformation("Started DalamudUtilService");
|
||||||
@@ -831,6 +834,9 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
|
|
||||||
Mediator.UnsubscribeAll(this);
|
Mediator.UnsubscribeAll(this);
|
||||||
_framework.Update -= FrameworkOnUpdate;
|
_framework.Update -= FrameworkOnUpdate;
|
||||||
|
_clientState.Login -= OnClientLogin;
|
||||||
|
_clientState.Logout -= OnClientLogout;
|
||||||
|
|
||||||
if (_FocusPairIdent.HasValue)
|
if (_FocusPairIdent.HasValue)
|
||||||
{
|
{
|
||||||
if (_framework.IsInFrameworkUpdateThread)
|
if (_framework.IsInFrameworkUpdateThread)
|
||||||
@@ -845,6 +851,41 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnClientLogin()
|
||||||
|
{
|
||||||
|
if (IsLoggedIn)
|
||||||
|
return;
|
||||||
|
_ = RunOnFrameworkThread(() =>
|
||||||
|
{
|
||||||
|
if (IsLoggedIn)
|
||||||
|
return;
|
||||||
|
var localPlayer = _objectTable.LocalPlayer;
|
||||||
|
IsLoggedIn = true;
|
||||||
|
_lastZone = _clientState.TerritoryType;
|
||||||
|
if (localPlayer != null)
|
||||||
|
{
|
||||||
|
_lastWorldId = (ushort)localPlayer.CurrentWorld.RowId;
|
||||||
|
_classJobId = localPlayer.ClassJob.RowId;
|
||||||
|
}
|
||||||
|
_cid = RebuildCID();
|
||||||
|
Mediator.Publish(new DalamudLoginMessage());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClientLogout(int type, int code)
|
||||||
|
{
|
||||||
|
if (!IsLoggedIn)
|
||||||
|
return;
|
||||||
|
_ = RunOnFrameworkThread(() =>
|
||||||
|
{
|
||||||
|
if (!IsLoggedIn)
|
||||||
|
return;
|
||||||
|
IsLoggedIn = false;
|
||||||
|
_lastWorldId = 0;
|
||||||
|
Mediator.Publish(new DalamudLogoutMessage());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async Task WaitWhileCharacterIsDrawing(
|
public async Task WaitWhileCharacterIsDrawing(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
GameObjectHandler handler,
|
GameObjectHandler handler,
|
||||||
@@ -1272,23 +1313,6 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
if (isNormalFrameworkUpdate)
|
if (isNormalFrameworkUpdate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (localPlayer != null && !IsLoggedIn)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Logged in");
|
|
||||||
IsLoggedIn = true;
|
|
||||||
_lastZone = _clientState.TerritoryType;
|
|
||||||
_lastWorldId = (ushort)localPlayer.CurrentWorld.RowId;
|
|
||||||
_cid = RebuildCID();
|
|
||||||
Mediator.Publish(new DalamudLoginMessage());
|
|
||||||
}
|
|
||||||
else if (localPlayer == null && IsLoggedIn)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Logged out");
|
|
||||||
IsLoggedIn = false;
|
|
||||||
_lastWorldId = 0;
|
|
||||||
Mediator.Publish(new DalamudLogoutMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gameConfig != null
|
if (_gameConfig != null
|
||||||
&& _gameConfig.TryGet(Dalamud.Game.Config.SystemConfigOption.LodType_DX11, out bool lodEnabled))
|
&& _gameConfig.TryGet(Dalamud.Game.Config.SystemConfigOption.LodType_DX11, out bool lodEnabled))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user