minor performance improvements
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using Dalamud.Memory;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using MareSynchronos.Services;
|
using MareSynchronos.Services;
|
||||||
using MareSynchronos.Services.Mediator;
|
using MareSynchronos.Services.Mediator;
|
||||||
@@ -209,7 +210,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
|
|||||||
_clearCts = null;
|
_clearCts = null;
|
||||||
}
|
}
|
||||||
var chara = (Character*)Address;
|
var chara = (Character*)Address;
|
||||||
var name = new ByteString(chara->GameObject.Name).ToString();
|
MemoryHelper.ReadStringNullTerminated((nint)chara->GameObject.Name, out var name);
|
||||||
bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal);
|
bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal);
|
||||||
if (nameChange)
|
if (nameChange)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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.Memory;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Control;
|
using FFXIVClientStructs.FFXIV.Client.Game.Control;
|
||||||
@@ -386,7 +387,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
if (!_playerInfoCache.TryGetValue(id, out var info))
|
if (!_playerInfoCache.TryGetValue(id, out var info))
|
||||||
{
|
{
|
||||||
info.Character.ObjectId = id;
|
info.Character.ObjectId = id;
|
||||||
info.Character.Name = chara.Name.ToString();
|
MemoryHelper.ReadStringNullTerminated((nint)((GameObject*)chara.Address)->Name, out info.Character.Name);
|
||||||
info.Character.HomeWorldId = ((BattleChara*)chara.Address)->Character.HomeWorld;
|
info.Character.HomeWorldId = ((BattleChara*)chara.Address)->Character.HomeWorld;
|
||||||
info.Character.Address = chara.Address;
|
info.Character.Address = chara.Address;
|
||||||
info.Hash = Crypto.GetHash256(info.Character.Name + info.Character.HomeWorldId.ToString());
|
info.Hash = Crypto.GetHash256(info.Character.Name + info.Character.HomeWorldId.ToString());
|
||||||
@@ -400,59 +401,57 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
|
|
||||||
private unsafe void CheckCharacterForDrawing(PlayerCharacter p)
|
private unsafe void CheckCharacterForDrawing(PlayerCharacter p)
|
||||||
{
|
{
|
||||||
if (!IsAnythingDrawing)
|
var gameObj = (GameObject*)p.Address;
|
||||||
|
var drawObj = gameObj->DrawObject;
|
||||||
|
var playerName = p.Name;
|
||||||
|
bool isDrawing = false;
|
||||||
|
bool isDrawingChanged = false;
|
||||||
|
if ((nint)drawObj != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
var gameObj = (GameObject*)p.Address;
|
isDrawing = gameObj->RenderFlags == 0b100000000000;
|
||||||
var drawObj = gameObj->DrawObject;
|
if (!isDrawing)
|
||||||
bool isDrawing = false;
|
|
||||||
bool isDrawingChanged = false;
|
|
||||||
if ((nint)drawObj != IntPtr.Zero)
|
|
||||||
{
|
{
|
||||||
isDrawing = gameObj->RenderFlags == 0b100000000000;
|
isDrawing = ((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0;
|
||||||
if (!isDrawing)
|
if (!isDrawing)
|
||||||
{
|
{
|
||||||
isDrawing = ((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0;
|
isDrawing = ((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0;
|
||||||
if (!isDrawing)
|
if (isDrawing && !string.Equals(_lastGlobalBlockPlayer, playerName, StringComparison.Ordinal)
|
||||||
|
&& !string.Equals(_lastGlobalBlockReason, "HasModelFilesInSlotLoaded", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
isDrawing = ((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0;
|
_lastGlobalBlockPlayer = playerName;
|
||||||
if (isDrawing && !string.Equals(_lastGlobalBlockPlayer, p.Name, StringComparison.Ordinal)
|
_lastGlobalBlockReason = "HasModelFilesInSlotLoaded";
|
||||||
&& !string.Equals(_lastGlobalBlockReason, "HasModelFilesInSlotLoaded", StringComparison.Ordinal))
|
isDrawingChanged = true;
|
||||||
{
|
|
||||||
_lastGlobalBlockPlayer = p.Name;
|
|
||||||
_lastGlobalBlockReason = "HasModelFilesInSlotLoaded";
|
|
||||||
isDrawingChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!string.Equals(_lastGlobalBlockPlayer, p.Name, StringComparison.Ordinal)
|
|
||||||
&& !string.Equals(_lastGlobalBlockReason, "HasModelInSlotLoaded", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
_lastGlobalBlockPlayer = p.Name;
|
|
||||||
_lastGlobalBlockReason = "HasModelInSlotLoaded";
|
|
||||||
isDrawingChanged = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!string.Equals(_lastGlobalBlockPlayer, p.Name, StringComparison.Ordinal)
|
if (!string.Equals(_lastGlobalBlockPlayer, playerName, StringComparison.Ordinal)
|
||||||
&& !string.Equals(_lastGlobalBlockReason, "RenderFlags", StringComparison.Ordinal))
|
&& !string.Equals(_lastGlobalBlockReason, "HasModelInSlotLoaded", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
_lastGlobalBlockPlayer = p.Name;
|
_lastGlobalBlockPlayer = playerName;
|
||||||
_lastGlobalBlockReason = "RenderFlags";
|
_lastGlobalBlockReason = "HasModelInSlotLoaded";
|
||||||
isDrawingChanged = true;
|
isDrawingChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (isDrawingChanged)
|
|
||||||
{
|
{
|
||||||
_logger.LogTrace("Global draw block: START => {name} ({reason})", p.Name, _lastGlobalBlockReason);
|
if (!string.Equals(_lastGlobalBlockPlayer, playerName, StringComparison.Ordinal)
|
||||||
|
&& !string.Equals(_lastGlobalBlockReason, "RenderFlags", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
_lastGlobalBlockPlayer = playerName;
|
||||||
|
_lastGlobalBlockReason = "RenderFlags";
|
||||||
|
isDrawingChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IsAnythingDrawing |= isDrawing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDrawingChanged)
|
||||||
|
{
|
||||||
|
_logger.LogTrace("Global draw block: START => {name} ({reason})", playerName, _lastGlobalBlockReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
IsAnythingDrawing |= isDrawing;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FrameworkOnUpdate(IFramework framework)
|
private void FrameworkOnUpdate(IFramework framework)
|
||||||
@@ -467,141 +466,156 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsAnythingDrawing = false;
|
bool isNormalFrameworkUpdate = DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1);
|
||||||
_performanceCollector.LogPerformance(this, "ObjTableToCharas",
|
|
||||||
() =>
|
_performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal+" + (isNormalFrameworkUpdate ? "Regular" : "Delayed"), () =>
|
||||||
|
{
|
||||||
|
IsAnythingDrawing = false;
|
||||||
|
_performanceCollector.LogPerformance(this, "ObjTableToCharas",
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
if (_sentBetweenAreas)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_notUpdatedCharas.AddRange(_playerCharas.Keys);
|
||||||
|
|
||||||
|
for (int i = 0; i < 200; i += 2)
|
||||||
|
{
|
||||||
|
var chara = _objectTable[i];
|
||||||
|
if (chara == null || chara.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var info = GetPlayerInfo(chara);
|
||||||
|
|
||||||
|
if (!IsAnythingDrawing)
|
||||||
|
CheckCharacterForDrawing(info.Character);
|
||||||
|
_notUpdatedCharas.Remove(info.Hash);
|
||||||
|
_playerCharas[info.Hash] = info.Character;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var notUpdatedChara in _notUpdatedCharas)
|
||||||
|
{
|
||||||
|
_playerCharas.Remove(notUpdatedChara);
|
||||||
|
}
|
||||||
|
|
||||||
|
_notUpdatedCharas.Clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!IsAnythingDrawing && !string.IsNullOrEmpty(_lastGlobalBlockPlayer))
|
||||||
{
|
{
|
||||||
_notUpdatedCharas.AddRange(_playerCharas.Keys);
|
_logger.LogTrace("Global draw block: END => {name}", _lastGlobalBlockPlayer);
|
||||||
|
_lastGlobalBlockPlayer = string.Empty;
|
||||||
foreach (var chara in _objectTable)
|
_lastGlobalBlockReason = string.Empty;
|
||||||
{
|
|
||||||
if (chara.ObjectIndex % 2 != 0 || chara.ObjectIndex >= 200) continue;
|
|
||||||
|
|
||||||
string charaName = chara.Name.ToString();
|
|
||||||
uint homeWorldId = ((BattleChara*)chara.Address)->Character.HomeWorld;
|
|
||||||
|
|
||||||
var info = GetPlayerInfo(chara);
|
|
||||||
if (!IsAnythingDrawing)
|
|
||||||
CheckCharacterForDrawing(info.Character);
|
|
||||||
_notUpdatedCharas.Remove(info.Hash);
|
|
||||||
_playerCharas[info.Hash] = info.Character;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var notUpdatedChara in _notUpdatedCharas)
|
|
||||||
{
|
|
||||||
_playerCharas.Remove(notUpdatedChara);
|
|
||||||
}
|
|
||||||
|
|
||||||
_notUpdatedCharas.Clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!IsAnythingDrawing && !string.IsNullOrEmpty(_lastGlobalBlockPlayer))
|
|
||||||
{
|
|
||||||
_logger.LogTrace("Global draw block: END => {name}", _lastGlobalBlockPlayer);
|
|
||||||
_lastGlobalBlockPlayer = string.Empty;
|
|
||||||
_lastGlobalBlockReason = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GposeTarget != null && !IsInGpose)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Gpose start");
|
|
||||||
IsInGpose = true;
|
|
||||||
Mediator.Publish(new GposeStartMessage());
|
|
||||||
}
|
|
||||||
else if (GposeTarget == null && IsInGpose)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Gpose end");
|
|
||||||
IsInGpose = false;
|
|
||||||
Mediator.Publish(new GposeEndMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_condition[ConditionFlag.InCombat] && !IsInCombat)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Combat start");
|
|
||||||
IsInCombat = true;
|
|
||||||
Mediator.Publish(new CombatStartMessage());
|
|
||||||
Mediator.Publish(new HaltScanMessage(nameof(IsInCombat)));
|
|
||||||
}
|
|
||||||
else if (!_condition[ConditionFlag.InCombat] && IsInCombat)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Combat end");
|
|
||||||
IsInCombat = false;
|
|
||||||
Mediator.Publish(new CombatEndMessage());
|
|
||||||
Mediator.Publish(new ResumeScanMessage(nameof(IsInCombat)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_condition[ConditionFlag.WatchingCutscene] && !IsInCutscene)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Cutscene start");
|
|
||||||
IsInCutscene = true;
|
|
||||||
Mediator.Publish(new CutsceneStartMessage());
|
|
||||||
Mediator.Publish(new HaltScanMessage(nameof(IsInCutscene)));
|
|
||||||
}
|
|
||||||
else if (!_condition[ConditionFlag.WatchingCutscene] && IsInCutscene)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Cutscene end");
|
|
||||||
IsInCutscene = false;
|
|
||||||
Mediator.Publish(new CutsceneEndMessage());
|
|
||||||
Mediator.Publish(new ResumeScanMessage(nameof(IsInCutscene)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsInCutscene) { Mediator.Publish(new CutsceneFrameworkUpdateMessage()); return; }
|
|
||||||
|
|
||||||
if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51])
|
|
||||||
{
|
|
||||||
var zone = _clientState.TerritoryType;
|
|
||||||
if (_lastZone != zone)
|
|
||||||
{
|
|
||||||
_lastZone = zone;
|
|
||||||
if (!_sentBetweenAreas)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Zone switch/Gpose start");
|
|
||||||
_sentBetweenAreas = true;
|
|
||||||
Mediator.Publish(new ZoneSwitchStartMessage());
|
|
||||||
Mediator.Publish(new HaltScanMessage(nameof(ConditionFlag.BetweenAreas)));
|
|
||||||
_playerInfoCache.Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
if (GposeTarget != null && !IsInGpose)
|
||||||
}
|
{
|
||||||
|
_logger.LogDebug("Gpose start");
|
||||||
|
IsInGpose = true;
|
||||||
|
Mediator.Publish(new GposeStartMessage());
|
||||||
|
}
|
||||||
|
else if (GposeTarget == null && IsInGpose)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Gpose end");
|
||||||
|
IsInGpose = false;
|
||||||
|
Mediator.Publish(new GposeEndMessage());
|
||||||
|
}
|
||||||
|
|
||||||
if (_sentBetweenAreas)
|
if (_condition[ConditionFlag.InCombat] && !IsInCombat)
|
||||||
{
|
{
|
||||||
_logger.LogDebug("Zone switch/Gpose end");
|
_logger.LogDebug("Combat start");
|
||||||
_sentBetweenAreas = false;
|
IsInCombat = true;
|
||||||
Mediator.Publish(new ZoneSwitchEndMessage());
|
Mediator.Publish(new CombatStartMessage());
|
||||||
Mediator.Publish(new ResumeScanMessage(nameof(ConditionFlag.BetweenAreas)));
|
Mediator.Publish(new HaltScanMessage(nameof(IsInCombat)));
|
||||||
}
|
}
|
||||||
|
else if (!_condition[ConditionFlag.InCombat] && IsInCombat)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Combat end");
|
||||||
|
IsInCombat = false;
|
||||||
|
Mediator.Publish(new CombatEndMessage());
|
||||||
|
Mediator.Publish(new ResumeScanMessage(nameof(IsInCombat)));
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsInCombat)
|
if (_condition[ConditionFlag.WatchingCutscene] && !IsInCutscene)
|
||||||
Mediator.Publish(new FrameworkUpdateMessage());
|
{
|
||||||
|
_logger.LogDebug("Cutscene start");
|
||||||
|
IsInCutscene = true;
|
||||||
|
Mediator.Publish(new CutsceneStartMessage());
|
||||||
|
Mediator.Publish(new HaltScanMessage(nameof(IsInCutscene)));
|
||||||
|
}
|
||||||
|
else if (!_condition[ConditionFlag.WatchingCutscene] && IsInCutscene)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Cutscene end");
|
||||||
|
IsInCutscene = false;
|
||||||
|
Mediator.Publish(new CutsceneEndMessage());
|
||||||
|
Mediator.Publish(new ResumeScanMessage(nameof(IsInCutscene)));
|
||||||
|
}
|
||||||
|
|
||||||
Mediator.Publish(new PriorityFrameworkUpdateMessage());
|
if (IsInCutscene)
|
||||||
|
{
|
||||||
|
Mediator.Publish(new CutsceneFrameworkUpdateMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1)) return;
|
if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51])
|
||||||
|
{
|
||||||
|
var zone = _clientState.TerritoryType;
|
||||||
|
if (_lastZone != zone)
|
||||||
|
{
|
||||||
|
_lastZone = zone;
|
||||||
|
if (!_sentBetweenAreas)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Zone switch/Gpose start");
|
||||||
|
_sentBetweenAreas = true;
|
||||||
|
_playerInfoCache.Clear();
|
||||||
|
Mediator.Publish(new ZoneSwitchStartMessage());
|
||||||
|
Mediator.Publish(new HaltScanMessage(nameof(ConditionFlag.BetweenAreas)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var localPlayer = _clientState.LocalPlayer;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (localPlayer != null && !IsLoggedIn)
|
if (_sentBetweenAreas)
|
||||||
{
|
{
|
||||||
_logger.LogDebug("Logged in");
|
_logger.LogDebug("Zone switch/Gpose end");
|
||||||
IsLoggedIn = true;
|
_sentBetweenAreas = false;
|
||||||
_lastZone = _clientState.TerritoryType;
|
Mediator.Publish(new ZoneSwitchEndMessage());
|
||||||
Mediator.Publish(new DalamudLoginMessage());
|
Mediator.Publish(new ResumeScanMessage(nameof(ConditionFlag.BetweenAreas)));
|
||||||
}
|
}
|
||||||
else if (localPlayer == null && IsLoggedIn)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Logged out");
|
|
||||||
IsLoggedIn = false;
|
|
||||||
Mediator.Publish(new DalamudLogoutMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsInCombat)
|
if (!IsInCombat)
|
||||||
Mediator.Publish(new FrameworkUpdateMessage());
|
_performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal>MediatorFrameworkUpdate",
|
||||||
|
() => Mediator.Publish(new FrameworkUpdateMessage()));
|
||||||
|
|
||||||
Mediator.Publish(new DelayedFrameworkUpdateMessage());
|
Mediator.Publish(new PriorityFrameworkUpdateMessage());
|
||||||
|
|
||||||
_delayedFrameworkUpdateCheck = DateTime.Now;
|
if (isNormalFrameworkUpdate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var localPlayer = _clientState.LocalPlayer;
|
||||||
|
|
||||||
|
if (localPlayer != null && !IsLoggedIn)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Logged in");
|
||||||
|
IsLoggedIn = true;
|
||||||
|
_lastZone = _clientState.TerritoryType;
|
||||||
|
Mediator.Publish(new DalamudLoginMessage());
|
||||||
|
}
|
||||||
|
else if (localPlayer == null && IsLoggedIn)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Logged out");
|
||||||
|
IsLoggedIn = false;
|
||||||
|
Mediator.Publish(new DalamudLogoutMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsInCombat)
|
||||||
|
_performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal>MediatorFrameworkUpdate",
|
||||||
|
() => Mediator.Publish(new FrameworkUpdateMessage()));
|
||||||
|
|
||||||
|
Mediator.Publish(new DelayedFrameworkUpdateMessage());
|
||||||
|
|
||||||
|
_delayedFrameworkUpdateCheck = DateTime.Now;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,40 +130,43 @@ public sealed class MareMediator : IHostedService
|
|||||||
{
|
{
|
||||||
if (!_subscriberDict.TryGetValue(message.GetType(), out HashSet<SubscriberAction>? subscribers) || subscribers == null || !subscribers.Any()) return;
|
if (!_subscriberDict.TryGetValue(message.GetType(), out HashSet<SubscriberAction>? subscribers) || subscribers == null || !subscribers.Any()) return;
|
||||||
|
|
||||||
HashSet<SubscriberAction> subscribersCopy = [];
|
List<SubscriberAction> subscribersCopy = [];
|
||||||
lock (_addRemoveLock)
|
lock (_addRemoveLock)
|
||||||
{
|
{
|
||||||
subscribersCopy = subscribers?.Where(s => s.Subscriber != null).ToHashSet() ?? [];
|
subscribersCopy = subscribers?.Where(s => s.Subscriber != null).ToList() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (SubscriberAction subscriber in subscribersCopy)
|
#pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
|
||||||
|
GetType()
|
||||||
|
.GetMethod(nameof(ExecuteReflected), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?
|
||||||
|
.MakeGenericMethod(message.GetType())?
|
||||||
|
.Invoke(this, [subscribersCopy, message]);
|
||||||
|
#pragma warning restore S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteReflected<T>(List<SubscriberAction> subscribers, T message) where T : MessageBase
|
||||||
|
{
|
||||||
|
var msgTypeName = message.GetType().Name;
|
||||||
|
foreach (SubscriberAction subscriber in subscribers)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
|
var isSameThread = message.KeepThreadContext ? "$" : string.Empty;
|
||||||
typeof(MareMediator)
|
_performanceCollector.LogPerformance(this, $"{isSameThread}Execute>{msgTypeName}+{subscriber.Subscriber.GetType().Name}>{subscriber.Subscriber}",
|
||||||
.GetMethod(nameof(ExecuteSubscriber), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?
|
() => ((Action<T>)subscriber.Action).Invoke(message));
|
||||||
.MakeGenericMethod(message.GetType())
|
|
||||||
.Invoke(this, new object[] { subscriber, message });
|
|
||||||
#pragma warning restore S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (_lastErrorTime.TryGetValue(subscriber, out var lastErrorTime) && lastErrorTime.Add(TimeSpan.FromSeconds(10)) > DateTime.UtcNow)
|
if (_lastErrorTime.TryGetValue(subscriber, out var lastErrorTime) && lastErrorTime.Add(TimeSpan.FromSeconds(10)) > DateTime.UtcNow)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_logger.LogError(ex.InnerException ?? ex, "Error executing {type} for subscriber {subscriber}", message.GetType().Name, subscriber.Subscriber.GetType().Name);
|
_logger.LogError(ex.InnerException ?? ex, "Error executing {type} for subscriber {subscriber}",
|
||||||
|
message.GetType().Name, subscriber.Subscriber.GetType().Name);
|
||||||
_lastErrorTime[subscriber] = DateTime.UtcNow;
|
_lastErrorTime[subscriber] = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteSubscriber<T>(SubscriberAction subscriber, T message) where T : MessageBase
|
|
||||||
{
|
|
||||||
var isSameThread = message.KeepThreadContext ? "$" : string.Empty;
|
|
||||||
_performanceCollector.LogPerformance(this, $"{isSameThread}Execute>{message.GetType().Name}+{subscriber.Subscriber.GetType().Name}>{subscriber.Subscriber}", () => ((Action<T>)subscriber.Action).Invoke(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class SubscriberAction
|
private sealed class SubscriberAction
|
||||||
{
|
{
|
||||||
public SubscriberAction(IMediatorSubscriber subscriber, object action)
|
public SubscriberAction(IMediatorSubscriber subscriber, object action)
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ public static class Crypto
|
|||||||
{
|
{
|
||||||
#pragma warning disable SYSLIB0021 // Type or member is obsolete
|
#pragma warning disable SYSLIB0021 // Type or member is obsolete
|
||||||
|
|
||||||
private static readonly Dictionary<string, string> _hashListSHA1 = new(StringComparer.Ordinal);
|
|
||||||
private static readonly Dictionary<string, string> _hashListSHA256 = new(StringComparer.Ordinal);
|
|
||||||
private static readonly SHA256CryptoServiceProvider _sha256CryptoProvider = new();
|
private static readonly SHA256CryptoServiceProvider _sha256CryptoProvider = new();
|
||||||
private static readonly SHA1CryptoServiceProvider _sha1CryptoProvider = new();
|
|
||||||
|
|
||||||
public static string GetFileHash(this string filePath)
|
public static string GetFileHash(this string filePath)
|
||||||
{
|
{
|
||||||
@@ -18,31 +15,17 @@ public static class Crypto
|
|||||||
return BitConverter.ToString(cryptoProvider.ComputeHash(File.ReadAllBytes(filePath))).Replace("-", "", StringComparison.Ordinal);
|
return BitConverter.ToString(cryptoProvider.ComputeHash(File.ReadAllBytes(filePath))).Replace("-", "", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetHash(this string stringToHash)
|
|
||||||
{
|
|
||||||
return GetOrComputeHashSHA1(stringToHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetHash256(this string stringToHash)
|
public static string GetHash256(this string stringToHash)
|
||||||
{
|
{
|
||||||
return GetOrComputeHashSHA256(stringToHash);
|
return GetOrComputeHashSHA256(stringToHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetOrComputeHashSHA1(string stringToCompute)
|
|
||||||
{
|
|
||||||
if (_hashListSHA1.TryGetValue(stringToCompute, out var hash))
|
|
||||||
return hash;
|
|
||||||
|
|
||||||
return _hashListSHA1[stringToCompute] = BitConverter.ToString(_sha1CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetOrComputeHashSHA256(string stringToCompute)
|
private static string GetOrComputeHashSHA256(string stringToCompute)
|
||||||
{
|
{
|
||||||
if (_hashListSHA256.TryGetValue(stringToCompute, out var hash))
|
return BitConverter.ToString(_sha256CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
|
||||||
return hash;
|
|
||||||
|
|
||||||
return _hashListSHA256[stringToCompute] = BitConverter.ToString(_sha256CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma warning restore SYSLIB0021 // Type or member is obsolete
|
#pragma warning restore SYSLIB0021 // Type or member is obsolete
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user