add some preliminary vfx work
This commit is contained in:
@@ -22,13 +22,15 @@ public class CharacterDataFactory
|
|||||||
{
|
{
|
||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
|
private readonly TransientResourceManager transientResourceManager;
|
||||||
|
|
||||||
public CharacterDataFactory(DalamudUtil dalamudUtil, IpcManager ipcManager)
|
public CharacterDataFactory(DalamudUtil dalamudUtil, IpcManager ipcManager, TransientResourceManager transientResourceManager)
|
||||||
{
|
{
|
||||||
Logger.Verbose("Creating " + nameof(CharacterDataFactory));
|
Logger.Verbose("Creating " + nameof(CharacterDataFactory));
|
||||||
|
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
|
this.transientResourceManager = transientResourceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharacterData BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer, CancellationToken token)
|
public CharacterData BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer, CancellationToken token)
|
||||||
@@ -167,6 +169,26 @@ public class CharacterDataFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddReplacement(string varPath, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0)
|
||||||
|
{
|
||||||
|
if (varPath.IsNullOrEmpty()) return;
|
||||||
|
|
||||||
|
//Logger.Verbose("Adding File Replacement for Texture " + texPath);
|
||||||
|
|
||||||
|
if (cache.FileReplacements.ContainsKey(objectKind))
|
||||||
|
{
|
||||||
|
if (cache.FileReplacements[objectKind].Any(c => c.GamePaths.Contains(varPath)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var variousReplacement = CreateFileReplacement(varPath, false);
|
||||||
|
DebugPrint(variousReplacement, objectKind, "Various", inheritanceLevel);
|
||||||
|
|
||||||
|
cache.AddFileReplacement(objectKind, variousReplacement);
|
||||||
|
}
|
||||||
|
|
||||||
private void AddReplacementsFromTexture(string texPath, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0, bool doNotReverseResolve = true)
|
private void AddReplacementsFromTexture(string texPath, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0, bool doNotReverseResolve = true)
|
||||||
{
|
{
|
||||||
if (texPath.IsNullOrEmpty()) return;
|
if (texPath.IsNullOrEmpty()) return;
|
||||||
@@ -233,6 +255,11 @@ public class CharacterDataFactory
|
|||||||
AddReplacementsFromRenderModel(mdl, objectKind, previousData, 0);
|
AddReplacementsFromRenderModel(mdl, objectKind, previousData, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var item in previousData.FileReplacements[objectKind])
|
||||||
|
{
|
||||||
|
transientResourceManager.RemoveTransientResource((IntPtr)human, item);
|
||||||
|
}
|
||||||
|
|
||||||
if (objectKind == ObjectKind.Player)
|
if (objectKind == ObjectKind.Player)
|
||||||
{
|
{
|
||||||
var weaponObject = (Weapon*)((Object*)human)->ChildObject;
|
var weaponObject = (Weapon*)((Object*)human)->ChildObject;
|
||||||
@@ -243,11 +270,33 @@ public class CharacterDataFactory
|
|||||||
|
|
||||||
AddReplacementsFromRenderModel(mainHandWeapon, objectKind, previousData, 0);
|
AddReplacementsFromRenderModel(mainHandWeapon, objectKind, previousData, 0);
|
||||||
|
|
||||||
|
foreach (var item in previousData.FileReplacements[objectKind])
|
||||||
|
{
|
||||||
|
transientResourceManager.RemoveTransientResource((IntPtr)weaponObject, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in transientResourceManager.GetTransientResources((IntPtr)weaponObject))
|
||||||
|
{
|
||||||
|
Logger.Verbose("Found transient weapon resource: " + item);
|
||||||
|
AddReplacementsFromTexture(item, objectKind, previousData, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (weaponObject->NextSibling != (IntPtr)weaponObject)
|
if (weaponObject->NextSibling != (IntPtr)weaponObject)
|
||||||
{
|
{
|
||||||
var offHandWeapon = ((Weapon*)weaponObject->NextSibling)->WeaponRenderModel->RenderModel;
|
var offHandWeapon = ((Weapon*)weaponObject->NextSibling)->WeaponRenderModel->RenderModel;
|
||||||
|
|
||||||
AddReplacementsFromRenderModel(offHandWeapon, objectKind, previousData, 1);
|
AddReplacementsFromRenderModel(offHandWeapon, objectKind, previousData, 1);
|
||||||
|
|
||||||
|
foreach (var item in previousData.FileReplacements[objectKind])
|
||||||
|
{
|
||||||
|
transientResourceManager.RemoveTransientResource((IntPtr)offHandWeapon, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in transientResourceManager.GetTransientResources((IntPtr)weaponObject))
|
||||||
|
{
|
||||||
|
Logger.Verbose("Found transient offhand weapon resource: " + item);
|
||||||
|
AddReplacement(item, objectKind, previousData, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,11 +317,21 @@ public class CharacterDataFactory
|
|||||||
{
|
{
|
||||||
Logger.Warn("Could not get Legacy Body Decal Data");
|
Logger.Warn("Could not get Legacy Body Decal Data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var item in previousData.FileReplacements[objectKind])
|
||||||
|
{
|
||||||
|
transientResourceManager.RemoveTransientResource((IntPtr)human, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in transientResourceManager.GetTransientResources((IntPtr)human))
|
||||||
|
{
|
||||||
|
Logger.Verbose("Found transient resource: " + item);
|
||||||
|
AddReplacement(item, objectKind, previousData, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
st.Stop();
|
st.Stop();
|
||||||
Logger.Verbose("Building " + objectKind + " Data took " + st.Elapsed);
|
Logger.Verbose("Building " + objectKind + " Data took " + st.Elapsed);
|
||||||
|
|
||||||
return previousData;
|
return previousData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,8 +341,6 @@ public class CharacterDataFactory
|
|||||||
|
|
||||||
string skeletonPath = $"chara/human/c{raceSexIdString}/skeleton/base/b0001/skl_c{raceSexIdString}b0001.sklb";
|
string skeletonPath = $"chara/human/c{raceSexIdString}/skeleton/base/b0001/skl_c{raceSexIdString}b0001.sklb";
|
||||||
|
|
||||||
//Logger.Verbose("Adding File Replacement for Skeleton " + skeletonPath);
|
|
||||||
|
|
||||||
var replacement = CreateFileReplacement(skeletonPath, true);
|
var replacement = CreateFileReplacement(skeletonPath, true);
|
||||||
cache.AddFileReplacement(objectKind, replacement);
|
cache.AddFileReplacement(objectKind, replacement);
|
||||||
|
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ namespace MareSynchronos.Managers
|
|||||||
{
|
{
|
||||||
PluginLog.Verbose("Removed: " + item);
|
PluginLog.Verbose("Removed: " + item);
|
||||||
|
|
||||||
db.RemoveRange(db.FileCaches.Where(f => f.Filepath.ToLowerInvariant() == item.ToLowerInvariant()));
|
db.RemoveRange(db.FileCaches.Where(f => f.Filepath.ToLower() == item.ToLowerInvariant()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -211,7 +211,7 @@ namespace MareSynchronos.Managers
|
|||||||
var fileCache = Create(item, _rescanTaskCancellationTokenSource.Token);
|
var fileCache = Create(item, _rescanTaskCancellationTokenSource.Token);
|
||||||
if (fileCache != null)
|
if (fileCache != null)
|
||||||
{
|
{
|
||||||
db.RemoveRange(db.FileCaches.Where(f => f.Filepath.ToLowerInvariant() == fileCache.Filepath.ToLowerInvariant()));
|
db.RemoveRange(db.FileCaches.Where(f => f.Filepath.ToLower() == fileCache.Filepath.ToLowerInvariant()));
|
||||||
await db.AddAsync(fileCache, _rescanTaskCancellationTokenSource.Token);
|
await db.AddAsync(fileCache, _rescanTaskCancellationTokenSource.Token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using MareSynchronos.WebAPI;
|
|||||||
namespace MareSynchronos.Managers
|
namespace MareSynchronos.Managers
|
||||||
{
|
{
|
||||||
public delegate void PenumbraRedrawEvent(IntPtr address, int objTblIdx);
|
public delegate void PenumbraRedrawEvent(IntPtr address, int objTblIdx);
|
||||||
|
public delegate void PenumbraResourceLoadEvent(IntPtr drawObject, string gamePath, string filePath);
|
||||||
public class IpcManager : IDisposable
|
public class IpcManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
|
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
|
||||||
@@ -31,7 +32,7 @@ namespace MareSynchronos.Managers
|
|||||||
private readonly ICallGateSubscriber<string, string[]>? _reverseResolvePlayer;
|
private readonly ICallGateSubscriber<string, string[]>? _reverseResolvePlayer;
|
||||||
private readonly ICallGateSubscriber<string, string, Dictionary<string, string>, string, int, int>
|
private readonly ICallGateSubscriber<string, string, Dictionary<string, string>, string, int, int>
|
||||||
_penumbraSetTemporaryMod;
|
_penumbraSetTemporaryMod;
|
||||||
private readonly ICallGateSubscriber<string, string, string> _penumbraPlayerPathResolved;
|
private readonly ICallGateSubscriber<IntPtr, string, string, string> _penumbraResourceLoaded;
|
||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
|
|
||||||
public IpcManager(DalamudPluginInterface pi, DalamudUtil dalamudUtil)
|
public IpcManager(DalamudPluginInterface pi, DalamudUtil dalamudUtil)
|
||||||
@@ -56,9 +57,9 @@ namespace MareSynchronos.Managers
|
|||||||
_glamourerApplyOnlyCustomization = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyCustomizationToCharacter");
|
_glamourerApplyOnlyCustomization = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyCustomizationToCharacter");
|
||||||
_glamourerApplyOnlyEquipment = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyEquipmentToCharacter");
|
_glamourerApplyOnlyEquipment = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyEquipmentToCharacter");
|
||||||
_glamourerRevertCustomization = pi.GetIpcSubscriber<GameObject?, object>("Glamourer.RevertCharacter");
|
_glamourerRevertCustomization = pi.GetIpcSubscriber<GameObject?, object>("Glamourer.RevertCharacter");
|
||||||
_penumbraPlayerPathResolved = pi.GetIpcSubscriber<string, string, string>("Penumbra.PlayerFileResourceResolved");
|
_penumbraResourceLoaded = pi.GetIpcSubscriber<IntPtr, string, string, string>("Penumbra.ResourceLoaded");
|
||||||
|
|
||||||
_penumbraPlayerPathResolved.Subscribe(PlayerPathResolved);
|
_penumbraResourceLoaded.Subscribe(ResourceLoaded);
|
||||||
_penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
_penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
||||||
_penumbraInit.Subscribe(PenumbraInit);
|
_penumbraInit.Subscribe(PenumbraInit);
|
||||||
_penumbraDispose.Subscribe(PenumbraDispose);
|
_penumbraDispose.Subscribe(PenumbraDispose);
|
||||||
@@ -81,14 +82,19 @@ namespace MareSynchronos.Managers
|
|||||||
this._dalamudUtil = dalamudUtil;
|
this._dalamudUtil = dalamudUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayerPathResolved(string arg1, string arg2)
|
private void ResourceLoaded(IntPtr ptr, string arg1, string arg2)
|
||||||
{
|
{
|
||||||
Logger.Debug($"Resolved {arg1} => {arg2}");
|
if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, true, System.Globalization.CultureInfo.InvariantCulture) != 0)
|
||||||
|
{
|
||||||
|
PenumbraResourceLoadEvent?.Invoke(ptr, arg1, arg2);
|
||||||
|
//Logger.Debug($"Resolved {ptr:X}: {arg1} => {arg2}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public event VoidDelegate? PenumbraInitialized;
|
public event VoidDelegate? PenumbraInitialized;
|
||||||
public event VoidDelegate? PenumbraDisposed;
|
public event VoidDelegate? PenumbraDisposed;
|
||||||
public event PenumbraRedrawEvent? PenumbraRedrawEvent;
|
public event PenumbraRedrawEvent? PenumbraRedrawEvent;
|
||||||
|
public event PenumbraResourceLoadEvent? PenumbraResourceLoadEvent;
|
||||||
|
|
||||||
public bool Initialized => CheckPenumbraApi();
|
public bool Initialized => CheckPenumbraApi();
|
||||||
public bool CheckGlamourerApi()
|
public bool CheckGlamourerApi()
|
||||||
@@ -122,6 +128,7 @@ namespace MareSynchronos.Managers
|
|||||||
_penumbraDispose.Unsubscribe(PenumbraDispose);
|
_penumbraDispose.Unsubscribe(PenumbraDispose);
|
||||||
_penumbraInit.Unsubscribe(PenumbraInit);
|
_penumbraInit.Unsubscribe(PenumbraInit);
|
||||||
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
||||||
|
_penumbraResourceLoaded.Unsubscribe(ResourceLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerApplyAll(string? customization, IntPtr obj)
|
public void GlamourerApplyAll(string? customization, IntPtr obj)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace MareSynchronos.Managers
|
|||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly CharacterDataFactory _characterDataFactory;
|
private readonly CharacterDataFactory _characterDataFactory;
|
||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
|
private readonly TransientResourceManager _transientResourceManager;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
public event PlayerHasChanged? PlayerHasChanged;
|
public event PlayerHasChanged? PlayerHasChanged;
|
||||||
public CharacterCacheDto? LastCreatedCharacterData { get; private set; }
|
public CharacterCacheDto? LastCreatedCharacterData { get; private set; }
|
||||||
@@ -34,7 +35,7 @@ namespace MareSynchronos.Managers
|
|||||||
private List<PlayerRelatedObject> playerRelatedObjects = new List<PlayerRelatedObject>();
|
private List<PlayerRelatedObject> playerRelatedObjects = new List<PlayerRelatedObject>();
|
||||||
|
|
||||||
public unsafe PlayerManager(ApiController apiController, IpcManager ipcManager,
|
public unsafe PlayerManager(ApiController apiController, IpcManager ipcManager,
|
||||||
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil)
|
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil, TransientResourceManager transientResourceManager)
|
||||||
{
|
{
|
||||||
Logger.Verbose("Creating " + nameof(PlayerManager));
|
Logger.Verbose("Creating " + nameof(PlayerManager));
|
||||||
|
|
||||||
@@ -42,10 +43,11 @@ namespace MareSynchronos.Managers
|
|||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
_characterDataFactory = characterDataFactory;
|
_characterDataFactory = characterDataFactory;
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
|
_transientResourceManager = transientResourceManager;
|
||||||
_apiController.Connected += ApiControllerOnConnected;
|
_apiController.Connected += ApiControllerOnConnected;
|
||||||
_apiController.Disconnected += ApiController_Disconnected;
|
_apiController.Disconnected += ApiController_Disconnected;
|
||||||
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
||||||
|
_transientResourceManager.TransientResourceLoaded += HandleTransientResourceLoad;
|
||||||
|
|
||||||
Logger.Debug("Watching Player, ApiController is Connected: " + _apiController.IsConnected);
|
Logger.Debug("Watching Player, ApiController is Connected: " + _apiController.IsConnected);
|
||||||
if (_apiController.IsConnected)
|
if (_apiController.IsConnected)
|
||||||
@@ -63,6 +65,19 @@ namespace MareSynchronos.Managers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HandleTransientResourceLoad(IntPtr drawObj)
|
||||||
|
{
|
||||||
|
foreach (var obj in playerRelatedObjects)
|
||||||
|
{
|
||||||
|
if (obj.DrawObjectAddress == drawObj && !obj.HasUnprocessedUpdate)
|
||||||
|
{
|
||||||
|
obj.HasUnprocessedUpdate = true;
|
||||||
|
OnPlayerOrAttachedObjectsChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Logger.Verbose("Disposing " + nameof(PlayerManager));
|
Logger.Verbose("Disposing " + nameof(PlayerManager));
|
||||||
@@ -72,13 +87,17 @@ namespace MareSynchronos.Managers
|
|||||||
|
|
||||||
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
|
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
|
||||||
_dalamudUtil.FrameworkUpdate -= DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.FrameworkUpdate -= DalamudUtilOnFrameworkUpdate;
|
||||||
|
|
||||||
|
_transientResourceManager.TransientResourceLoaded -= HandleTransientResourceLoad;
|
||||||
|
|
||||||
|
_playerChangedCts?.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void DalamudUtilOnFrameworkUpdate()
|
private unsafe void DalamudUtilOnFrameworkUpdate()
|
||||||
{
|
{
|
||||||
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized) return;
|
//if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized) return;
|
||||||
|
|
||||||
if (DateTime.Now < _lastPlayerObjectCheck.AddSeconds(0.25)) 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))
|
||||||
@@ -86,7 +105,7 @@ namespace MareSynchronos.Managers
|
|||||||
OnPlayerOrAttachedObjectsChanged();
|
OnPlayerOrAttachedObjectsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastPlayerObjectCheck = DateTime.Now;
|
//_lastPlayerObjectCheck = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApiControllerOnConnected()
|
private void ApiControllerOnConnected()
|
||||||
@@ -119,6 +138,7 @@ namespace MareSynchronos.Managers
|
|||||||
|
|
||||||
while (!PermanentDataCache.IsReady && !token.IsCancellationRequested)
|
while (!PermanentDataCache.IsReady && !token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
|
Logger.Verbose("Waiting until cache is ready");
|
||||||
await Task.Delay(50, token);
|
await Task.Delay(50, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
87
MareSynchronos/Managers/TransientResourceManager.cs
Normal file
87
MareSynchronos/Managers/TransientResourceManager.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
using MareSynchronos.Models;
|
||||||
|
using MareSynchronos.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MareSynchronos.Managers
|
||||||
|
{
|
||||||
|
public delegate void TransientResourceLoadedEvent(IntPtr drawObject);
|
||||||
|
|
||||||
|
public class TransientResourceManager : IDisposable
|
||||||
|
{
|
||||||
|
private readonly IpcManager manager;
|
||||||
|
private readonly DalamudUtil dalamudUtil;
|
||||||
|
public event TransientResourceLoadedEvent? TransientResourceLoaded;
|
||||||
|
|
||||||
|
private Dictionary<IntPtr, HashSet<string>> TransientResources { get; } = new();
|
||||||
|
public TransientResourceManager(IpcManager manager, DalamudUtil dalamudUtil)
|
||||||
|
{
|
||||||
|
manager.PenumbraResourceLoadEvent += Manager_PenumbraResourceLoadEvent;
|
||||||
|
this.manager = manager;
|
||||||
|
this.dalamudUtil = dalamudUtil;
|
||||||
|
dalamudUtil.FrameworkUpdate += DalamudUtil_FrameworkUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DalamudUtil_FrameworkUpdate()
|
||||||
|
{
|
||||||
|
foreach (var item in TransientResources.ToList())
|
||||||
|
{
|
||||||
|
if (!dalamudUtil.IsDrawObjectPresent(item.Key))
|
||||||
|
{
|
||||||
|
Logger.Debug("Object not present anymore: " + item.Key);
|
||||||
|
TransientResources.Remove(item.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> GetTransientResources(IntPtr drawObject)
|
||||||
|
{
|
||||||
|
if (TransientResources.TryGetValue(drawObject, out var result))
|
||||||
|
{
|
||||||
|
return result.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Manager_PenumbraResourceLoadEvent(IntPtr drawObject, string gamePath, string filePath)
|
||||||
|
{
|
||||||
|
if (!TransientResources.ContainsKey(drawObject))
|
||||||
|
{
|
||||||
|
TransientResources[drawObject] = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePath.StartsWith("|"))
|
||||||
|
{
|
||||||
|
filePath = filePath.Split("|")[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
var newPath = filePath.ToLowerInvariant().Replace("\\", "/");
|
||||||
|
|
||||||
|
if (filePath != gamePath && !TransientResources[drawObject].Contains(newPath))
|
||||||
|
{
|
||||||
|
TransientResources[drawObject].Add(newPath);
|
||||||
|
Logger.Debug($"Adding {filePath.ToLowerInvariant().Replace("\\", "/")} for {drawObject}");
|
||||||
|
TransientResourceLoaded?.Invoke(drawObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveTransientResource(IntPtr drawObject, FileReplacement fileReplacement)
|
||||||
|
{
|
||||||
|
if (TransientResources.ContainsKey(drawObject))
|
||||||
|
{
|
||||||
|
TransientResources[drawObject].RemoveWhere(f => fileReplacement.ResolvedPath == f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
dalamudUtil.FrameworkUpdate -= DalamudUtil_FrameworkUpdate;
|
||||||
|
manager.PenumbraResourceLoadEvent -= Manager_PenumbraResourceLoadEvent;
|
||||||
|
TransientResources.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,9 +27,9 @@ namespace MareSynchronos.Models
|
|||||||
public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => p != ResolvedPath);
|
public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => p != ResolvedPath);
|
||||||
|
|
||||||
public string Hash { get; set; } = string.Empty;
|
public string Hash { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string ResolvedPath { get; set; } = string.Empty;
|
public string ResolvedPath { get; set; } = string.Empty;
|
||||||
|
|
||||||
public void SetResolvedPath(string path)
|
public void SetResolvedPath(string path)
|
||||||
{
|
{
|
||||||
ResolvedPath = path.ToLowerInvariant().Replace('/', '\\').Replace(_penumbraDirectory, "").Replace('\\', '/');
|
ResolvedPath = path.ToLowerInvariant().Replace('/', '\\').Replace(_penumbraDirectory, "").Replace('\\', '/');
|
||||||
@@ -93,6 +93,7 @@ namespace MareSynchronos.Models
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Logger.Debug("Adding new file to DB: " + fi.FullName + ", " + hash);
|
||||||
db.Add(new FileCache()
|
db.Add(new FileCache()
|
||||||
{
|
{
|
||||||
Hash = hash,
|
Hash = hash,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace MareSynchronos.Models
|
|||||||
if (addr || equip || drawObj || nameChange)
|
if (addr || equip || drawObj || nameChange)
|
||||||
{
|
{
|
||||||
_name = name;
|
_name = name;
|
||||||
Logger.Verbose(ObjectKind + " Changed: " + _name + ", now: " + curPtr + ", " + (IntPtr)chara->GameObject.DrawObject);
|
Logger.Verbose($"{ObjectKind} changed: {_name}, now: {curPtr:X}, {(IntPtr)chara->GameObject.DrawObject:X}");
|
||||||
|
|
||||||
Address = curPtr;
|
Address = curPtr;
|
||||||
DrawObjectAddress = (IntPtr)chara->GameObject.DrawObject;
|
DrawObjectAddress = (IntPtr)chara->GameObject.DrawObject;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace MareSynchronos
|
|||||||
private readonly SettingsUi _settingsUi;
|
private readonly SettingsUi _settingsUi;
|
||||||
private readonly WindowSystem _windowSystem;
|
private readonly WindowSystem _windowSystem;
|
||||||
private PlayerManager? _playerManager;
|
private PlayerManager? _playerManager;
|
||||||
|
private TransientResourceManager? _transientResourceManager;
|
||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
private OnlinePlayerManager? _characterCacheManager;
|
private OnlinePlayerManager? _characterCacheManager;
|
||||||
private readonly DownloadUi _downloadUi;
|
private readonly DownloadUi _downloadUi;
|
||||||
@@ -129,6 +130,7 @@ namespace MareSynchronos
|
|||||||
_ipcManager?.Dispose();
|
_ipcManager?.Dispose();
|
||||||
_playerManager?.Dispose();
|
_playerManager?.Dispose();
|
||||||
_characterCacheManager?.Dispose();
|
_characterCacheManager?.Dispose();
|
||||||
|
_transientResourceManager?.Dispose();
|
||||||
Logger.Debug("Shut down");
|
Logger.Debug("Shut down");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +162,7 @@ namespace MareSynchronos
|
|||||||
Logger.Debug("Client logout");
|
Logger.Debug("Client logout");
|
||||||
_characterCacheManager?.Dispose();
|
_characterCacheManager?.Dispose();
|
||||||
_playerManager?.Dispose();
|
_playerManager?.Dispose();
|
||||||
|
_transientResourceManager?.Dispose();
|
||||||
PluginInterface.UiBuilder.Draw -= Draw;
|
PluginInterface.UiBuilder.Draw -= Draw;
|
||||||
PluginInterface.UiBuilder.OpenConfigUi -= OpenUi;
|
PluginInterface.UiBuilder.OpenConfigUi -= OpenUi;
|
||||||
_commandManager.RemoveHandler(CommandName);
|
_commandManager.RemoveHandler(CommandName);
|
||||||
@@ -169,6 +172,7 @@ namespace MareSynchronos
|
|||||||
{
|
{
|
||||||
_characterCacheManager?.Dispose();
|
_characterCacheManager?.Dispose();
|
||||||
_playerManager?.Dispose();
|
_playerManager?.Dispose();
|
||||||
|
_transientResourceManager?.Dispose();
|
||||||
|
|
||||||
Task.Run(WaitForPlayerAndLaunchCharacterManager);
|
Task.Run(WaitForPlayerAndLaunchCharacterManager);
|
||||||
}
|
}
|
||||||
@@ -182,10 +186,11 @@ namespace MareSynchronos
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_transientResourceManager = new TransientResourceManager(_ipcManager, _dalamudUtil);
|
||||||
var characterCacheFactory =
|
var characterCacheFactory =
|
||||||
new CharacterDataFactory(_dalamudUtil, _ipcManager);
|
new CharacterDataFactory(_dalamudUtil, _ipcManager, _transientResourceManager);
|
||||||
_playerManager = new PlayerManager(_apiController, _ipcManager,
|
_playerManager = new PlayerManager(_apiController, _ipcManager,
|
||||||
characterCacheFactory, _dalamudUtil);
|
characterCacheFactory, _dalamudUtil, _transientResourceManager);
|
||||||
_characterCacheManager = new OnlinePlayerManager(_framework,
|
_characterCacheManager = new OnlinePlayerManager(_framework,
|
||||||
_apiController, _dalamudUtil, _ipcManager, _playerManager);
|
_apiController, _dalamudUtil, _ipcManager, _playerManager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,19 @@ namespace MareSynchronos.Utils
|
|||||||
public event LogOut? LogOut;
|
public event LogOut? LogOut;
|
||||||
public event FrameworkUpdate? FrameworkUpdate;
|
public event FrameworkUpdate? FrameworkUpdate;
|
||||||
|
|
||||||
|
public unsafe bool IsDrawObjectPresent(IntPtr key)
|
||||||
|
{
|
||||||
|
foreach (var obj in _objectTable)
|
||||||
|
{
|
||||||
|
if ((IntPtr)((GameObject*)obj.Address)->GetDrawObject() == key)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework)
|
public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework)
|
||||||
{
|
{
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
{
|
{
|
||||||
CurrentUploads.Add(new UploadFileTransfer(file)
|
CurrentUploads.Add(new UploadFileTransfer(file)
|
||||||
{
|
{
|
||||||
Total = new FileInfo(db.FileCaches.FirstOrDefault(f => f.Hash.ToLowerInvariant() == file.Hash.ToLowerInvariant())
|
Total = new FileInfo(db.FileCaches.FirstOrDefault(f => f.Hash.ToLower() == file.Hash.ToLower())
|
||||||
?.Filepath ?? string.Empty).Length
|
?.Filepath ?? string.Empty).Length
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ namespace MareSynchronos.WebAPI
|
|||||||
|
|
||||||
public async Task CreateConnections()
|
public async Task CreateConnections()
|
||||||
{
|
{
|
||||||
|
Logger.Info("Recreating Connection");
|
||||||
|
|
||||||
|
await StopConnection(_connectionCancellationTokenSource.Token);
|
||||||
|
|
||||||
if (_pluginConfiguration.FullPause)
|
if (_pluginConfiguration.FullPause)
|
||||||
{
|
{
|
||||||
ServerState = ServerState.Disconnected;
|
ServerState = ServerState.Disconnected;
|
||||||
@@ -135,10 +139,6 @@ namespace MareSynchronos.WebAPI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info("Recreating Connection");
|
|
||||||
|
|
||||||
await StopConnection(_connectionCancellationTokenSource.Token);
|
|
||||||
|
|
||||||
_connectionCancellationTokenSource.Cancel();
|
_connectionCancellationTokenSource.Cancel();
|
||||||
_connectionCancellationTokenSource = new CancellationTokenSource();
|
_connectionCancellationTokenSource = new CancellationTokenSource();
|
||||||
var token = _connectionCancellationTokenSource.Token;
|
var token = _connectionCancellationTokenSource.Token;
|
||||||
@@ -329,6 +329,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
{
|
{
|
||||||
if (_mareHub is not null)
|
if (_mareHub is not null)
|
||||||
{
|
{
|
||||||
|
_uploadCancellationTokenSource?.Cancel();
|
||||||
Logger.Info("Stopping existing connection");
|
Logger.Info("Stopping existing connection");
|
||||||
await _mareHub.StopAsync(token);
|
await _mareHub.StopAsync(token);
|
||||||
_mareHub.Closed -= MareHubOnClosed;
|
_mareHub.Closed -= MareHubOnClosed;
|
||||||
|
|||||||
Reference in New Issue
Block a user