add some preliminary vfx work

This commit is contained in:
Stanley Dimant
2022-08-15 17:36:43 +02:00
parent 4226f2e16d
commit 8459fe8f25
11 changed files with 217 additions and 26 deletions

View File

@@ -203,7 +203,7 @@ namespace MareSynchronos.Managers
{
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
{
@@ -211,7 +211,7 @@ namespace MareSynchronos.Managers
var fileCache = Create(item, _rescanTaskCancellationTokenSource.Token);
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);
}
}

View File

@@ -9,6 +9,7 @@ using MareSynchronos.WebAPI;
namespace MareSynchronos.Managers
{
public delegate void PenumbraRedrawEvent(IntPtr address, int objTblIdx);
public delegate void PenumbraResourceLoadEvent(IntPtr drawObject, string gamePath, string filePath);
public class IpcManager : IDisposable
{
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
@@ -31,7 +32,7 @@ namespace MareSynchronos.Managers
private readonly ICallGateSubscriber<string, string[]>? _reverseResolvePlayer;
private readonly ICallGateSubscriber<string, string, Dictionary<string, string>, string, int, int>
_penumbraSetTemporaryMod;
private readonly ICallGateSubscriber<string, string, string> _penumbraPlayerPathResolved;
private readonly ICallGateSubscriber<IntPtr, string, string, string> _penumbraResourceLoaded;
private readonly DalamudUtil _dalamudUtil;
public IpcManager(DalamudPluginInterface pi, DalamudUtil dalamudUtil)
@@ -56,9 +57,9 @@ namespace MareSynchronos.Managers
_glamourerApplyOnlyCustomization = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyCustomizationToCharacter");
_glamourerApplyOnlyEquipment = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyEquipmentToCharacter");
_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);
_penumbraInit.Subscribe(PenumbraInit);
_penumbraDispose.Subscribe(PenumbraDispose);
@@ -81,14 +82,19 @@ namespace MareSynchronos.Managers
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? PenumbraDisposed;
public event PenumbraRedrawEvent? PenumbraRedrawEvent;
public event PenumbraResourceLoadEvent? PenumbraResourceLoadEvent;
public bool Initialized => CheckPenumbraApi();
public bool CheckGlamourerApi()
@@ -122,6 +128,7 @@ namespace MareSynchronos.Managers
_penumbraDispose.Unsubscribe(PenumbraDispose);
_penumbraInit.Unsubscribe(PenumbraInit);
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
_penumbraResourceLoaded.Unsubscribe(ResourceLoaded);
}
public void GlamourerApplyAll(string? customization, IntPtr obj)

View File

@@ -21,6 +21,7 @@ namespace MareSynchronos.Managers
private readonly ApiController _apiController;
private readonly CharacterDataFactory _characterDataFactory;
private readonly DalamudUtil _dalamudUtil;
private readonly TransientResourceManager _transientResourceManager;
private readonly IpcManager _ipcManager;
public event PlayerHasChanged? PlayerHasChanged;
public CharacterCacheDto? LastCreatedCharacterData { get; private set; }
@@ -34,7 +35,7 @@ namespace MareSynchronos.Managers
private List<PlayerRelatedObject> playerRelatedObjects = new List<PlayerRelatedObject>();
public unsafe PlayerManager(ApiController apiController, IpcManager ipcManager,
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil)
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil, TransientResourceManager transientResourceManager)
{
Logger.Verbose("Creating " + nameof(PlayerManager));
@@ -42,10 +43,11 @@ namespace MareSynchronos.Managers
_ipcManager = ipcManager;
_characterDataFactory = characterDataFactory;
_dalamudUtil = dalamudUtil;
_transientResourceManager = transientResourceManager;
_apiController.Connected += ApiControllerOnConnected;
_apiController.Disconnected += ApiController_Disconnected;
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
_transientResourceManager.TransientResourceLoaded += HandleTransientResourceLoad;
Logger.Debug("Watching Player, ApiController is Connected: " + _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()
{
Logger.Verbose("Disposing " + nameof(PlayerManager));
@@ -72,13 +87,17 @@ namespace MareSynchronos.Managers
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
_dalamudUtil.FrameworkUpdate -= DalamudUtilOnFrameworkUpdate;
_transientResourceManager.TransientResourceLoaded -= HandleTransientResourceLoad;
_playerChangedCts?.Cancel();
}
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());
if (playerRelatedObjects.Any(c => c.HasUnprocessedUpdate && !c.IsProcessing))
@@ -86,7 +105,7 @@ namespace MareSynchronos.Managers
OnPlayerOrAttachedObjectsChanged();
}
_lastPlayerObjectCheck = DateTime.Now;
//_lastPlayerObjectCheck = DateTime.Now;
}
private void ApiControllerOnConnected()
@@ -119,6 +138,7 @@ namespace MareSynchronos.Managers
while (!PermanentDataCache.IsReady && !token.IsCancellationRequested)
{
Logger.Verbose("Waiting until cache is ready");
await Task.Delay(50, token);
}

View 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();
}
}
}