add intro UI for first time registration, add FileCacheManager to scan and rescan for file changes, fix namings, polish UI for normal usage
This commit is contained in:
@@ -45,7 +45,7 @@ namespace MareSynchronos.Managers
|
||||
private string _lastSentHash = string.Empty;
|
||||
private Task? _playerChangedTask = null;
|
||||
|
||||
private HashSet<string> onlineWhitelistedUsers = new();
|
||||
private HashSet<string> _onlineWhitelistedUsers = new();
|
||||
|
||||
public CharacterManager(ClientState clientState, Framework framework, ApiController apiController, ObjectTable objectTable, IpcManager ipcManager, FileReplacementFactory factory,
|
||||
Configuration pluginConfiguration)
|
||||
@@ -154,6 +154,11 @@ namespace MareSynchronos.Managers
|
||||
_watcher.Disable();
|
||||
_watcher.PlayerChanged -= Watcher_PlayerChanged;
|
||||
_watcher?.Dispose();
|
||||
|
||||
foreach (var character in _onlineWhitelistedUsers)
|
||||
{
|
||||
RestoreCharacter(character);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopWatchPlayer(string name)
|
||||
@@ -164,7 +169,7 @@ namespace MareSynchronos.Managers
|
||||
public async Task UpdatePlayersFromService(Dictionary<string, PlayerCharacter> currentLocalPlayers)
|
||||
{
|
||||
PluginLog.Debug("Updating local players from service");
|
||||
currentLocalPlayers = currentLocalPlayers.Where(k => onlineWhitelistedUsers.Contains(k.Key))
|
||||
currentLocalPlayers = currentLocalPlayers.Where(k => _onlineWhitelistedUsers.Contains(k.Key))
|
||||
.ToDictionary(k => k.Key, k => k.Value);
|
||||
await _apiController.GetCharacterData(currentLocalPlayers
|
||||
.ToDictionary(
|
||||
@@ -205,10 +210,10 @@ namespace MareSynchronos.Managers
|
||||
|
||||
Task.WaitAll(apiTask);
|
||||
|
||||
onlineWhitelistedUsers = new HashSet<string>(apiTask.Result);
|
||||
_onlineWhitelistedUsers = new HashSet<string>(apiTask.Result);
|
||||
var assignTask = AssignLocalPlayersData();
|
||||
Task.WaitAll(assignTask);
|
||||
PluginLog.Debug("Online and whitelisted users: " + string.Join(",", onlineWhitelistedUsers));
|
||||
PluginLog.Debug("Online and whitelisted users: " + string.Join(",", _onlineWhitelistedUsers));
|
||||
|
||||
_framework.Update += Framework_Update;
|
||||
_ipcManager.PenumbraRedrawEvent += IpcManager_PenumbraRedrawEvent;
|
||||
@@ -221,6 +226,12 @@ namespace MareSynchronos.Managers
|
||||
_framework.Update -= Framework_Update;
|
||||
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
|
||||
_clientState.TerritoryChanged -= ClientState_TerritoryChanged;
|
||||
foreach (var character in _onlineWhitelistedUsers)
|
||||
{
|
||||
RestoreCharacter(character);
|
||||
}
|
||||
|
||||
_lastSentHash = string.Empty;
|
||||
}
|
||||
|
||||
private void ApiControllerOnAddedToWhitelist(object? sender, EventArgs e)
|
||||
@@ -230,7 +241,7 @@ namespace MareSynchronos.Managers
|
||||
var players = GetLocalPlayers();
|
||||
if (players.ContainsKey(characterHash))
|
||||
{
|
||||
PluginLog.Debug("You got added to a whitelist, restoring data for " + characterHash);
|
||||
PluginLog.Debug("Removed from whitelist, restoring data for " + characterHash);
|
||||
_ = _apiController.GetCharacterData(new Dictionary<string, int> { { characterHash, (int)players[characterHash].ClassJob.Id } });
|
||||
}
|
||||
}
|
||||
@@ -287,8 +298,8 @@ namespace MareSynchronos.Managers
|
||||
}
|
||||
|
||||
PluginLog.Debug("Assigned hash to visible player: " + otherPlayerName);
|
||||
/*ipcManager.PenumbraRemoveTemporaryCollection(otherPlayerName);
|
||||
ipcManager.PenumbraCreateTemporaryCollection(otherPlayerName);
|
||||
_ipcManager.PenumbraRemoveTemporaryCollection(otherPlayerName);
|
||||
_ipcManager.PenumbraCreateTemporaryCollection(otherPlayerName);
|
||||
Dictionary<string, string> moddedPaths = new();
|
||||
using (var db = new FileCacheContext())
|
||||
{
|
||||
@@ -306,41 +317,49 @@ namespace MareSynchronos.Managers
|
||||
}
|
||||
}
|
||||
|
||||
ipcManager.PenumbraSetTemporaryMods(otherPlayerName, moddedPaths);*/
|
||||
_ipcManager.PenumbraSetTemporaryMods(otherPlayerName, moddedPaths);
|
||||
_ipcManager.GlamourerApplyCharacterCustomization(e.CharacterData.GlamourerData, otherPlayerName);
|
||||
//ipcManager.PenumbraRedraw(otherPlayerName);
|
||||
_ipcManager.PenumbraRedraw(otherPlayerName);
|
||||
}
|
||||
|
||||
private void ApiControllerOnRemovedFromWhitelist(object? sender, EventArgs e)
|
||||
{
|
||||
var characterHash = (string?)sender;
|
||||
if (string.IsNullOrEmpty(characterHash)) return;
|
||||
RestoreCharacter(characterHash);
|
||||
}
|
||||
|
||||
private void RestoreCharacter(string characterHash)
|
||||
{
|
||||
var players = GetLocalPlayers();
|
||||
|
||||
foreach (var entry in _characterCache.Where(c => c.Key.Item1 == characterHash))
|
||||
{
|
||||
_characterCache.Remove(entry.Key);
|
||||
}
|
||||
|
||||
var playerName = players.SingleOrDefault(p => p.Key == characterHash).Value.Name.ToString() ?? null;
|
||||
if (playerName != null)
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player.Key != characterHash) continue;
|
||||
var playerName = player.Value.Name.ToString();
|
||||
RestorePreviousCharacter(playerName);
|
||||
PluginLog.Debug("Removed from whitelist, restoring glamourer state for " + playerName);
|
||||
_ipcManager.PenumbraRemoveTemporaryCollection(playerName);
|
||||
_ipcManager.GlamourerRevertCharacterCustomization(playerName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApiControllerOnWhitelistedPlayerOffline(object? sender, EventArgs e)
|
||||
{
|
||||
PluginLog.Debug("Player offline: " + sender!);
|
||||
onlineWhitelistedUsers.Remove((string)sender!);
|
||||
_onlineWhitelistedUsers.Remove((string)sender!);
|
||||
}
|
||||
|
||||
private void ApiControllerOnWhitelistedPlayerOnline(object? sender, EventArgs e)
|
||||
{
|
||||
PluginLog.Debug("Player online: " + sender!);
|
||||
onlineWhitelistedUsers.Add((string)sender!);
|
||||
_onlineWhitelistedUsers.Add((string)sender!);
|
||||
}
|
||||
|
||||
private async Task AssignLocalPlayersData()
|
||||
@@ -351,11 +370,7 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
if (currentLocalPlayers.ContainsKey(player.Key.Item1))
|
||||
{
|
||||
await Task.Run(() => ApiControllerOnCharacterReceived(null, new CharacterReceivedEventArgs
|
||||
{
|
||||
CharacterNameHash = player.Key.Item1,
|
||||
CharacterData = player.Value
|
||||
}));
|
||||
await Task.Run(() => ApiControllerOnCharacterReceived(null, new CharacterReceivedEventArgs(player.Key.Item1, player.Value)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +428,7 @@ namespace MareSynchronos.Managers
|
||||
var pObj = (PlayerCharacter)obj;
|
||||
var hashedName = Crypto.GetHash256(pObj.Name.ToString() + pObj.HomeWorld.Id.ToString());
|
||||
|
||||
if (!onlineWhitelistedUsers.Contains(hashedName)) continue;
|
||||
if (!_onlineWhitelistedUsers.Contains(hashedName)) continue;
|
||||
|
||||
localPlayersList.Add(hashedName);
|
||||
if (!_cachedLocalPlayers.ContainsKey(hashedName)) newPlayers[hashedName] = pObj;
|
||||
@@ -455,7 +470,7 @@ namespace MareSynchronos.Managers
|
||||
string playerName = obj.Name.ToString();
|
||||
if (playerName == GetPlayerName()) continue;
|
||||
var playerObject = (PlayerCharacter)obj;
|
||||
allLocalPlayers.Add(Crypto.GetHash256(playerObject.Name.ToString() + playerObject.HomeWorld.Id.ToString()), playerObject);
|
||||
allLocalPlayers[Crypto.GetHash256(playerObject.Name.ToString() + playerObject.HomeWorld.Id.ToString())] = playerObject;
|
||||
}
|
||||
|
||||
return allLocalPlayers;
|
||||
@@ -509,7 +524,7 @@ namespace MareSynchronos.Managers
|
||||
var cacheDto = characterCacheTask.Result.ToCharacterCacheDto();
|
||||
if (cacheDto.Hash == _lastSentHash)
|
||||
{
|
||||
PluginLog.Warning("Not sending data, already sent");
|
||||
PluginLog.Debug("Not sending data, already sent");
|
||||
return;
|
||||
}
|
||||
Task.WaitAll(_apiController.SendCharacterData(cacheDto, GetLocalPlayers().Select(d => d.Key).ToList()));
|
||||
|
||||
187
MareSynchronos/Managers/FileCacheManager.cs
Normal file
187
MareSynchronos/Managers/FileCacheManager.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Logging;
|
||||
using MareSynchronos.Factories;
|
||||
using MareSynchronos.FileCacheDB;
|
||||
|
||||
namespace MareSynchronos.Managers
|
||||
{
|
||||
internal class FileCacheManager : IDisposable
|
||||
{
|
||||
private const int MinutesForScan = 10;
|
||||
private readonly FileCacheFactory _fileCacheFactory;
|
||||
private readonly IpcManager _ipcManager;
|
||||
private readonly Configuration _pluginConfiguration;
|
||||
private CancellationTokenSource? _scanCancellationTokenSource;
|
||||
private System.Timers.Timer? _scanScheduler;
|
||||
private Task? _scanTask;
|
||||
private Stopwatch? _timerStopWatch;
|
||||
public FileCacheManager(FileCacheFactory fileCacheFactory, IpcManager ipcManager, Configuration pluginConfiguration)
|
||||
{
|
||||
_fileCacheFactory = fileCacheFactory;
|
||||
_ipcManager = ipcManager;
|
||||
_pluginConfiguration = pluginConfiguration;
|
||||
|
||||
if (_ipcManager.CheckPenumbraApi()
|
||||
&& _pluginConfiguration.AcceptedAgreement
|
||||
&& !string.IsNullOrEmpty(_pluginConfiguration.CacheFolder)
|
||||
&& _pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri)
|
||||
&& !string.IsNullOrEmpty(_ipcManager.PenumbraModDirectory()))
|
||||
{
|
||||
StartInitialScan();
|
||||
}
|
||||
}
|
||||
|
||||
public long CurrentFileProgress { get; private set; }
|
||||
public bool IsScanRunning => !_scanTask?.IsCompleted ?? false;
|
||||
|
||||
public TimeSpan TimeToNextScan => TimeSpan.FromMinutes(MinutesForScan).Subtract(_timerStopWatch?.Elapsed ?? TimeSpan.FromMinutes(MinutesForScan));
|
||||
public long TotalFiles { get; private set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
PluginLog.Debug("Disposing File Cache Manager");
|
||||
_scanScheduler?.Stop();
|
||||
_scanCancellationTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
public void StartInitialScan()
|
||||
{
|
||||
_scanCancellationTokenSource = new CancellationTokenSource();
|
||||
_scanTask = StartFileScan(_scanCancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
private async Task StartFileScan(CancellationToken ct)
|
||||
{
|
||||
_scanCancellationTokenSource = new CancellationTokenSource();
|
||||
var penumbraDir = _ipcManager.PenumbraModDirectory()!;
|
||||
PluginLog.Debug("Getting files from " + penumbraDir);
|
||||
var scannedFiles = new ConcurrentDictionary<string, bool>(
|
||||
Directory.EnumerateFiles(penumbraDir, "*.*", SearchOption.AllDirectories)
|
||||
.Select(s => s.ToLowerInvariant())
|
||||
.Where(f => f.Contains(@"\chara\") && (f.EndsWith(".tex") || f.EndsWith(".mdl") || f.EndsWith(".mtrl")))
|
||||
.Select(p => new KeyValuePair<string, bool>(p, false)));
|
||||
List<FileCache> fileCaches;
|
||||
await using (FileCacheContext db = new())
|
||||
{
|
||||
fileCaches = db.FileCaches.ToList();
|
||||
}
|
||||
|
||||
TotalFiles = scannedFiles.Count;
|
||||
|
||||
var fileCachesToUpdate = new ConcurrentBag<FileCache>();
|
||||
var fileCachesToDelete = new ConcurrentBag<FileCache>();
|
||||
var fileCachesToAdd = new ConcurrentBag<FileCache>();
|
||||
|
||||
PluginLog.Debug("Getting file list from Database");
|
||||
// scan files from database
|
||||
Parallel.ForEach(fileCaches, new ParallelOptions()
|
||||
{
|
||||
MaxDegreeOfParallelism = _pluginConfiguration.MaxParallelScan,
|
||||
CancellationToken = ct,
|
||||
},
|
||||
cache =>
|
||||
{
|
||||
if (ct.IsCancellationRequested) return;
|
||||
if (!File.Exists(cache.Filepath))
|
||||
{
|
||||
fileCachesToDelete.Add(cache);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scannedFiles.ContainsKey(cache.Filepath))
|
||||
{
|
||||
scannedFiles[cache.Filepath] = true;
|
||||
}
|
||||
FileInfo fileInfo = new(cache.Filepath);
|
||||
if (fileInfo.LastWriteTimeUtc.Ticks == long.Parse(cache.LastModifiedDate)) return;
|
||||
_fileCacheFactory.UpdateFileCache(cache);
|
||||
fileCachesToUpdate.Add(cache);
|
||||
}
|
||||
|
||||
var files = CurrentFileProgress;
|
||||
Interlocked.Increment(ref files);
|
||||
CurrentFileProgress = files;
|
||||
});
|
||||
|
||||
if (ct.IsCancellationRequested) return;
|
||||
|
||||
// scan new files
|
||||
Parallel.ForEach(scannedFiles.Where(c => c.Value == false), new ParallelOptions()
|
||||
{
|
||||
MaxDegreeOfParallelism = _pluginConfiguration.MaxParallelScan,
|
||||
CancellationToken = ct
|
||||
},
|
||||
file =>
|
||||
{
|
||||
fileCachesToAdd.Add(_fileCacheFactory.Create(file.Key));
|
||||
|
||||
var files = CurrentFileProgress;
|
||||
Interlocked.Increment(ref files);
|
||||
CurrentFileProgress = files;
|
||||
});
|
||||
|
||||
await using (FileCacheContext db = new())
|
||||
{
|
||||
if (fileCachesToAdd.Any() || fileCachesToUpdate.Any() || fileCachesToDelete.Any())
|
||||
{
|
||||
db.FileCaches.AddRange(fileCachesToAdd);
|
||||
db.FileCaches.UpdateRange(fileCachesToUpdate);
|
||||
db.FileCaches.RemoveRange(fileCachesToDelete);
|
||||
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
PluginLog.Debug("Scan complete");
|
||||
TotalFiles = 0;
|
||||
CurrentFileProgress = 0;
|
||||
|
||||
if (!_pluginConfiguration.InitialScanComplete)
|
||||
{
|
||||
_pluginConfiguration.InitialScanComplete = true;
|
||||
_pluginConfiguration.Save();
|
||||
_timerStopWatch = Stopwatch.StartNew();
|
||||
StartScheduler();
|
||||
}
|
||||
else if (_timerStopWatch == null)
|
||||
{
|
||||
StartScheduler();
|
||||
_timerStopWatch = Stopwatch.StartNew();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartScheduler()
|
||||
{
|
||||
PluginLog.Debug("Scheduling next scan for in " + MinutesForScan + " minutes");
|
||||
_scanScheduler = new System.Timers.Timer(TimeSpan.FromMinutes(MinutesForScan).TotalMilliseconds)
|
||||
{
|
||||
AutoReset = false,
|
||||
Enabled = false,
|
||||
};
|
||||
_scanScheduler.AutoReset = true;
|
||||
_scanScheduler.Elapsed += (_, _) =>
|
||||
{
|
||||
_timerStopWatch?.Stop();
|
||||
if (_scanTask?.IsCompleted ?? false)
|
||||
{
|
||||
PluginLog.Warning("Scanning task is still running, not reinitiating.");
|
||||
return;
|
||||
}
|
||||
|
||||
PluginLog.Debug("Initiating periodic scan for mod changes");
|
||||
_scanTask = StartFileScan(_scanCancellationTokenSource!.Token);
|
||||
_timerStopWatch = Stopwatch.StartNew();
|
||||
};
|
||||
|
||||
_scanScheduler.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,23 +10,23 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
public class IpcManager : IDisposable
|
||||
{
|
||||
private readonly DalamudPluginInterface pluginInterface;
|
||||
private ICallGateSubscriber<object> penumbraInit;
|
||||
private ICallGateSubscriber<string, string, string>? penumbraResolvePath;
|
||||
private ICallGateSubscriber<string>? penumbraResolveModDir;
|
||||
private ICallGateSubscriber<string>? glamourerGetCharacterCustomization;
|
||||
private ICallGateSubscriber<string, string, object>? glamourerApplyCharacterCustomization;
|
||||
private ICallGateSubscriber<int> penumbraApiVersion;
|
||||
private ICallGateSubscriber<int> glamourerApiVersion;
|
||||
private ICallGateSubscriber<IntPtr, int, object?> penumbraObjectIsRedrawn;
|
||||
private ICallGateSubscriber<string, int, object>? penumbraRedraw;
|
||||
private ICallGateSubscriber<string, string, string[]>? penumbraReverseResolvePath;
|
||||
private ICallGateSubscriber<string, object> glamourerRevertCustomization;
|
||||
private readonly DalamudPluginInterface _pluginInterface;
|
||||
private readonly ICallGateSubscriber<object> _penumbraInit;
|
||||
private readonly ICallGateSubscriber<string, string, string>? _penumbraResolvePath;
|
||||
private readonly ICallGateSubscriber<string>? _penumbraResolveModDir;
|
||||
private readonly ICallGateSubscriber<string>? _glamourerGetCharacterCustomization;
|
||||
private readonly ICallGateSubscriber<string, string, object>? _glamourerApplyCharacterCustomization;
|
||||
private readonly ICallGateSubscriber<int> _penumbraApiVersion;
|
||||
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
|
||||
private readonly ICallGateSubscriber<IntPtr, int, object?> _penumbraObjectIsRedrawn;
|
||||
private readonly ICallGateSubscriber<string, int, object>? _penumbraRedraw;
|
||||
private readonly ICallGateSubscriber<string, string, string[]>? _penumbraReverseResolvePath;
|
||||
private readonly ICallGateSubscriber<string, object> _glamourerRevertCustomization;
|
||||
|
||||
private ICallGateSubscriber<string, string, IReadOnlyDictionary<string, string>, List<string>, int, int>
|
||||
penumbraSetTemporaryMod;
|
||||
private ICallGateSubscriber<string, string, bool, (int, string)> penumbraCreateTemporaryCollection;
|
||||
private ICallGateSubscriber<string, int> penumbraRemoveTemporaryCollection;
|
||||
private readonly ICallGateSubscriber<string, string, IReadOnlyDictionary<string, string>, List<string>, int, int>
|
||||
_penumbraSetTemporaryMod;
|
||||
private readonly ICallGateSubscriber<string, string, bool, (int, string)> _penumbraCreateTemporaryCollection;
|
||||
private readonly ICallGateSubscriber<string, int> _penumbraRemoveTemporaryCollection;
|
||||
|
||||
public bool Initialized { get; private set; } = false;
|
||||
|
||||
@@ -34,41 +34,41 @@ namespace MareSynchronos.Managers
|
||||
|
||||
public IpcManager(DalamudPluginInterface pi)
|
||||
{
|
||||
pluginInterface = pi;
|
||||
_pluginInterface = pi;
|
||||
|
||||
penumbraInit = pluginInterface.GetIpcSubscriber<object>("Penumbra.Initialized");
|
||||
penumbraResolvePath = pluginInterface.GetIpcSubscriber<string, string, string>("Penumbra.ResolveCharacterPath");
|
||||
penumbraResolveModDir = pluginInterface.GetIpcSubscriber<string>("Penumbra.GetModDirectory");
|
||||
penumbraRedraw = pluginInterface.GetIpcSubscriber<string, int, object>("Penumbra.RedrawObjectByName");
|
||||
glamourerGetCharacterCustomization = pluginInterface.GetIpcSubscriber<string>("Glamourer.GetCharacterCustomization");
|
||||
glamourerApplyCharacterCustomization = pluginInterface.GetIpcSubscriber<string, string, object>("Glamourer.ApplyCharacterCustomization");
|
||||
penumbraReverseResolvePath = pluginInterface.GetIpcSubscriber<string, string, string[]>("Penumbra.ReverseResolvePath");
|
||||
penumbraApiVersion = pluginInterface.GetIpcSubscriber<int>("Penumbra.ApiVersion");
|
||||
glamourerApiVersion = pluginInterface.GetIpcSubscriber<int>("Glamourer.ApiVersion");
|
||||
glamourerRevertCustomization = pluginInterface.GetIpcSubscriber<string, object>("Glamourer.RevertCharacterCustomization");
|
||||
penumbraObjectIsRedrawn = pluginInterface.GetIpcSubscriber<IntPtr, int, object?>("Penumbra.GameObjectRedrawn");
|
||||
_penumbraInit = _pluginInterface.GetIpcSubscriber<object>("Penumbra.Initialized");
|
||||
_penumbraResolvePath = _pluginInterface.GetIpcSubscriber<string, string, string>("Penumbra.ResolveCharacterPath");
|
||||
_penumbraResolveModDir = _pluginInterface.GetIpcSubscriber<string>("Penumbra.GetModDirectory");
|
||||
_penumbraRedraw = _pluginInterface.GetIpcSubscriber<string, int, object>("Penumbra.RedrawObjectByName");
|
||||
_glamourerGetCharacterCustomization = _pluginInterface.GetIpcSubscriber<string>("Glamourer.GetCharacterCustomization");
|
||||
_glamourerApplyCharacterCustomization = _pluginInterface.GetIpcSubscriber<string, string, object>("Glamourer.ApplyCharacterCustomization");
|
||||
_penumbraReverseResolvePath = _pluginInterface.GetIpcSubscriber<string, string, string[]>("Penumbra.ReverseResolvePath");
|
||||
_penumbraApiVersion = _pluginInterface.GetIpcSubscriber<int>("Penumbra.ApiVersion");
|
||||
_glamourerApiVersion = _pluginInterface.GetIpcSubscriber<int>("Glamourer.ApiVersion");
|
||||
_glamourerRevertCustomization = _pluginInterface.GetIpcSubscriber<string, object>("Glamourer.RevertCharacterCustomization");
|
||||
_penumbraObjectIsRedrawn = _pluginInterface.GetIpcSubscriber<IntPtr, int, object?>("Penumbra.GameObjectRedrawn");
|
||||
|
||||
penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
||||
penumbraInit.Subscribe(RedrawSelf);
|
||||
_penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
||||
_penumbraInit.Subscribe(RedrawSelf);
|
||||
|
||||
penumbraSetTemporaryMod =
|
||||
pluginInterface
|
||||
_penumbraSetTemporaryMod =
|
||||
_pluginInterface
|
||||
.GetIpcSubscriber<string, string, IReadOnlyDictionary<string, string>, List<string>, int,
|
||||
int>("Penumbra.AddTemporaryMod");
|
||||
|
||||
penumbraCreateTemporaryCollection =
|
||||
pluginInterface.GetIpcSubscriber<string, string, bool, (int, string)>("Penumbra.CreateTemporaryCollection");
|
||||
penumbraRemoveTemporaryCollection =
|
||||
pluginInterface.GetIpcSubscriber<string, int>("Penumbra.RemoveTemporaryCollection");
|
||||
_penumbraCreateTemporaryCollection =
|
||||
_pluginInterface.GetIpcSubscriber<string, string, bool, (int, string)>("Penumbra.CreateTemporaryCollection");
|
||||
_penumbraRemoveTemporaryCollection =
|
||||
_pluginInterface.GetIpcSubscriber<string, int>("Penumbra.RemoveTemporaryCollection");
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public bool CheckPenumbraAPI()
|
||||
public bool CheckPenumbraApi()
|
||||
{
|
||||
try
|
||||
{
|
||||
return penumbraApiVersion.InvokeFunc() >= 4;
|
||||
return _penumbraApiVersion.InvokeFunc() >= 4;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -76,11 +76,11 @@ namespace MareSynchronos.Managers
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckGlamourerAPI()
|
||||
public bool CheckGlamourerApi()
|
||||
{
|
||||
try
|
||||
{
|
||||
return glamourerApiVersion.InvokeFunc() >= 0;
|
||||
return _glamourerApiVersion.InvokeFunc() >= 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -95,91 +95,78 @@ namespace MareSynchronos.Managers
|
||||
|
||||
private void RedrawSelf()
|
||||
{
|
||||
penumbraRedraw!.InvokeAction("self", 0);
|
||||
_penumbraRedraw!.InvokeAction("self", 0);
|
||||
}
|
||||
|
||||
private void Uninitialize()
|
||||
{
|
||||
penumbraInit.Unsubscribe(RedrawSelf);
|
||||
penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
||||
penumbraResolvePath = null;
|
||||
penumbraResolveModDir = null;
|
||||
glamourerGetCharacterCustomization = null;
|
||||
glamourerApplyCharacterCustomization = null;
|
||||
penumbraReverseResolvePath = null;
|
||||
_penumbraInit.Unsubscribe(RedrawSelf);
|
||||
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
||||
Initialized = false;
|
||||
PluginLog.Debug("IPC Manager disposed");
|
||||
}
|
||||
|
||||
public string[] PenumbraReverseResolvePath(string path, string characterName)
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return new[] { path };
|
||||
return penumbraReverseResolvePath!.InvokeFunc(path, characterName);
|
||||
if (!CheckPenumbraApi()) return new[] { path };
|
||||
return _penumbraReverseResolvePath!.InvokeFunc(path, characterName);
|
||||
}
|
||||
|
||||
public string? PenumbraResolvePath(string path, string characterName)
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return null;
|
||||
return penumbraResolvePath!.InvokeFunc(path, characterName);
|
||||
if (!CheckPenumbraApi()) return null;
|
||||
return _penumbraResolvePath!.InvokeFunc(path, characterName);
|
||||
}
|
||||
|
||||
public string? PenumbraModDirectory()
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return null;
|
||||
return penumbraResolveModDir!.InvokeFunc();
|
||||
if (!CheckPenumbraApi()) return null;
|
||||
return _penumbraResolveModDir!.InvokeFunc();
|
||||
}
|
||||
|
||||
public string? GlamourerGetCharacterCustomization()
|
||||
{
|
||||
if (!CheckGlamourerAPI()) return null;
|
||||
return glamourerGetCharacterCustomization!.InvokeFunc();
|
||||
if (!CheckGlamourerApi()) return null;
|
||||
return _glamourerGetCharacterCustomization!.InvokeFunc();
|
||||
}
|
||||
|
||||
public void GlamourerApplyCharacterCustomization(string customization, string characterName)
|
||||
{
|
||||
if (!CheckGlamourerAPI()) return;
|
||||
glamourerApplyCharacterCustomization!.InvokeAction(customization, characterName);
|
||||
if (!CheckGlamourerApi()) return;
|
||||
_glamourerApplyCharacterCustomization!.InvokeAction(customization, characterName);
|
||||
}
|
||||
|
||||
public void GlamourerRevertCharacterCustomization(string characterName)
|
||||
{
|
||||
if (!CheckGlamourerAPI()) return;
|
||||
glamourerRevertCustomization!.InvokeAction(characterName);
|
||||
if (!CheckGlamourerApi()) return;
|
||||
_glamourerRevertCustomization!.InvokeAction(characterName);
|
||||
}
|
||||
|
||||
public void PenumbraRedraw(string actorName)
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return;
|
||||
penumbraRedraw!.InvokeAction(actorName, 0);
|
||||
if (!CheckPenumbraApi()) return;
|
||||
_penumbraRedraw!.InvokeAction(actorName, 0);
|
||||
}
|
||||
|
||||
public void PenumbraCreateTemporaryCollection(string characterName)
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return;
|
||||
if (!CheckPenumbraApi()) return;
|
||||
PluginLog.Debug("Creating temp collection for " + characterName);
|
||||
//penumbraCreateTemporaryCollection.InvokeFunc("MareSynchronos", characterName, true);
|
||||
}
|
||||
|
||||
public void PenumbraRemoveTemporaryCollection(string characterName)
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return;
|
||||
if (!CheckPenumbraApi()) return;
|
||||
PluginLog.Debug("Removing temp collection for " + characterName);
|
||||
//penumbraRemoveTemporaryCollection.InvokeFunc(characterName);
|
||||
}
|
||||
|
||||
public void PenumbraSetTemporaryMods(string characterName, IReadOnlyDictionary<string, string> modPaths)
|
||||
{
|
||||
if (!CheckPenumbraAPI()) return;
|
||||
if (!CheckPenumbraApi()) return;
|
||||
PluginLog.Debug("Assigning temp mods for " + characterName);
|
||||
try
|
||||
{
|
||||
//var result = penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", characterName, modPaths, new List<string>(), 0);
|
||||
//PluginLog.Debug("Success: " + result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PluginLog.Error(ex, "Error during IPC call");
|
||||
}
|
||||
//penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", characterName, modPaths, new List<string>(), 0);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
Reference in New Issue
Block a user