merge from downstream
This commit is contained in:
@@ -245,7 +245,7 @@ public class CharacterDataFactory
|
|||||||
|
|
||||||
previousData.ManipulationString = _ipcManager.PenumbraGetMetaManipulations();
|
previousData.ManipulationString = _ipcManager.PenumbraGetMetaManipulations();
|
||||||
|
|
||||||
previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(chara);
|
previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(charaPointer);
|
||||||
|
|
||||||
var human = (Human*)((Character*)charaPointer)->GameObject.GetDrawObject();
|
var human = (Human*)((Character*)charaPointer)->GameObject.GetDrawObject();
|
||||||
for (var mdlIdx = 0; mdlIdx < human->CharacterBase.SlotCount; ++mdlIdx)
|
for (var mdlIdx = 0; mdlIdx < human->CharacterBase.SlotCount; ++mdlIdx)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class CachedPlayer
|
|||||||
|
|
||||||
private string _originalGlamourerData = string.Empty;
|
private string _originalGlamourerData = string.Empty;
|
||||||
|
|
||||||
public Dalamud.Game.ClientState.Objects.Types.Character? PlayerCharacter { get; set; }
|
public IntPtr PlayerCharacter { get; set; } = IntPtr.Zero;
|
||||||
|
|
||||||
public string? PlayerName { get; private set; }
|
public string? PlayerName { get; private set; }
|
||||||
|
|
||||||
@@ -237,27 +237,27 @@ public class CachedPlayer
|
|||||||
|
|
||||||
private unsafe void ApplyCustomizationData(ObjectKind objectKind)
|
private unsafe void ApplyCustomizationData(ObjectKind objectKind)
|
||||||
{
|
{
|
||||||
if (PlayerCharacter is null) return;
|
if (PlayerCharacter == IntPtr.Zero) return;
|
||||||
_cachedData.GlamourerData.TryGetValue(objectKind, out var glamourerData);
|
_cachedData.GlamourerData.TryGetValue(objectKind, out var glamourerData);
|
||||||
|
|
||||||
if (objectKind == ObjectKind.Player)
|
if (objectKind == ObjectKind.Player)
|
||||||
{
|
{
|
||||||
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter.Address);
|
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter);
|
||||||
RequestedPenumbraRedraw = true;
|
RequestedPenumbraRedraw = true;
|
||||||
Logger.Debug(
|
Logger.Debug(
|
||||||
$"Request Redraw for {PlayerName}");
|
$"Request Redraw for {PlayerName}");
|
||||||
if (_ipcManager.CheckGlamourerApi() && !string.IsNullOrEmpty(glamourerData))
|
if (_ipcManager.CheckGlamourerApi() && !string.IsNullOrEmpty(glamourerData))
|
||||||
{
|
{
|
||||||
_ipcManager.GlamourerApplyAll(glamourerData, PlayerCharacter.Address);
|
_ipcManager.GlamourerApplyAll(glamourerData, PlayerCharacter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ipcManager.PenumbraRedraw(PlayerCharacter.Address);
|
_ipcManager.PenumbraRedraw(PlayerCharacter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.MinionOrMount)
|
else if (objectKind == ObjectKind.MinionOrMount)
|
||||||
{
|
{
|
||||||
var minionOrMount = ((Character*)PlayerCharacter.Address)->CompanionObject;
|
var minionOrMount = ((Character*)PlayerCharacter)->CompanionObject;
|
||||||
if (minionOrMount != null)
|
if (minionOrMount != null)
|
||||||
{
|
{
|
||||||
Logger.Debug($"Request Redraw for Minion/Mount");
|
Logger.Debug($"Request Redraw for Minion/Mount");
|
||||||
@@ -275,7 +275,7 @@ public class CachedPlayer
|
|||||||
else if (objectKind == ObjectKind.Pet)
|
else if (objectKind == ObjectKind.Pet)
|
||||||
{
|
{
|
||||||
int tick = 16;
|
int tick = 16;
|
||||||
var pet = _dalamudUtil.GetPet(PlayerCharacter.Address);
|
var pet = _dalamudUtil.GetPet(PlayerCharacter);
|
||||||
if (pet != IntPtr.Zero)
|
if (pet != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
var totalWait = 0;
|
var totalWait = 0;
|
||||||
@@ -302,7 +302,7 @@ public class CachedPlayer
|
|||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.Companion)
|
else if (objectKind == ObjectKind.Companion)
|
||||||
{
|
{
|
||||||
var companion = _dalamudUtil.GetCompanion(PlayerCharacter.Address);
|
var companion = _dalamudUtil.GetCompanion(PlayerCharacter);
|
||||||
if (companion != IntPtr.Zero)
|
if (companion != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.Debug("Request Redraw for Companion");
|
Logger.Debug("Request Redraw for Companion");
|
||||||
@@ -321,7 +321,7 @@ public class CachedPlayer
|
|||||||
|
|
||||||
private unsafe void RevertCustomizationData(ObjectKind objectKind)
|
private unsafe void RevertCustomizationData(ObjectKind objectKind)
|
||||||
{
|
{
|
||||||
if (PlayerCharacter is null) return;
|
if (PlayerCharacter == IntPtr.Zero) return;
|
||||||
|
|
||||||
if (objectKind == ObjectKind.Player)
|
if (objectKind == ObjectKind.Player)
|
||||||
{
|
{
|
||||||
@@ -332,12 +332,12 @@ public class CachedPlayer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ipcManager.PenumbraRedraw(PlayerCharacter.Address);
|
_ipcManager.PenumbraRedraw(PlayerCharacter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.MinionOrMount)
|
else if (objectKind == ObjectKind.MinionOrMount)
|
||||||
{
|
{
|
||||||
var minionOrMount = ((Character*)PlayerCharacter.Address)->CompanionObject;
|
var minionOrMount = ((Character*)PlayerCharacter)->CompanionObject;
|
||||||
if (minionOrMount != null)
|
if (minionOrMount != null)
|
||||||
{
|
{
|
||||||
_ipcManager.PenumbraRedraw((IntPtr)minionOrMount);
|
_ipcManager.PenumbraRedraw((IntPtr)minionOrMount);
|
||||||
@@ -345,7 +345,7 @@ public class CachedPlayer
|
|||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.Pet)
|
else if (objectKind == ObjectKind.Pet)
|
||||||
{
|
{
|
||||||
var pet = _dalamudUtil.GetPet(PlayerCharacter.Address);
|
var pet = _dalamudUtil.GetPet(PlayerCharacter);
|
||||||
if (pet != IntPtr.Zero)
|
if (pet != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
_ipcManager.PenumbraRedraw(pet);
|
_ipcManager.PenumbraRedraw(pet);
|
||||||
@@ -353,7 +353,7 @@ public class CachedPlayer
|
|||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.Companion)
|
else if (objectKind == ObjectKind.Companion)
|
||||||
{
|
{
|
||||||
var companion = _dalamudUtil.GetCompanion(PlayerCharacter.Address);
|
var companion = _dalamudUtil.GetCompanion(PlayerCharacter);
|
||||||
if (companion != IntPtr.Zero)
|
if (companion != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
_ipcManager.PenumbraRedraw(companion);
|
_ipcManager.PenumbraRedraw(companion);
|
||||||
@@ -370,12 +370,12 @@ public class CachedPlayer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Verbose("Restoring state for " + PlayerName);
|
Logger.Verbose("Restoring state for " + PlayerName);
|
||||||
_dalamudUtil.FrameworkUpdate -= DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.DelayedFrameworkUpdate -= DalamudUtilOnDelayedFrameworkUpdate;
|
||||||
_ipcManager.PenumbraRedrawEvent -= IpcManagerOnPenumbraRedrawEvent;
|
_ipcManager.PenumbraRedrawEvent -= IpcManagerOnPenumbraRedrawEvent;
|
||||||
_ipcManager.PenumbraRemoveTemporaryCollection(PlayerName);
|
_ipcManager.PenumbraRemoveTemporaryCollection(PlayerName);
|
||||||
_downloadCancellationTokenSource?.Cancel();
|
_downloadCancellationTokenSource?.Cancel();
|
||||||
_downloadCancellationTokenSource?.Dispose();
|
_downloadCancellationTokenSource?.Dispose();
|
||||||
if (PlayerCharacter != null && PlayerCharacter.IsValid())
|
if (PlayerCharacter != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
foreach (var item in _cachedData.FileReplacements)
|
foreach (var item in _cachedData.FileReplacements)
|
||||||
{
|
{
|
||||||
@@ -391,19 +391,19 @@ public class CachedPlayer
|
|||||||
{
|
{
|
||||||
_cachedData = new();
|
_cachedData = new();
|
||||||
PlayerName = string.Empty;
|
PlayerName = string.Empty;
|
||||||
PlayerCharacter = null;
|
PlayerCharacter = IntPtr.Zero;
|
||||||
IsVisible = false;
|
IsVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializePlayer(PlayerCharacter character, CharacterCacheDto? cache)
|
public void InitializePlayer(IntPtr character, string name, CharacterCacheDto? cache)
|
||||||
{
|
{
|
||||||
if (!_isDisposed) return;
|
if (!_isDisposed) return;
|
||||||
Logger.Debug("Initializing Player " + this + " has cache: " + (cache != null));
|
Logger.Debug("Initializing Player " + this + " has cache: " + (cache != null));
|
||||||
IsVisible = true;
|
IsVisible = true;
|
||||||
PlayerName = character.Name.ToString();
|
PlayerName = name;
|
||||||
PlayerCharacter = character;
|
PlayerCharacter = character;
|
||||||
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.DelayedFrameworkUpdate += DalamudUtilOnDelayedFrameworkUpdate;
|
||||||
_ipcManager.PenumbraRedrawEvent += IpcManagerOnPenumbraRedrawEvent;
|
_ipcManager.PenumbraRedrawEvent += IpcManagerOnPenumbraRedrawEvent;
|
||||||
_originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter);
|
_originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter);
|
||||||
_currentCharacterEquipment = new PlayerRelatedObject(ObjectKind.Player, IntPtr.Zero, IntPtr.Zero,
|
_currentCharacterEquipment = new PlayerRelatedObject(ObjectKind.Player, IntPtr.Zero, IntPtr.Zero,
|
||||||
@@ -415,12 +415,12 @@ public class CachedPlayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DalamudUtilOnFrameworkUpdate()
|
private void DalamudUtilOnDelayedFrameworkUpdate()
|
||||||
{
|
{
|
||||||
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized || !_apiController.IsConnected) return;
|
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized || !_apiController.IsConnected) return;
|
||||||
|
|
||||||
PlayerCharacter = _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName!);
|
PlayerCharacter = _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName!)?.Address ?? IntPtr.Zero;
|
||||||
if (PlayerCharacter == null)
|
if (PlayerCharacter == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
DisposePlayer();
|
DisposePlayer();
|
||||||
return;
|
return;
|
||||||
@@ -437,7 +437,7 @@ public class CachedPlayer
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return PlayerNameHash + ":" + PlayerName + ":HasChar " + (PlayerCharacter != null);
|
return PlayerNameHash + ":" + PlayerName + ":HasChar " + (PlayerCharacter != IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task? _penumbraRedrawEventTask;
|
private Task? _penumbraRedrawEventTask;
|
||||||
@@ -450,10 +450,10 @@ public class CachedPlayer
|
|||||||
|
|
||||||
_penumbraRedrawEventTask = Task.Run(() =>
|
_penumbraRedrawEventTask = Task.Run(() =>
|
||||||
{
|
{
|
||||||
PlayerCharacter = player;
|
PlayerCharacter = address;
|
||||||
using var cts = new CancellationTokenSource();
|
using var cts = new CancellationTokenSource();
|
||||||
cts.CancelAfter(TimeSpan.FromSeconds(5));
|
cts.CancelAfter(TimeSpan.FromSeconds(5));
|
||||||
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter.Address, cts.Token);
|
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter, cts.Token);
|
||||||
|
|
||||||
if (RequestedPenumbraRedraw == false)
|
if (RequestedPenumbraRedraw == false)
|
||||||
{
|
{
|
||||||
@@ -473,10 +473,10 @@ public class CachedPlayer
|
|||||||
{
|
{
|
||||||
Logger.Debug($"Player {PlayerName} changed, PenumbraRedraw is {RequestedPenumbraRedraw}");
|
Logger.Debug($"Player {PlayerName} changed, PenumbraRedraw is {RequestedPenumbraRedraw}");
|
||||||
_currentCharacterEquipment!.HasUnprocessedUpdate = false;
|
_currentCharacterEquipment!.HasUnprocessedUpdate = false;
|
||||||
if (!RequestedPenumbraRedraw && PlayerCharacter is not null)
|
if (!RequestedPenumbraRedraw && PlayerCharacter != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.Debug($"Saving new Glamourer data");
|
Logger.Debug($"Saving new Glamourer data");
|
||||||
_lastGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter!);
|
_lastGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
|||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
using MareSynchronos.WebAPI;
|
using MareSynchronos.WebAPI;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using Action = System.Action;
|
using Action = System.Action;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
@@ -87,14 +86,6 @@ namespace MareSynchronos.Managers
|
|||||||
_dalamudUtil.FrameworkUpdate += HandleActionQueue;
|
_dalamudUtil.FrameworkUpdate += HandleActionQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleActionQueue()
|
|
||||||
{
|
|
||||||
while (actionQueue.TryDequeue(out var action))
|
|
||||||
{
|
|
||||||
action();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResourceLoaded(IntPtr ptr, string arg1, string arg2)
|
private void ResourceLoaded(IntPtr ptr, string arg1, string arg2)
|
||||||
{
|
{
|
||||||
if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, true, System.Globalization.CultureInfo.InvariantCulture) != 0)
|
if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, true, System.Globalization.CultureInfo.InvariantCulture) != 0)
|
||||||
@@ -104,6 +95,16 @@ namespace MareSynchronos.Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleActionQueue()
|
||||||
|
{
|
||||||
|
if (actionQueue.TryDequeue(out var action))
|
||||||
|
{
|
||||||
|
if (action == null) return;
|
||||||
|
Logger.Debug("Execution action in queue: " + action.Method);
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public event VoidDelegate? PenumbraInitialized;
|
public event VoidDelegate? PenumbraInitialized;
|
||||||
public event VoidDelegate? PenumbraDisposed;
|
public event VoidDelegate? PenumbraDisposed;
|
||||||
public event PenumbraRedrawEvent? PenumbraRedrawEvent;
|
public event PenumbraRedrawEvent? PenumbraRedrawEvent;
|
||||||
@@ -168,38 +169,51 @@ namespace MareSynchronos.Managers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerApplyOnlyEquipment(string customization, GameObject character)
|
public void GlamourerApplyOnlyEquipment(string customization, IntPtr character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||||
actionQueue.Enqueue(() =>
|
actionQueue.Enqueue(() =>
|
||||||
{
|
{
|
||||||
Logger.Verbose("Glamourer apply only equipment to " + character);
|
var gameObj = _dalamudUtil.CreateGameObject(character);
|
||||||
_glamourerApplyOnlyEquipment!.InvokeAction(customization, character);
|
if (gameObj != null)
|
||||||
|
{
|
||||||
|
Logger.Verbose("Glamourer apply only equipment to " + character.ToString("X"));
|
||||||
|
_glamourerApplyOnlyEquipment!.InvokeAction(customization, gameObj);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerApplyOnlyCustomization(string customization, GameObject character)
|
public void GlamourerApplyOnlyCustomization(string customization, IntPtr character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||||
actionQueue.Enqueue(() =>
|
actionQueue.Enqueue(() =>
|
||||||
{
|
{
|
||||||
Logger.Verbose("Glamourer apply only customization to " + character);
|
var gameObj = _dalamudUtil.CreateGameObject(character);
|
||||||
_glamourerApplyOnlyCustomization!.InvokeAction(customization, character);
|
if (gameObj != null)
|
||||||
|
{
|
||||||
|
Logger.Verbose("Glamourer apply only customization to " + character.ToString("X"));
|
||||||
|
_glamourerApplyOnlyCustomization!.InvokeAction(customization, gameObj);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GlamourerGetCharacterCustomization(GameObject character)
|
public string GlamourerGetCharacterCustomization(IntPtr character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi()) return string.Empty;
|
if (!CheckGlamourerApi()) return string.Empty;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var glamourerString = _glamourerGetAllCustomization!.InvokeFunc(character);
|
var gameObj = _dalamudUtil.CreateGameObject(character);
|
||||||
|
if (gameObj != null)
|
||||||
|
{
|
||||||
|
var glamourerString = _glamourerGetAllCustomization!.InvokeFunc(gameObj);
|
||||||
byte[] bytes = Convert.FromBase64String(glamourerString);
|
byte[] bytes = Convert.FromBase64String(glamourerString);
|
||||||
// ignore transparency
|
// ignore transparency
|
||||||
bytes[88] = 128;
|
bytes[88] = 128;
|
||||||
bytes[89] = 63;
|
bytes[89] = 63;
|
||||||
return Convert.ToBase64String(bytes);
|
return Convert.ToBase64String(bytes);
|
||||||
}
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@@ -212,14 +226,6 @@ namespace MareSynchronos.Managers
|
|||||||
actionQueue.Enqueue(() => _glamourerRevertCustomization!.InvokeAction(character));
|
actionQueue.Enqueue(() => _glamourerRevertCustomization!.InvokeAction(character));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string PenumbraCreateTemporaryCollection(string characterName)
|
|
||||||
{
|
|
||||||
if (!CheckPenumbraApi()) return string.Empty;
|
|
||||||
Logger.Verbose("Creating temp collection for " + characterName);
|
|
||||||
var ret = _penumbraCreateTemporaryCollection.InvokeFunc("MareSynchronos", characterName, true);
|
|
||||||
return ret.Item2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string PenumbraGetMetaManipulations()
|
public string PenumbraGetMetaManipulations()
|
||||||
{
|
{
|
||||||
if (!CheckPenumbraApi()) return string.Empty;
|
if (!CheckPenumbraApi()) return string.Empty;
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
private readonly PlayerManager _playerManager;
|
private readonly PlayerManager _playerManager;
|
||||||
private readonly ConcurrentDictionary<string, CachedPlayer> _onlineCachedPlayers = new();
|
private readonly ConcurrentDictionary<string, CachedPlayer> _onlineCachedPlayers = new();
|
||||||
private readonly Dictionary<string, CharacterCacheDto> _temporaryStoredCharacterCache = new();
|
private readonly ConcurrentDictionary<string, CharacterCacheDto> _temporaryStoredCharacterCache = new();
|
||||||
private readonly Dictionary<CachedPlayer, CancellationTokenSource> _playerTokenDisposal = new();
|
private readonly ConcurrentDictionary<CachedPlayer, CancellationTokenSource> _playerTokenDisposal = new();
|
||||||
|
|
||||||
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Where(p => p.Value.PlayerCharacter != null)
|
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Select(p => p.Value).Where(p => p.PlayerCharacter != null)
|
||||||
.Select(p => p.Value.PlayerNameHash).ToList();
|
.Select(p => p.PlayerNameHash).ToList();
|
||||||
private DateTime _lastPlayerObjectCheck = DateTime.Now;
|
private DateTime _lastPlayerObjectCheck = DateTime.Now;
|
||||||
|
|
||||||
public OnlinePlayerManager(Framework framework, ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager, PlayerManager playerManager)
|
public OnlinePlayerManager(Framework framework, ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager, PlayerManager playerManager)
|
||||||
@@ -58,8 +58,7 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
|
|
||||||
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
|
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
var visiblePlayer = _onlineCachedPlayers.Select(v => v.Value).SingleOrDefault(c => c.IsVisible && c.PlayerNameHash == e.CharacterNameHash);
|
if (_onlineCachedPlayers.TryGetValue(e.CharacterNameHash, out var visiblePlayer) && visiblePlayer.IsVisible)
|
||||||
if (visiblePlayer != null)
|
|
||||||
{
|
{
|
||||||
Logger.Debug("Received data and applying to " + e.CharacterNameHash);
|
Logger.Debug("Received data and applying to " + e.CharacterNameHash);
|
||||||
visiblePlayer.ApplyCharacterData(e.CharacterData);
|
visiblePlayer.ApplyCharacterData(e.CharacterData);
|
||||||
@@ -99,14 +98,14 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
|
|
||||||
private void IpcManagerOnPenumbraDisposed()
|
private void IpcManagerOnPenumbraDisposed()
|
||||||
{
|
{
|
||||||
DisposeAllPlayers();
|
DisposePlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeAllPlayers()
|
private void DisposePlayers()
|
||||||
{
|
{
|
||||||
foreach (var entry in _onlineCachedPlayers)
|
foreach (var kvp in _onlineCachedPlayers)
|
||||||
{
|
{
|
||||||
entry.Value.DisposePlayer();
|
kvp.Value.DisposePlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,11 +118,11 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
public void AddInitialPairs(List<string> apiTaskResult)
|
public void AddInitialPairs(List<string> apiTaskResult)
|
||||||
{
|
{
|
||||||
_onlineCachedPlayers.Clear();
|
_onlineCachedPlayers.Clear();
|
||||||
foreach (var result in apiTaskResult)
|
foreach (var hash in apiTaskResult)
|
||||||
{
|
{
|
||||||
_onlineCachedPlayers.TryAdd(result, CreateCachedPlayer(result));
|
_onlineCachedPlayers.TryAdd(hash, CreateCachedPlayer(hash));
|
||||||
}
|
}
|
||||||
Logger.Verbose("Online and paired users: " + string.Join(Environment.NewLine, _onlineCachedPlayers));
|
Logger.Verbose("Online and paired users: " + string.Join(Environment.NewLine, _onlineCachedPlayers.Select(k => k.Key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -149,7 +148,7 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
|
|
||||||
private void RestoreAllCharacters()
|
private void RestoreAllCharacters()
|
||||||
{
|
{
|
||||||
DisposeAllPlayers();
|
DisposePlayers();
|
||||||
_onlineCachedPlayers.Clear();
|
_onlineCachedPlayers.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,10 +181,10 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
|
|
||||||
private void AddPlayer(string characterNameHash)
|
private void AddPlayer(string characterNameHash)
|
||||||
{
|
{
|
||||||
if (_onlineCachedPlayers.ContainsKey(characterNameHash))
|
if (_onlineCachedPlayers.TryGetValue(characterNameHash, out var cachedPlayer))
|
||||||
{
|
{
|
||||||
PushCharacterData(new List<string>() { characterNameHash });
|
PushCharacterData(new List<string>() { characterNameHash });
|
||||||
_playerTokenDisposal.TryGetValue(_onlineCachedPlayers[characterNameHash], out var cancellationTokenSource);
|
_playerTokenDisposal.TryGetValue(cachedPlayer, out var cancellationTokenSource);
|
||||||
cancellationTokenSource?.Cancel();
|
cancellationTokenSource?.Cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -217,7 +216,7 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
cachedPlayer.DisposePlayer();
|
cachedPlayer.DisposePlayer();
|
||||||
_onlineCachedPlayers.TryRemove(cachedPlayer.PlayerNameHash, out _);
|
_onlineCachedPlayers.TryRemove(characterHash, out _);
|
||||||
}, token);
|
}, token);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -237,25 +236,21 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
foreach (var pChar in playerCharacters)
|
foreach (var pChar in playerCharacters)
|
||||||
{
|
{
|
||||||
var hashedName = Crypto.GetHash256(pChar);
|
var hashedName = Crypto.GetHash256(pChar);
|
||||||
if (_onlineCachedPlayers.TryGetValue(hashedName, out var existingCachedPlayer) && !string.IsNullOrEmpty(existingCachedPlayer.PlayerName))
|
if (_onlineCachedPlayers.TryGetValue(hashedName, out var existingPlayer) && !string.IsNullOrEmpty(existingPlayer.PlayerName))
|
||||||
{
|
{
|
||||||
existingCachedPlayer.IsVisible = true;
|
existingPlayer.IsVisible = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_temporaryStoredCharacterCache.TryGetValue(hashedName, out var cache))
|
if (existingPlayer != null)
|
||||||
{
|
{
|
||||||
_temporaryStoredCharacterCache.Remove(hashedName);
|
_temporaryStoredCharacterCache.TryRemove(hashedName, out var cache);
|
||||||
}
|
existingPlayer.InitializePlayer(pChar.Address, pChar.Name.ToString(), cache);
|
||||||
|
|
||||||
if (_onlineCachedPlayers.TryGetValue(hashedName, out var playerToInit))
|
|
||||||
{
|
|
||||||
playerToInit.InitializePlayer(pChar, cache);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newlyVisiblePlayers = _onlineCachedPlayers.Values
|
var newlyVisiblePlayers = _onlineCachedPlayers.Select(v => v.Value)
|
||||||
.Where(p => p.PlayerCharacter != null && p.IsVisible && !p.WasVisible).Select(p => p.PlayerNameHash)
|
.Where(p => p.PlayerCharacter != IntPtr.Zero && p.IsVisible && !p.WasVisible).Select(p => p.PlayerNameHash)
|
||||||
.ToList();
|
.ToList();
|
||||||
if (newlyVisiblePlayers.Any())
|
if (newlyVisiblePlayers.Any())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace MareSynchronos.Managers
|
|||||||
private readonly Dictionary<ObjectKind, Func<bool>> objectKindsToUpdate = new();
|
private readonly Dictionary<ObjectKind, Func<bool>> objectKindsToUpdate = new();
|
||||||
|
|
||||||
private CancellationTokenSource? _playerChangedCts = new();
|
private CancellationTokenSource? _playerChangedCts = new();
|
||||||
private DateTime _lastPlayerObjectCheck;
|
|
||||||
|
|
||||||
private List<PlayerRelatedObject> playerRelatedObjects = new List<PlayerRelatedObject>();
|
private List<PlayerRelatedObject> playerRelatedObjects = new List<PlayerRelatedObject>();
|
||||||
|
|
||||||
@@ -44,8 +43,8 @@ namespace MareSynchronos.Managers
|
|||||||
_transientResourceManager = transientResourceManager;
|
_transientResourceManager = transientResourceManager;
|
||||||
_apiController.Connected += ApiControllerOnConnected;
|
_apiController.Connected += ApiControllerOnConnected;
|
||||||
_apiController.Disconnected += ApiController_Disconnected;
|
_apiController.Disconnected += ApiController_Disconnected;
|
||||||
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
|
||||||
_transientResourceManager.TransientResourceLoaded += HandleTransientResourceLoad;
|
_transientResourceManager.TransientResourceLoaded += HandleTransientResourceLoad;
|
||||||
|
_dalamudUtil.DelayedFrameworkUpdate += DalamudUtilOnDelayedFrameworkUpdate;
|
||||||
|
|
||||||
Logger.Debug("Watching Player, ApiController is Connected: " + _apiController.IsConnected);
|
Logger.Debug("Watching Player, ApiController is Connected: " + _apiController.IsConnected);
|
||||||
if (_apiController.IsConnected)
|
if (_apiController.IsConnected)
|
||||||
@@ -83,26 +82,22 @@ namespace MareSynchronos.Managers
|
|||||||
_apiController.Disconnected -= ApiController_Disconnected;
|
_apiController.Disconnected -= ApiController_Disconnected;
|
||||||
|
|
||||||
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
|
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
|
||||||
_dalamudUtil.FrameworkUpdate -= DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.DelayedFrameworkUpdate -= DalamudUtilOnDelayedFrameworkUpdate;
|
||||||
|
|
||||||
_transientResourceManager.TransientResourceLoaded -= HandleTransientResourceLoad;
|
_transientResourceManager.TransientResourceLoaded -= HandleTransientResourceLoad;
|
||||||
|
|
||||||
_playerChangedCts?.Cancel();
|
_playerChangedCts?.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void DalamudUtilOnFrameworkUpdate()
|
private unsafe void DalamudUtilOnDelayedFrameworkUpdate()
|
||||||
{
|
{
|
||||||
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized) return;
|
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized) return;
|
||||||
|
|
||||||
//if (DateTime.Now < _lastPlayerObjectCheck.AddSeconds(0.25)) return;
|
|
||||||
|
|
||||||
playerRelatedObjects.ForEach(k => k.CheckAndUpdateObject());
|
playerRelatedObjects.ForEach(k => k.CheckAndUpdateObject());
|
||||||
if (playerRelatedObjects.Any(c => c.HasUnprocessedUpdate && !c.IsProcessing))
|
if (playerRelatedObjects.Any(c => c.HasUnprocessedUpdate && !c.IsProcessing))
|
||||||
{
|
{
|
||||||
OnPlayerOrAttachedObjectsChanged();
|
OnPlayerOrAttachedObjectsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
//_lastPlayerObjectCheck = DateTime.Now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApiControllerOnConnected()
|
private void ApiControllerOnConnected()
|
||||||
|
|||||||
@@ -36,6 +36,23 @@ namespace MareSynchronos.UI
|
|||||||
public CompactUi(WindowSystem windowSystem,
|
public CompactUi(WindowSystem windowSystem,
|
||||||
UiShared uiShared, Configuration configuration, ApiController apiController) : base("###MareSynchronosMainUI")
|
UiShared uiShared, Configuration configuration, ApiController apiController) : base("###MareSynchronosMainUI")
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
string dateTime = "DEV VERSION";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dateTime = VariousExtensions.GetLinkerTime(Assembly.GetCallingAssembly()).ToString("yyyyMMddHHmmss");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Warn("Could not get assembly name");
|
||||||
|
Logger.Warn(ex.Message);
|
||||||
|
Logger.Warn(ex.StackTrace);
|
||||||
|
}
|
||||||
|
this.WindowName = "Mare Synchronos " + dateTime + "###MareSynchronosMainUI";
|
||||||
|
#else
|
||||||
|
this.WindowName = "Mare Synchronos " + Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
|
#endif
|
||||||
Logger.Verbose("Creating " + nameof(CompactUi));
|
Logger.Verbose("Creating " + nameof(CompactUi));
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Dalamud.Game;
|
|||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
||||||
|
|
||||||
@@ -30,6 +29,8 @@ namespace MareSynchronos.Utils
|
|||||||
public event FrameworkUpdate? FrameworkUpdate;
|
public event FrameworkUpdate? FrameworkUpdate;
|
||||||
public event ClassJobChanged? ClassJobChanged;
|
public event ClassJobChanged? ClassJobChanged;
|
||||||
private uint? classJobId = 0;
|
private uint? classJobId = 0;
|
||||||
|
public event FrameworkUpdate? DelayedFrameworkUpdate;
|
||||||
|
private DateTime _delayedFrameworkUpdateCheck = DateTime.Now;
|
||||||
|
|
||||||
public unsafe bool IsGameObjectPresent(IntPtr key)
|
public unsafe bool IsGameObjectPresent(IntPtr key)
|
||||||
{
|
{
|
||||||
@@ -61,12 +62,36 @@ namespace MareSynchronos.Utils
|
|||||||
|
|
||||||
private void FrameworkOnUpdate(Framework framework)
|
private void FrameworkOnUpdate(Framework framework)
|
||||||
{
|
{
|
||||||
if(_clientState.LocalPlayer != null && _clientState.LocalPlayer.ClassJob.Id != classJobId)
|
foreach (FrameworkUpdate frameworkInvocation in (FrameworkUpdate?.GetInvocationList() ?? Array.Empty<FrameworkUpdate>()).Cast<FrameworkUpdate>())
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
frameworkInvocation.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Warn(ex.Message);
|
||||||
|
Logger.Warn(ex.StackTrace ?? string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
classJobId = _clientState.LocalPlayer.ClassJob.Id;
|
classJobId = _clientState.LocalPlayer.ClassJob.Id;
|
||||||
ClassJobChanged?.Invoke();
|
ClassJobChanged?.Invoke();
|
||||||
|
|
||||||
|
if (DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(0.25)) return;
|
||||||
|
foreach (FrameworkUpdate frameworkInvocation in (DelayedFrameworkUpdate?.GetInvocationList() ?? Array.Empty<FrameworkUpdate>()).Cast<FrameworkUpdate>())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
frameworkInvocation.Invoke();
|
||||||
}
|
}
|
||||||
FrameworkUpdate?.Invoke();
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Warn(ex.Message);
|
||||||
|
Logger.Warn(ex.StackTrace ?? string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_delayedFrameworkUpdateCheck = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClientStateOnLogout(object? sender, EventArgs e)
|
private void ClientStateOnLogout(object? sender, EventArgs e)
|
||||||
|
|||||||
Reference in New Issue
Block a user