Skip to content

Commit 97fe0e7

Browse files
martinmineRyddag
authored andcommitted
Improved exception messages and minor refactoring (#9)
1 parent 1bb8088 commit 97fe0e7

1 file changed

Lines changed: 73 additions & 75 deletions

File tree

src/GameScannnerManager.cs

Lines changed: 73 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,20 @@ public class GameScannnerManager : IDisposable
3030

3131
private bool _scanIsRunning;
3232

33-
private readonly bool _useChunkDownloader;
34-
3533
private CancellationTokenSource _cts;
3634

3735
private IEnumerable<GameFileInfo> _gameFiles;
3836

39-
public GameScannnerManager(bool useChunkDownloader = false, bool isSteam = false) : this(GetGameFilesRootPath(),
40-
useChunkDownloader, isSteam)
37+
public GameScannnerManager(bool isSteam = false) : this(GetGameFilesRootPath(), isSteam)
4138
{
4239
}
4340

44-
public GameScannnerManager(string filesRootPath, bool useChunkDownloader, bool isSteam = false)
41+
public GameScannnerManager(string filesRootPath, bool isSteam = false)
4542
{
4643
if (string.IsNullOrEmpty(filesRootPath))
47-
throw new ArgumentException("Game files path is null or empty!", nameof(filesRootPath));
44+
throw new ArgumentException("Game files path is null or empty", nameof(filesRootPath));
4845

4946
_filesRootPath = filesRootPath;
50-
_useChunkDownloader = useChunkDownloader;
5147
_isSteam = isSteam;
5248
_scanIsRunning = false;
5349
}
@@ -72,38 +68,33 @@ public async Task InitializeFromCelesteManifest()
7268

7369
CleanUpTmpFolder();
7470

75-
//
7671
var gameFileInfos = await GameFilesInfoFromCelesteManifest(_isSteam);
77-
var fileInfos = gameFileInfos as GameFileInfo[] ?? gameFileInfos.ToArray();
78-
if (!fileInfos.Any())
79-
throw new ArgumentException("Game files info is null or empty!", nameof(gameFileInfos));
72+
var gamesFiles = gameFileInfos as GameFileInfo[] ?? gameFileInfos.ToArray();
73+
if (!gamesFiles.Any())
74+
throw new ArgumentException("Game files info is null or empty", nameof(gameFileInfos));
8075

81-
_gameFiles = fileInfos;
76+
_gameFiles = gamesFiles;
8277
}
8378

84-
public async Task InitializeFromGameManifest(string type, int build)
79+
public async Task InitializeFromGameManifest()
8580
{
8681
if (_gameFiles?.Any() == true)
8782
throw new Exception("Already Initialized");
8883

8984
CleanUpTmpFolder();
9085

91-
//
9286
var gameFileInfos = await GameFilesInfoFromCelesteManifest(_isSteam);
9387
var fileInfos = gameFileInfos as GameFileInfo[] ?? gameFileInfos.ToArray();
9488
if (!fileInfos.Any())
95-
throw new ArgumentException("Game files info is null or empty!", nameof(gameFileInfos));
89+
throw new ArgumentException("Game files info is null or empty", nameof(gameFileInfos));
9690

9791
_gameFiles = fileInfos;
9892
}
9993

