fix some shit, add triangle count

This commit is contained in:
rootdarkarchon
2024-03-20 15:12:19 +01:00
parent f62e8675e7
commit 1d99102c73
22 changed files with 196 additions and 46 deletions

View File

@@ -12,16 +12,22 @@ namespace MareSynchronos.Services;
public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
{
private readonly FileCacheManager _fileCacheManager;
private readonly ModelAnalyzer _modelAnalyzer;
private CancellationTokenSource? _analysisCts;
private CancellationTokenSource _baseAnalysisCts = new();
private string _lastDataHash = string.Empty;
public CharacterAnalyzer(ILogger<CharacterAnalyzer> logger, MareMediator mediator, FileCacheManager fileCacheManager) : base(logger, mediator)
public CharacterAnalyzer(ILogger<CharacterAnalyzer> logger, MareMediator mediator, FileCacheManager fileCacheManager, ModelAnalyzer modelAnalyzer)
: base(logger, mediator)
{
Mediator.Subscribe<CharacterDataCreatedMessage>(this, (msg) =>
{
_ = Task.Run(() => BaseAnalysis(msg.CharacterData.DeepClone()));
_baseAnalysisCts = _baseAnalysisCts.CancelRecreate();
var token = _baseAnalysisCts.Token;
_ = BaseAnalysis(msg.CharacterData, token);
});
_fileCacheManager = fileCacheManager;
_modelAnalyzer = modelAnalyzer;
}
public int CurrentFile { get; internal set; }
@@ -87,7 +93,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
_analysisCts.CancelDispose();
}
private void BaseAnalysis(CharacterData charaData)
private async Task BaseAnalysis(CharacterData charaData, CancellationToken token)
{
if (string.Equals(charaData.DataHash.Value, _lastDataHash, StringComparison.Ordinal)) return;
@@ -98,6 +104,8 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
Dictionary<string, FileDataEntry> data = new(StringComparer.OrdinalIgnoreCase);
foreach (var fileEntry in obj.Value)
{
token.ThrowIfCancellationRequested();
var fileCacheEntries = _fileCacheManager.GetAllFileCachesByHash(fileEntry.Hash, ignoreCacheEntries: true, validate: false).ToList();
if (fileCacheEntries.Count == 0) continue;
@@ -113,12 +121,16 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
Logger.LogWarning(ex, "Could not identify extension for {path}", filePath);
}
var tris = await _modelAnalyzer.GetTrianglesByHash(fileEntry.Hash).ConfigureAwait(false);
foreach (var entry in fileCacheEntries)
{
data[fileEntry.Hash] = new FileDataEntry(fileEntry.Hash, ext,
[.. fileEntry.GamePaths],
fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct().ToList(),
entry.Size > 0 ? entry.Size.Value : 0, entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0);
entry.Size > 0 ? entry.Size.Value : 0,
entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0,
tris);
}
}
@@ -176,7 +188,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
Logger.LogInformation("IMPORTANT NOTES:\n\r- For Mare up- and downloads only the compressed size is relevant.\n\r- An unusually high total files count beyond 200 and up will also increase your download time to others significantly.");
}
internal sealed record FileDataEntry(string Hash, string FileType, List<string> GamePaths, List<string> FilePaths, long OriginalSize, long CompressedSize)
internal sealed record FileDataEntry(string Hash, string FileType, List<string> GamePaths, List<string> FilePaths, long OriginalSize, long CompressedSize, long Triangles)
{
public bool IsComputed => OriginalSize > 0 && CompressedSize > 0;
public async Task ComputeSizes(FileCacheManager fileCacheManager, CancellationToken token)
@@ -194,6 +206,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
}
public long OriginalSize { get; private set; } = OriginalSize;
public long CompressedSize { get; private set; } = CompressedSize;
public long Triangles { get; private set; } = Triangles;
public Lazy<string> Format = new(() =>
{

View File

@@ -48,7 +48,7 @@ public sealed class CommandManagerService : IDisposable
{
var splitArgs = args.ToLowerInvariant().Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries);
if (splitArgs == null || splitArgs.Length == 0)
if (splitArgs.Length == 0)
{
// Interpret this as toggling the UI
if (_mareConfigService.Current.HasValidSetup())

View File

@@ -0,0 +1,72 @@
using Dalamud.Plugin.Services;
using Lumina;
using Lumina.Data.Files;
using MareSynchronos.FileCache;
using MareSynchronos.MareConfiguration;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.Services;
public sealed class ModelAnalyzer
{
private readonly ILogger<ModelAnalyzer> _logger;
private readonly FileCacheManager _fileCacheManager;
private readonly TriangleCalculationConfigService _configService;
private readonly GameData _luminaGameData;
public ModelAnalyzer(ILogger<ModelAnalyzer> logger, FileCacheManager fileCacheManager,
TriangleCalculationConfigService configService, IDataManager gameData)
{
_logger = logger;
_fileCacheManager = fileCacheManager;
_configService = configService;
_luminaGameData = new GameData(gameData.GameData.DataPath.FullName);
}
public Task<long> GetTrianglesFromGamePath(string gamePath)
{
if (_configService.Current.TriangleDictionary.TryGetValue(gamePath, out var cachedTris))
return Task.FromResult(cachedTris);
_logger.LogInformation("Detected Model File {path}, calculating Tris", gamePath);
var file = _luminaGameData.GetFile<MdlFile>(gamePath);
if (file == null)
return Task.FromResult((long)0);
if (file.FileHeader.LodCount <= 0)
return Task.FromResult((long)0);
var meshIdx = file.Lods[0].MeshIndex;
var meshCnt = file.Lods[0].MeshCount;
var tris = file.Meshes.Skip(meshIdx).Take(meshCnt).Sum(p => p.IndexCount) / 3;
_logger.LogInformation("{filePath} => {tris} triangles", gamePath, tris);
_configService.Current.TriangleDictionary[gamePath] = tris;
_configService.Save();
return Task.FromResult(tris);
}
public Task<long> GetTrianglesByHash(string hash)
{
if (_configService.Current.TriangleDictionary.TryGetValue(hash, out var cachedTris))
return Task.FromResult(cachedTris);
var path = _fileCacheManager.GetFileCacheByHash(hash);
if (path == null || !path.ResolvedFilepath.EndsWith(".mdl", StringComparison.OrdinalIgnoreCase))
return Task.FromResult((long)0);
var filePath = path.ResolvedFilepath;
_logger.LogInformation("Detected Model File {path}, calculating Tris", filePath);
var file = _luminaGameData.GetFileFromDisk<MdlFile>(filePath);
if (file.FileHeader.LodCount <= 0)
return Task.FromResult((long)0);
var meshIdx = file.Lods[0].MeshIndex;
var meshCnt = file.Lods[0].MeshCount;
var tris = file.Meshes.Skip(meshIdx).Take(meshCnt).Sum(p => p.IndexCount) / 3;
_logger.LogInformation("{filePath} => {tris} triangles", filePath, tris);
_configService.Current.TriangleDictionary[hash] = tris;
_configService.Save();
return Task.FromResult(tris);
}
}