Merge branch '2.0.0' into dotnet10-api14-migration

This commit is contained in:
defnotken
2025-11-26 16:20:38 -06:00
116 changed files with 20468 additions and 3311 deletions

View File

@@ -12,15 +12,20 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using LightlessSync.API.Dto.CharaData;
using LightlessSync.Interop;
using LightlessSync.LightlessConfiguration;
using LightlessSync.PlayerData.Factories;
using LightlessSync.PlayerData.Handlers;
using LightlessSync.PlayerData.Pairs;
using LightlessSync.Services.ActorTracking;
using LightlessSync.Services.Mediator;
using LightlessSync.Utils;
using Lumina.Excel.Sheets;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using DalamudObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
namespace LightlessSync.Services;
@@ -37,23 +42,24 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
private readonly IGameGui _gameGui;
private readonly ILogger<DalamudUtilService> _logger;
private readonly IObjectTable _objectTable;
private readonly ActorObjectService _actorObjectService;
private readonly PerformanceCollectorService _performanceCollector;
private readonly LightlessConfigService _configService;
private readonly PlayerPerformanceConfigService _playerPerformanceConfigService;
private readonly Lazy<PairFactory> _pairFactory;
private uint? _classJobId = 0;
private DateTime _delayedFrameworkUpdateCheck = DateTime.UtcNow;
private string _lastGlobalBlockPlayer = string.Empty;
private string _lastGlobalBlockReason = string.Empty;
private ushort _lastZone = 0;
private readonly Dictionary<string, (string Name, nint Address)> _playerCharas = new(StringComparer.Ordinal);
private readonly List<string> _notUpdatedCharas = [];
private ushort _lastWorldId = 0;
private bool _sentBetweenAreas = false;
private Lazy<ulong> _cid;
public DalamudUtilService(ILogger<DalamudUtilService> logger, IClientState clientState, IObjectTable objectTable, IFramework framework,
IGameGui gameGui, ICondition condition, IDataManager gameData, ITargetManager targetManager, IGameConfig gameConfig,
BlockedCharacterHandler blockedCharacterHandler, LightlessMediator mediator, PerformanceCollectorService performanceCollector,
LightlessConfigService configService, PlayerPerformanceConfigService playerPerformanceConfigService)
ActorObjectService actorObjectService, BlockedCharacterHandler blockedCharacterHandler, LightlessMediator mediator, PerformanceCollectorService performanceCollector,
LightlessConfigService configService, PlayerPerformanceConfigService playerPerformanceConfigService, Lazy<PairFactory> pairFactory)
{
_logger = logger;
_clientState = clientState;
@@ -63,11 +69,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_condition = condition;
_gameData = gameData;
_gameConfig = gameConfig;
_actorObjectService = actorObjectService;
_blockedCharacterHandler = blockedCharacterHandler;
Mediator = mediator;
_performanceCollector = performanceCollector;
_configService = configService;
_playerPerformanceConfigService = playerPerformanceConfigService;
_pairFactory = pairFactory;
WorldData = new(() =>
{
return gameData.GetExcelSheet<Lumina.Excel.Sheets.World>(Dalamud.Game.ClientLanguage.English)!
@@ -119,9 +127,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
mediator.Subscribe<TargetPairMessage>(this, (msg) =>
{
if (clientState.IsPvP) return;
var name = msg.Pair.PlayerName;
var pair = _pairFactory.Value.Create(msg.Pair.UniqueIdent) ?? msg.Pair;
var name = pair.PlayerName;
if (string.IsNullOrEmpty(name)) return;
var addr = _playerCharas.FirstOrDefault(f => string.Equals(f.Value.Name, name, StringComparison.Ordinal)).Value.Address;
if (!_actorObjectService.TryGetPlayerByName(name, out var descriptor))
return;
var addr = descriptor.Address;
if (addr == nint.Zero) return;
var useFocusTarget = _configService.Current.UseFocusTarget;
_ = RunOnFrameworkThread(() =>
@@ -194,7 +205,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
{
EnsureIsOnFramework();
var objTableObj = _objectTable[index];
if (objTableObj!.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player) return null;
if (objTableObj!.ObjectKind != DalamudObjectKind.Player) return null;
return (ICharacter)objTableObj;
}
@@ -226,7 +237,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public IEnumerable<ICharacter?> GetGposeCharactersFromObjectTable()
{
return _objectTable.Where(o => o.ObjectIndex > 200 && o.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player).Cast<ICharacter>();
foreach (var actor in _actorObjectService.PlayerDescriptors
.Where(a => a.ObjectKind == DalamudObjectKind.Player && a.ObjectIndex > 200))
{
var character = _objectTable.CreateObjectReference(actor.Address) as ICharacter;
if (character != null)
yield return character;
}
}
public bool GetIsPlayerPresent()
@@ -281,7 +298,8 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public IntPtr GetPlayerCharacterFromCachedTableByIdent(string characterName)
{
if (_playerCharas.TryGetValue(characterName, out var pchar)) return pchar.Address;
if (_actorObjectService.TryGetActorByHash(characterName, out var actor))
return actor.Address;
return IntPtr.Zero;
}
@@ -548,8 +566,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
internal (string Name, nint Address) FindPlayerByNameHash(string ident)
{
_playerCharas.TryGetValue(ident, out var result);
return result;
if (_actorObjectService.TryGetActorByHash(ident, out var descriptor))
{
return (descriptor.Name, descriptor.Address);
}
return default;
}
public string? GetWorldNameFromPlayerAddress(nint address)
@@ -635,37 +657,43 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_performanceCollector.LogPerformance(this, $"FrameworkOnUpdateInternal+{(isNormalFrameworkUpdate ? "Regular" : "Delayed")}", () =>
{
IsAnythingDrawing = false;
_performanceCollector.LogPerformance(this, $"ObjTableToCharas",
_performanceCollector.LogPerformance(this, $"TrackedActorsToState",
() =>
{
_notUpdatedCharas.AddRange(_playerCharas.Keys);
_actorObjectService.RefreshTrackedActors();
for (int i = 0; i < 200; i += 2)
var playerDescriptors = _actorObjectService.PlayerCharacterDescriptors;
for (var i = 0; i < playerDescriptors.Count; i++)
{
var chara = _objectTable[i];
if (chara == null || chara.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player)
var actor = playerDescriptors[i];
var playerAddress = actor.Address;
if (playerAddress == nint.Zero)
continue;
if (_blockedCharacterHandler.IsCharacterBlocked(chara.Address, out bool firstTime) && firstTime)
if (actor.ObjectIndex >= 200)
continue;
if (_blockedCharacterHandler.IsCharacterBlocked(playerAddress, out bool firstTime) && firstTime)
{
_logger.LogTrace("Skipping character {addr}, blocked/muted", chara.Address.ToString("X"));
_logger.LogTrace("Skipping character {addr}, blocked/muted", playerAddress.ToString("X"));
continue;
}
var charaName = ((GameObject*)chara.Address)->NameString;
var hash = GetHashedCIDFromPlayerPointer(chara.Address);
if (!IsAnythingDrawing)
CheckCharacterForDrawing(chara.Address, charaName);
_notUpdatedCharas.Remove(hash);
_playerCharas[hash] = (charaName, chara.Address);
{
var gameObj = (GameObject*)playerAddress;
var currentName = gameObj != null ? gameObj->NameString ?? string.Empty : string.Empty;
var charaName = string.IsNullOrEmpty(currentName) ? actor.Name : currentName;
CheckCharacterForDrawing(playerAddress, charaName);
if (IsAnythingDrawing)
break;
}
else
{
break;
}
}
foreach (var notUpdatedChara in _notUpdatedCharas)
{
_playerCharas.Remove(notUpdatedChara);
}
_notUpdatedCharas.Clear();
});
if (!IsAnythingDrawing && !string.IsNullOrEmpty(_lastGlobalBlockPlayer))
@@ -781,6 +809,18 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
if (localPlayer != null)
{
_classJobId = localPlayer.ClassJob.RowId;
var currentWorldId = (ushort)localPlayer.CurrentWorld.RowId;
if (currentWorldId != _lastWorldId)
{
var previousWorldId = _lastWorldId;
_lastWorldId = currentWorldId;
Mediator.Publish(new WorldChangedMessage(previousWorldId, currentWorldId));
}
}
else if (_lastWorldId != 0)
{
_lastWorldId = 0;
}
if (!IsInCombat || !IsPerforming || !IsInInstance)
@@ -796,6 +836,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_logger.LogDebug("Logged in");
IsLoggedIn = true;
_lastZone = _clientState.TerritoryType;
_lastWorldId = (ushort)localPlayer.CurrentWorld.RowId;
_cid = RebuildCID();
Mediator.Publish(new DalamudLoginMessage());
}
@@ -803,6 +844,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
{
_logger.LogDebug("Logged out");
IsLoggedIn = false;
_lastWorldId = 0;
Mediator.Publish(new DalamudLogoutMessage());
}