fuck vfx
This commit is contained in:
@@ -150,6 +150,32 @@ public sealed class FileCacheManager : IDisposable
|
||||
return output;
|
||||
}
|
||||
|
||||
public Dictionary<string, FileCacheEntity?> GetFileCachesByPaths(string[] paths)
|
||||
{
|
||||
var cleanedPaths = paths.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(p => p,
|
||||
p => p.Replace("/", "\\", StringComparison.OrdinalIgnoreCase).Replace(_ipcManager.PenumbraModDirectory!, PenumbraPrefix, StringComparison.OrdinalIgnoreCase),
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
Dictionary<string, FileCacheEntity?> result = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var dict = _fileCaches.SelectMany(f => f.Value).Where(f => f.PrefixedFilePath.StartsWith(PenumbraPrefix, StringComparison.Ordinal))
|
||||
.ToDictionary(d => d.PrefixedFilePath, d => d, StringComparer.Ordinal);
|
||||
|
||||
foreach (var entry in cleanedPaths)
|
||||
{
|
||||
if (dict.TryGetValue(entry.Value, out var entity))
|
||||
{
|
||||
result.Add(entry.Key, entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(entry.Key, null);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public FileCacheEntity? GetFileCacheByPath(string path)
|
||||
{
|
||||
var cleanedPath = path.Replace("/", "\\", StringComparison.OrdinalIgnoreCase).ToLowerInvariant().Replace(_ipcManager.PenumbraModDirectory!.ToLowerInvariant(), "", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
@@ -13,14 +13,15 @@ public class CharacterData
|
||||
|
||||
public string HeelsData { get; set; } = string.Empty;
|
||||
public string HonorificData { get; set; } = string.Empty;
|
||||
public bool IsReady => FileReplacements.SelectMany(k => k.Value).All(f => f.Computed);
|
||||
|
||||
public string ManipulationString { get; set; } = string.Empty;
|
||||
public string PalettePlusPalette { get; set; } = string.Empty;
|
||||
|
||||
public API.Data.CharacterData ToAPI()
|
||||
{
|
||||
var fileReplacements = FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement && !f.IsFileSwap).GroupBy(f => f.Hash, StringComparer.OrdinalIgnoreCase).Select(g =>
|
||||
Dictionary<ObjectKind, List<FileReplacementData>> fileReplacements =
|
||||
FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement && !f.IsFileSwap)
|
||||
.GroupBy(f => f.Hash, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(g =>
|
||||
{
|
||||
return new FileReplacementData()
|
||||
{
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using MareSynchronos.FileCache;
|
||||
using MareSynchronos.API.Data;
|
||||
|
||||
namespace MareSynchronos.PlayerData.Data;
|
||||
|
||||
public partial class FileReplacement
|
||||
{
|
||||
private readonly Lazy<string> _hashLazy;
|
||||
|
||||
public FileReplacement(string[] gamePaths, string filePath, FileCacheManager fileDbManager)
|
||||
public FileReplacement(string[] gamePaths, string filePath)
|
||||
{
|
||||
GamePaths = gamePaths.Select(g => g.Replace('\\', '/').ToLowerInvariant()).ToHashSet(StringComparer.Ordinal);
|
||||
ResolvedPath = filePath.Replace('\\', '/');
|
||||
_hashLazy = new(() => !IsFileSwap ? fileDbManager.GetFileCacheByPath(ResolvedPath)?.Hash ?? string.Empty : string.Empty);
|
||||
}
|
||||
|
||||
public bool Computed => IsFileSwap || !HasFileReplacement || !string.IsNullOrEmpty(Hash);
|
||||
|
||||
public HashSet<string> GamePaths { get; init; }
|
||||
|
||||
public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => !string.Equals(p, ResolvedPath, StringComparison.Ordinal));
|
||||
|
||||
public string Hash => _hashLazy.Value;
|
||||
public string Hash { get; set; } = string.Empty;
|
||||
public bool IsFileSwap => !LocalPathRegex().IsMatch(ResolvedPath) && GamePaths.All(p => !LocalPathRegex().IsMatch(p));
|
||||
public string ResolvedPath { get; init; }
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ public class PlayerDataFactory
|
||||
var (forwardResolve, reverseResolve) = await _dalamudUtil.RunOnFrameworkThread(() => BuildDataFromModel(objectKind, charaPointer, token)).ConfigureAwait(false);
|
||||
Dictionary<string, List<string>> resolvedPaths = await GetFileReplacementsFromPaths(forwardResolve, reverseResolve).ConfigureAwait(false);
|
||||
previousData.FileReplacements[objectKind] =
|
||||
new HashSet<FileReplacement>(resolvedPaths.Select(c => new FileReplacement(c.Value.ToArray(), c.Key, _fileCacheManager)), FileReplacementComparer.Instance)
|
||||
new HashSet<FileReplacement>(resolvedPaths.Select(c => new FileReplacement(c.Value.ToArray(), c.Key)), FileReplacementComparer.Instance)
|
||||
.Where(p => p.HasFileReplacement).ToHashSet();
|
||||
previousData.FileReplacements[objectKind].RemoveWhere(c => c.GamePaths.Any(g => !AllowedExtensionsForGamePaths.Any(e => g.EndsWith(e, StringComparison.OrdinalIgnoreCase))));
|
||||
|
||||
@@ -371,7 +371,7 @@ public class PlayerDataFactory
|
||||
var resolvedTransientPaths = await GetFileReplacementsFromPaths(transientPaths, new HashSet<string>(StringComparer.Ordinal)).ConfigureAwait(false);
|
||||
|
||||
_logger.LogDebug("== Transient Replacements ==");
|
||||
foreach (var replacement in resolvedTransientPaths.Select(c => new FileReplacement(c.Value.ToArray(), c.Key, _fileCacheManager)).OrderBy(f => f.ResolvedPath, StringComparer.Ordinal))
|
||||
foreach (var replacement in resolvedTransientPaths.Select(c => new FileReplacement(c.Value.ToArray(), c.Key)).OrderBy(f => f.ResolvedPath, StringComparer.Ordinal))
|
||||
{
|
||||
_logger.LogDebug("=> {repl}", replacement);
|
||||
previousData.FileReplacements[objectKind].Add(replacement);
|
||||
@@ -407,6 +407,22 @@ public class PlayerDataFactory
|
||||
previousData.HeelsData = await getHeelsOffset.ConfigureAwait(false);
|
||||
_logger.LogDebug("Heels is now: {heels}", previousData.HeelsData);
|
||||
|
||||
if (previousData.FileReplacements.ContainsKey(objectKind))
|
||||
{
|
||||
var toCompute = previousData.FileReplacements[objectKind].Where(f => !f.IsFileSwap).ToArray();
|
||||
_logger.LogDebug("Getting Hashes for {amount} Files", toCompute.Length);
|
||||
var computedPaths = _fileCacheManager.GetFileCachesByPaths(toCompute.Select(c => c.ResolvedPath).ToArray());
|
||||
foreach (var file in toCompute)
|
||||
{
|
||||
file.Hash = computedPaths[file.ResolvedPath]?.Hash ?? string.Empty;
|
||||
}
|
||||
var removed = previousData.FileReplacements[objectKind].RemoveWhere(f => !f.IsFileSwap && string.IsNullOrEmpty(f.Hash));
|
||||
if (removed > 0)
|
||||
{
|
||||
_logger.LogDebug("Removed {amount} of invalid files", removed);
|
||||
}
|
||||
}
|
||||
|
||||
st.Stop();
|
||||
_logger.LogInformation("Building character data for {obj} took {time}ms", objectKind, TimeSpan.FromTicks(st.ElapsedTicks).TotalMilliseconds);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public class OnlinePlayerManager : DisposableMediatorSubscriberBase
|
||||
{
|
||||
if (visiblePlayers.Any() && _lastSentData != null)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
var dataToSend = await _fileTransferManager.UploadFiles(_lastSentData.DeepClone(), visiblePlayers).ConfigureAwait(false);
|
||||
await _apiController.PushCharacterData(dataToSend, visiblePlayers).ConfigureAwait(false);
|
||||
|
||||
@@ -165,14 +165,6 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
|
||||
await _characterDataFactory.BuildCharacterData(_playerData, obj.Value, _cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
int maxWaitingTime = 10000;
|
||||
while (!_playerData.IsReady && maxWaitingTime > 0)
|
||||
{
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
maxWaitingTime -= 100;
|
||||
Logger.LogTrace("Waiting for Cache to be ready");
|
||||
}
|
||||
|
||||
Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI()));
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user