This commit is contained in:
rootdarkarchon
2023-10-14 12:13:43 +02:00
parent a46c63c12a
commit a9a57e0a31
6 changed files with 51 additions and 22 deletions

View File

@@ -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);

View File

@@ -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()
{

View File

@@ -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; }

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)