10094
public async Task<bool> Scan(bool quick = true, IProgress<ScanProgress> progress = null)
10195
{
102-
if (_gameFiles == null || !_gameFiles.Any())
103-
throw new Exception("Not Initialized");
104-
105-
if (_scanIsRunning)
106-
throw new Exception("Scan already running!");
96+
EnsureInitialized();
97+
EnsureGameScannerIsNotRunning();
10798

10899
_scanIsRunning = true;
109100

@@ -115,8 +106,6 @@ public async Task<bool> Scan(bool quick = true, IProgress<ScanProgress> progress
115106
_cts = new CancellationTokenSource();
116107
var token = _cts.Token;
117108

118-
//
119-
120109
var totalSize = _gameFiles.Select(key => key.Size).Sum();
121110
var currentSize = 0L;
122111
var index = 0;
@@ -179,17 +168,13 @@ public async Task<bool> Scan(bool quick = true, IProgress<ScanProgress> progress
179168
public async Task<bool> ScanAndRepair(IProgress<ScanProgress> progress = null,
180169
IProgress<ScanSubProgress> subProgress = null)
181170
{
182-
if (_gameFiles == null || !_gameFiles.Any())
183-
throw new Exception("Not Initialized");
184-
185-
if (_scanIsRunning)
186-
throw new Exception("Scan already running!");
171+
EnsureInitialized();
172+
EnsureGameScannerIsNotRunning();
187173

188174
_scanIsRunning = true;
189175

190176
try
191177
{
192-
//
193178
if (_cts != null)
194179
{
195180
_cts.Cancel();
@@ -200,13 +185,10 @@ public async Task<bool> ScanAndRepair(IProgress<ScanProgress> progress = null,
200185

201186
var token = _cts.Token;
202187

203-
//
204188
CleanUpTmpFolder();
205189

206-
//
207190
var retVal = false;
208191

209-
//
210192
var totalSize = _gameFiles.Select(key => key.BinSize).Sum();
211193
var globalProgress = 0L;
212194
var totalIndex = _gameFiles.Count();
@@ -221,7 +203,7 @@ public async Task<bool> ScanAndRepair(IProgress<ScanProgress> progress = null,
221203
progress?.Report(new ScanProgress(fileInfo.FileName,
222204
(double) globalProgress / totalSize * 100, i, totalIndex));
223205

224-
retVal = await ScanAndRepairFile(fileInfo, _filesRootPath, _useChunkDownloader, subProgress, token);
206+
retVal = await ScanAndRepairFile(fileInfo, _filesRootPath, subProgress, token);
225207

226208
if (!retVal)
227209
break;
@@ -248,6 +230,18 @@ public void Abort()
248230
_cts.Cancel();
249231
}
250232

233+
private void EnsureInitialized()
234+
{
235+
if (_gameFiles == null || !_gameFiles.Any())
236+
throw new Exception("Game scanner has not been initialized or no game files was found");
237+
}
238+
239+
private void EnsureGameScannerIsNotRunning()
240+
{
241+
if (_scanIsRunning)
242+
throw new Exception("Scan is already running");
243+
}
244+
251245
private static void CleanUpTmpFolder()
252246
{
253247
if (!Directory.Exists(GameScannerTempPath))
@@ -280,23 +274,38 @@ private static void CleanUpTmpFolder()
280274

281275
#region GameFile
282276

283-
public static async Task<bool> RunFileCheck(string filePath, long fileSize, uint fileCrc32,
284-
CancellationToken ct = default,
285-
IProgress<double> progress = null)
277+
public static async Task EnsureValidGameFile(string gameFilePath, long expectedFileSize, uint expectedCrc32,
278+
CancellationToken ct = default, IProgress<double> progress = null)
286279
{
287-
return RunFileQuickCheck(filePath, fileSize) &&
288-
fileCrc32 == await Crc32Utils.DoGetCrc32FromFile(filePath, ct, progress);
280+
var gameFileInfo = new FileInfo(gameFilePath);
281+
282+
if (!gameFileInfo.Exists)
283+
throw new Exception($"The game file {gameFilePath} does not exist");
284+
285+
if (gameFileInfo.Length != expectedFileSize)
286+
throw new Exception($"The game file {gameFilePath} was expected to have a size of {expectedFileSize} but was {gameFileInfo.Length}");
287+
288+
var gameFileCrc32 = await Crc32Utils.DoGetCrc32FromFile(gameFilePath, ct, progress);
289+
290+
if (gameFileCrc32 != expectedCrc32)
291+
throw new Exception($"The game file {gameFilePath} was expected to have a crc32 {expectedCrc32} but was {gameFileCrc32}");
289292
}
290293

291-
public static bool RunFileQuickCheck(string filePath, long fileSize)
294+
public static async Task<bool> RunFileCheck(string gameFilePath, long expectedFileSize, uint expectedCrc32,
295+
CancellationToken ct = default, IProgress<double> progress = null)
292296
{
293-
var fi = new FileInfo(filePath);
294-
return fi.Exists && fi.Length == fileSize;
297+
return RunFileQuickCheck(gameFilePath, expectedFileSize) &&
298+
expectedCrc32 == await Crc32Utils.DoGetCrc32FromFile(gameFilePath, ct, progress);
299+
}
300+
301+
public static bool RunFileQuickCheck(string gameFilePath, long expectedFileSize)
302+
{
303+
var fi = new FileInfo(gameFilePath);
304+
return fi.Exists && fi.Length == expectedFileSize;
295305
}
296306

297307
public static async Task<bool> ScanAndRepairFile(GameFileInfo fileInfo, string gameFilePath,
298-
bool useChunkDownloader = false, IProgress<ScanSubProgress> progress = null,
299-
CancellationToken ct = default)
308+
IProgress<ScanSubProgress> progress = null, CancellationToken ct = default)
300309
{
301310
var filePath = Path.Combine(gameFilePath, fileInfo.FileName);
302311

@@ -364,15 +373,8 @@ public static async Task<bool> ScanAndRepairFile(GameFileInfo fileInfo, string g
364373
}
365374
};
366375

367-
try
368-
{
369-
await fileDownloader.DownloadAsync(ct);
370-
}
371-
catch (Exception e)
372-
{
373-
throw new Exception($"Downloaded file '{fileInfo.FileName}' failed!\r\n" +
374-
$"{e.Message}");
375-
}
376+
await fileDownloader.DownloadAsync(ct);
377+
376378

377379
//#3 Check Downloaded File
378380
ct.ThrowIfCancellationRequested();
@@ -390,12 +392,16 @@ public static async Task<bool> ScanAndRepairFile(GameFileInfo fileInfo, string g
390392
};
391393
}
392394

393-
if (!await RunFileCheck(tempFileName, fileInfo.BinSize, fileInfo.BinCrc32, ct, subProgressCheckDown))
395+
try
396+
{
397+
await EnsureValidGameFile(tempFileName, fileInfo.BinSize, fileInfo.BinCrc32, ct, subProgressCheckDown);
398+
}
399+
catch
394400
{
395401
if (File.Exists(tempFileName))
396402
File.Delete(tempFileName);
397403

398-
throw new Exception($"Downloaded file '{fileInfo.FileName}' is invalid!");
404+
throw;
399405
}
400406

401407
//#4 Extract downloaded file
@@ -424,7 +430,6 @@ public static async Task<bool> ScanAndRepairFile(GameFileInfo fileInfo, string g
424430
Progress<double> subProgressCheckExt = null;
425431
if (progress != null)
426432
{
427-
//
428433
progress.Report(new ScanSubProgress(
429434
ScanSubProgressStep.CheckExtractDownload, 0));
430435

@@ -436,8 +441,7 @@ public static async Task<bool> ScanAndRepairFile(GameFileInfo fileInfo, string g
436441
};
437442
}
438443

439-
if (!await RunFileCheck(tempFileName2, fileInfo.Size, fileInfo.Crc32, ct, subProgressCheckExt))
440-
throw new Exception($"Extracted file '{fileInfo.FileName}' is invalid!");
444+
await EnsureValidGameFile(tempFileName2, fileInfo.Size, fileInfo.Crc32, ct, subProgressCheckExt);
441445

442446
File.Delete(tempFileName);
443447

@@ -582,14 +586,14 @@ public static async Task<IEnumerable<GameFileInfo>> GameFilesInfoFromCelesteMani
582586
.ToDictionary(key => key.FileName, StringComparer.OrdinalIgnoreCase);
583587

584588
//Load Celeste override
585-
string json;
589+
string manifestJsonContents;
586590
using (var client = new WebClient())
587591
{
588-
json = await client.DownloadStringTaskAsync(
592+
manifestJsonContents = await client.DownloadStringTaskAsync(
589593
"https://downloads.projectceleste.com/game_files/manifest_override.json");
590594
}
591595

592-
var filesInfoOverride = JsonConvert.DeserializeObject<GameFilesInfo>(json).GameFileInfo.ToArray()
596+
var filesInfoOverride = JsonConvert.DeserializeObject<GameFilesInfo>(manifestJsonContents).GameFileInfo.ToArray()
593597
.Select(key => key.Value);
594598

595599
foreach (var fileInfo in filesInfoOverride)
@@ -614,22 +618,20 @@ public static async Task CreateUpdatePackage(string inputFolder, string outputFo
614618
baseHttpLink += "/";
615619
baseHttpLink = Path.Combine(baseHttpLink, "bin_override", buildId.ToString()).Replace("\\", "/");
616620

617-
var data = await GenerateGameFilesInfo(inputFolder, finalOutputFolder, baseHttpLink, buildId, ct);
621+
var gameFiles = await GenerateGameFilesInfo(inputFolder, finalOutputFolder, baseHttpLink, buildId, ct);
618622

619-
if (data.GameFileInfo.Count < 1)
620-
throw new Exception("FileInfo.Count < 1");
623+
if (gameFiles.GameFileInfo.Count < 1)
624+
throw new Exception($"No game files found in {inputFolder}");
621625

622-
//Json
623-
var json = JsonConvert.SerializeObject(data, Formatting.Indented);
624-
File.WriteAllText(Path.Combine(finalOutputFolder, $"manifest_override-{buildId}.json"), json,
626+
var manifestJsonContents = JsonConvert.SerializeObject(gameFiles, Formatting.Indented);
627+
File.WriteAllText(Path.Combine(finalOutputFolder, $"manifest_override-{buildId}.json"), manifestJsonContents,
625628
Encoding.UTF8);
626-
File.WriteAllText(Path.Combine(outputFolder, "manifest_override.json"), json, Encoding.UTF8);
629+
File.WriteAllText(Path.Combine(outputFolder, "manifest_override.json"), manifestJsonContents, Encoding.UTF8);
627630

628-
//Xml
629-
var xml = data.SerializeToXml();
630-
File.WriteAllText(Path.Combine(finalOutputFolder, $"manifest_override-{buildId}.xml"), xml,
631+
var manifestXmlContents = gameFiles.SerializeToXml();
632+
File.WriteAllText(Path.Combine(finalOutputFolder, $"manifest_override-{buildId}.xml"), manifestXmlContents,
631633
Encoding.UTF8);
632-
File.WriteAllText(Path.Combine(outputFolder, "manifest_override.xml"), xml, Encoding.UTF8);
634+
File.WriteAllText(Path.Combine(outputFolder, "manifest_override.xml"), manifestXmlContents, Encoding.UTF8);
633635
}
634636

635637
private static async Task<GameFilesInfo> GenerateGameFilesInfo(string inputFolder, string outputFolder,
@@ -643,10 +645,8 @@ private static async Task<GameFilesInfo> GenerateGameFilesInfo(string inputFolde
643645
var newFilesInfo = new List<GameFileInfo>();
644646
foreach (var file in Directory.GetFiles(inputFolder, "*", SearchOption.AllDirectories))
645647
{
646-
//
647648
ct.ThrowIfCancellationRequested();
648649

649-
//
650650
var rootPath = inputFolder;
651651
if (!rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
652652
rootPath += Path.DirectorySeparatorChar;
@@ -679,10 +679,8 @@ private static async Task<GameFileInfo> GenerateGameFileInfo(string file, string
679679
var outFileCrc = await Crc32Utils.DoGetCrc32FromFile(outFileName, ct);
680680
var outFileLength = new FileInfo(outFileName).Length;
681681

682-
var fileInfo = new GameFileInfo(fileName, fileCrc, fileLength, externalLocation,
682+
return new GameFileInfo(fileName, fileCrc, fileLength, externalLocation,
683683
outFileCrc, outFileLength);
684-
685-
return fileInfo;
686684
}
687685

688686
#endregion

0 commit comments

Comments
 (0)