3 Commits

Author SHA1 Message Date
ecenshu 359bb0ef3b Merge branch 'main' into feature/bugfix_selflock
ci / build_linux (push) Successful in 3m47s
ci / build_linux (pull_request) Successful in 3m45s
# Conflicts:
#	TinfoilVibeServer/Services/ROMArchiveReader.cs
#	TinfoilVibeServer/Services/SnapshotService.cs
2025-12-14 10:10:42 +10:30
ecenshu f710a4cbde Check lock against base archive in multipart scenario
ci / build_linux (push) Has been cancelled
ci / build_linux (pull_request) Successful in 8m8s
Explicitly attempt to close Reader when using ArchiveFactory
2025-12-14 10:05:53 +10:30
ecenshu eda922c3f3 Implement DisposeAsync
ci / build_linux (pull_request) Has been cancelled
ci / build_linux (push) Has been cancelled
Log when snapshot is added
2025-12-13 11:55:58 +10:30
4 changed files with 14 additions and 38 deletions
-1
View File
@@ -10,4 +10,3 @@ data/*
TinfoilVibeServer/config/prod.keys TinfoilVibeServer/config/prod.keys
TinfoilVibeServer/data/* TinfoilVibeServer/data/*
!TinfoilVibeServer/data/.gitkeep !TinfoilVibeServer/data/.gitkeep
.vs/
+9 -16
View File
@@ -7,7 +7,6 @@ using SharpCompress.Archives;
using SharpCompress.Archives.Rar; using SharpCompress.Archives.Rar;
using SharpCompress.Archives.SevenZip; using SharpCompress.Archives.SevenZip;
using SharpCompress.Common; using SharpCompress.Common;
using SharpCompress.Readers;
using TinfoilVibeServer.Models; using TinfoilVibeServer.Models;
using TinfoilVibeServer.Utilities; using TinfoilVibeServer.Utilities;
using ZipArchive = SharpCompress.Archives.Zip.ZipArchive; using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
@@ -152,10 +151,6 @@ public sealed class ArchiveHandler : IArchiveHandler
{ {
_logger.LogError("Failed to extract title info from archive {Archive}: {Exception}", path, e.Message); _logger.LogError("Failed to extract title info from archive {Archive}: {Exception}", path, e.Message);
} }
else if (e.Message.StartsWith("Unable to decrypt NCA section"))
{
_logger.LogError("Unable to decrypt NCA section, try updating prod.keys");
}
else else
{ {
throw; throw;
@@ -176,19 +171,17 @@ public sealed class ArchiveHandler : IArchiveHandler
_logger.LogInformation( _logger.LogInformation(
"Failed to open archive with SharpCompress, falling back to SharpSevenZip {Exception}", "Failed to open archive with SharpCompress, falling back to SharpSevenZip {Exception}",
exception.Message); exception.Message);
using var archive = SevenZipArchive.Open(path, new ReaderOptions { LeaveStreamOpen = false }); using var archive = SevenZipArchive.Open(path);
foreach (var entry in archive.Entries) foreach (var entry in archive.Entries)
{ {
if (entry is not { IsDirectory: false, Key: not null } || !IsRomArchive(entry.Key)) continue; if (entry is { IsDirectory: false, Key: not null } && IsRomArchive(entry.Key))
{
var temp = Path.GetTempFileName(); var temp = Path.GetTempFileName();
entry.WriteToFile(temp); entry.WriteToFile(temp);
var title = _nspExtractor.ExtractFromFile(temp); // instance call var title = _nspExtractor.ExtractFromFile(temp); // instance call
File.Delete(temp); File.Delete(temp);
if (title == null) continue; if (title != null) titles.Add((entry.Key, entry.Size, title));
}
_logger.LogInformation("Extracted title {Key} using SharpSevenZip", entry.Key);
titles.Add((entry.Key, entry.Size, title));
} }
} }
+3 -11
View File
@@ -317,12 +317,9 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
return; return;
} }
var cacheUpdated = _cache.ContainsKey(entry.Path);
var hashMatch = _hashCache.ContainsKey(entry.Hash) && _hashCache[entry.Hash] == entry.Path;
if (cacheUpdated && hashMatch) return;
var lastModified = File.GetLastWriteTimeUtc(entry.Path.Contains(ArchivePathSeparator) ? entry.Path.Split(ArchivePathSeparator)[0] : entry.Path); var lastModified = File.GetLastWriteTimeUtc(entry.Path.Contains(ArchivePathSeparator) ? entry.Path.Split(ArchivePathSeparator)[0] : entry.Path);
var cacheUpdated = _cache.ContainsKey(entry.Path);
_cache[entry.Path] = new SnapshotEntry(entry.Path, entry.Hash, entry.Size, lastModified, entry.Titles); _cache[entry.Path] = new SnapshotEntry(entry.Path, entry.Hash, entry.Size, lastModified, entry.Titles);
_hashCache[entry.Hash] = entry.Path; _hashCache[entry.Hash] = entry.Path;
_sizeLookup[entry.Hash] = entry.Size; _sizeLookup[entry.Hash] = entry.Size;
@@ -861,13 +858,12 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
try try
{ {
var ext = Path.GetExtension(filePath).ToLowerInvariant(); var ext = Path.GetExtension(filePath).ToLowerInvariant();
var multiPartBasePathWithExtension = $"{MultiPartRarHelper.GetBaseNameForRarVolume(filePath)}{ext}"; var multiPartBasePathWithExtension = $"{MultiPartRarHelper.GetBaseNameForRarVolume(filePath)}{ext}";
if (string.CompareOrdinal(multiPartBasePathWithExtension, filePath) != 0) if (string.CompareOrdinal(multiPartBasePathWithExtension, filePath) != 0)
{ {
filePath = multiPartBasePathWithExtension; filePath = multiPartBasePathWithExtension;
} }
if (FileLockHelper.IsFileLocked(filePath)) if (FileLockHelper.IsFileLocked(filePath))
{ {
throw new IOException("File is locked"); throw new IOException("File is locked");
@@ -911,10 +907,6 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
_logger.LogWarning("Load {Path} failed after {retries} attempts", filePath, attempt + 1); _logger.LogWarning("Load {Path} failed after {retries} attempts", filePath, attempt + 1);
return null; return null;
} }
catch (Exception exception)
{
_logger.LogError(exception, "Unknown exception: {exception}", exception.Message);
}
} }
return string.Empty; return string.Empty;
@@ -67,8 +67,7 @@ public sealed class RewindableStream : Stream
get get
{ {
EnsureLengthAsync(CancellationToken.None).GetAwaiter().GetResult(); EnsureLengthAsync(CancellationToken.None).GetAwaiter().GetResult();
if (_length != null) return _length.Value; return _length.Value;
return -1;
} }
} }
@@ -140,14 +139,7 @@ public sealed class RewindableStream : Stream
{ {
// We need the length first. // We need the length first.
EnsureLengthAsync(CancellationToken.None).GetAwaiter().GetResult(); EnsureLengthAsync(CancellationToken.None).GetAwaiter().GetResult();
if (_length != null) newPos = _length.Value + offset;
{
newPos = _length.Value + offset;
}
else
{
throw new NullReferenceException(nameof(_length));
}
} }
else else
{ {