Improve ObjTableToCharas efficiency
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
@@ -18,6 +19,13 @@ namespace MareSynchronos.Services;
|
|||||||
|
|
||||||
public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||||
{
|
{
|
||||||
|
private struct PlayerInfo
|
||||||
|
{
|
||||||
|
public String Name;
|
||||||
|
public uint WorldId;
|
||||||
|
public String Hash;
|
||||||
|
};
|
||||||
|
|
||||||
private readonly List<uint> _classJobIdsIgnoredForPets = [30];
|
private readonly List<uint> _classJobIdsIgnoredForPets = [30];
|
||||||
private readonly IClientState _clientState;
|
private readonly IClientState _clientState;
|
||||||
private readonly ICondition _condition;
|
private readonly ICondition _condition;
|
||||||
@@ -33,6 +41,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
private ushort _lastZone = 0;
|
private ushort _lastZone = 0;
|
||||||
private Dictionary<string, (string Name, nint Address)> _playerCharas = new(StringComparer.Ordinal);
|
private Dictionary<string, (string Name, nint Address)> _playerCharas = new(StringComparer.Ordinal);
|
||||||
private bool _sentBetweenAreas = false;
|
private bool _sentBetweenAreas = false;
|
||||||
|
private static readonly Dictionary<uint, PlayerInfo> _playerInfoCache = new();
|
||||||
|
|
||||||
public DalamudUtilService(ILogger<DalamudUtilService> logger, IClientState clientState, IObjectTable objectTable, IFramework framework,
|
public DalamudUtilService(ILogger<DalamudUtilService> logger, IClientState clientState, IObjectTable objectTable, IFramework framework,
|
||||||
IGameGui gameGui, ICondition condition, IDataManager gameData, ITargetManager targetManager,
|
IGameGui gameGui, ICondition condition, IDataManager gameData, ITargetManager targetManager,
|
||||||
@@ -360,13 +369,28 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PlayerInfo GetPlayerInfo(PlayerCharacter p)
|
||||||
|
{
|
||||||
|
uint id = p.ObjectId;
|
||||||
|
|
||||||
|
if (!_playerInfoCache.TryGetValue(id, out var info))
|
||||||
|
{
|
||||||
|
info.Name = p.Name.ToString();
|
||||||
|
info.WorldId = p.HomeWorld.Id;
|
||||||
|
info.Hash = Crypto.GetHash256(info.Name + info.WorldId.ToString());
|
||||||
|
_playerInfoCache[id] = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
private unsafe void CheckCharacterForDrawing(PlayerCharacter p)
|
private unsafe void CheckCharacterForDrawing(PlayerCharacter p)
|
||||||
{
|
{
|
||||||
if (!IsAnythingDrawing)
|
if (!IsAnythingDrawing)
|
||||||
{
|
{
|
||||||
var gameObj = (GameObject*)p.Address;
|
var gameObj = (GameObject*)p.Address;
|
||||||
var drawObj = gameObj->DrawObject;
|
var drawObj = gameObj->DrawObject;
|
||||||
var playerName = p.Name.ToString();
|
var playerInfo = GetPlayerInfo(p);
|
||||||
bool isDrawing = false;
|
bool isDrawing = false;
|
||||||
bool isDrawingChanged = false;
|
bool isDrawingChanged = false;
|
||||||
if ((nint)drawObj != IntPtr.Zero)
|
if ((nint)drawObj != IntPtr.Zero)
|
||||||
@@ -378,20 +402,20 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
if (!isDrawing)
|
if (!isDrawing)
|
||||||
{
|
{
|
||||||
isDrawing = ((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0;
|
isDrawing = ((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0;
|
||||||
if (isDrawing && !string.Equals(_lastGlobalBlockPlayer, playerName, StringComparison.Ordinal)
|
if (isDrawing && !string.Equals(_lastGlobalBlockPlayer, playerInfo.Name, StringComparison.Ordinal)
|
||||||
&& !string.Equals(_lastGlobalBlockReason, "HasModelFilesInSlotLoaded", StringComparison.Ordinal))
|
&& !string.Equals(_lastGlobalBlockReason, "HasModelFilesInSlotLoaded", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
_lastGlobalBlockPlayer = playerName;
|
_lastGlobalBlockPlayer = playerInfo.Name;
|
||||||
_lastGlobalBlockReason = "HasModelFilesInSlotLoaded";
|
_lastGlobalBlockReason = "HasModelFilesInSlotLoaded";
|
||||||
isDrawingChanged = true;
|
isDrawingChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!string.Equals(_lastGlobalBlockPlayer, playerName, StringComparison.Ordinal)
|
if (!string.Equals(_lastGlobalBlockPlayer, playerInfo.Name, StringComparison.Ordinal)
|
||||||
&& !string.Equals(_lastGlobalBlockReason, "HasModelInSlotLoaded", StringComparison.Ordinal))
|
&& !string.Equals(_lastGlobalBlockReason, "HasModelInSlotLoaded", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
_lastGlobalBlockPlayer = playerName;
|
_lastGlobalBlockPlayer = playerInfo.Name;
|
||||||
_lastGlobalBlockReason = "HasModelInSlotLoaded";
|
_lastGlobalBlockReason = "HasModelInSlotLoaded";
|
||||||
isDrawingChanged = true;
|
isDrawingChanged = true;
|
||||||
}
|
}
|
||||||
@@ -399,10 +423,10 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!string.Equals(_lastGlobalBlockPlayer, playerName, StringComparison.Ordinal)
|
if (!string.Equals(_lastGlobalBlockPlayer, playerInfo.Name, StringComparison.Ordinal)
|
||||||
&& !string.Equals(_lastGlobalBlockReason, "RenderFlags", StringComparison.Ordinal))
|
&& !string.Equals(_lastGlobalBlockReason, "RenderFlags", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
_lastGlobalBlockPlayer = playerName;
|
_lastGlobalBlockPlayer = playerInfo.Name;
|
||||||
_lastGlobalBlockReason = "RenderFlags";
|
_lastGlobalBlockReason = "RenderFlags";
|
||||||
isDrawingChanged = true;
|
isDrawingChanged = true;
|
||||||
}
|
}
|
||||||
@@ -411,7 +435,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
|
|
||||||
if (isDrawingChanged)
|
if (isDrawingChanged)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("Global draw block: START => {name} ({reason})", playerName, _lastGlobalBlockReason);
|
_logger.LogTrace("Global draw block: START => {name} ({reason})", playerInfo.Name, _lastGlobalBlockReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsAnythingDrawing |= isDrawing;
|
IsAnythingDrawing |= isDrawing;
|
||||||
@@ -431,13 +455,17 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsAnythingDrawing = false;
|
IsAnythingDrawing = false;
|
||||||
_playerCharas = _performanceCollector.LogPerformance(this, "ObjTableToCharas",
|
_playerCharas.Clear();
|
||||||
() => _objectTable.OfType<PlayerCharacter>().Where(o => o.ObjectIndex < 200)
|
_performanceCollector.LogPerformance(this, "ObjTableToCharas",
|
||||||
.ToDictionary(p => p.GetHash256(), p =>
|
() => {
|
||||||
|
foreach (var p in _objectTable.OfType<PlayerCharacter>().Where(o => o.ObjectIndex < 200))
|
||||||
{
|
{
|
||||||
CheckCharacterForDrawing(p);
|
CheckCharacterForDrawing(p);
|
||||||
return (p.Name.ToString(), p.Address);
|
var info = GetPlayerInfo(p);
|
||||||
}, StringComparer.Ordinal));
|
_playerCharas.Add(info.Hash, (info.Name, p.Address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!IsAnythingDrawing && !string.IsNullOrEmpty(_lastGlobalBlockPlayer))
|
if (!IsAnythingDrawing && !string.IsNullOrEmpty(_lastGlobalBlockPlayer))
|
||||||
{
|
{
|
||||||
@@ -503,6 +531,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
_sentBetweenAreas = true;
|
_sentBetweenAreas = true;
|
||||||
Mediator.Publish(new ZoneSwitchStartMessage());
|
Mediator.Publish(new ZoneSwitchStartMessage());
|
||||||
Mediator.Publish(new HaltScanMessage(nameof(ConditionFlag.BetweenAreas)));
|
Mediator.Publish(new HaltScanMessage(nameof(ConditionFlag.BetweenAreas)));
|
||||||
|
_playerInfoCache.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user