private static async Task <GameFileInfo> GenerateGameFileInfo(string file, string fileName, string outputFolder, #pragma warning disable IDE0034 // Simplifier l'expression 'default' string baseHttpLink, CancellationToken ct = default(CancellationToken)) #pragma warning restore IDE0034 // Simplifier l'expression 'default' { if (!baseHttpLink.EndsWith("/")) { baseHttpLink += "/"; } var binFileName = $"{fileName.ToLower().GetHashCode():X4}.bin"; var outFileName = Path.Combine(outputFolder, binFileName); await L33TZipUtils.DoCreateL33TZipFile(file, outFileName, ct); var fileInfo = new GameFileInfo(fileName, await Crc32Utils.DoGetCrc32FromFile(file, ct), new FileInfo(file).Length, Path.Combine(baseHttpLink, binFileName).Replace("\\", "/"), await Crc32Utils.DoGetCrc32FromFile(outFileName, ct), new FileInfo(outFileName).Length); return(fileInfo); }
public static async Task <bool> ScanAndRepairFile(GameFileInfo fileInfo, string gameFilePath, PathTransformer pathTransformer, IProgress <ScanSubProgress> progress = null, int concurrentDownload = 0, CancellationToken ct = default) { var filePath = Path.Combine(gameFilePath, pathTransformer.TransformPath(fileInfo.FileName)); //#1 Check File ct.ThrowIfCancellationRequested(); progress?.Report(new ScanSubProgress(ScanSubProgressStep.Check, 0)); Progress <double> subProgressCheck = null; if (progress != null) { subProgressCheck = new Progress <double>(); subProgressCheck.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.Check, d)); }; } if (await RunFileCheck(filePath, fileInfo.Size, fileInfo.Crc32, ct, subProgressCheck)) { progress?.Report(new ScanSubProgress(ScanSubProgressStep.End, 100)); return(true); } //#2 Download File ct.ThrowIfCancellationRequested(); progress?.Report(new ScanSubProgress(ScanSubProgressStep.Download, 0)); var tempFileName = Path.Combine(GameScannerTempPath, $"{fileInfo.FileName.GetHashCode():X4}.tmp"); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } var fileDownloader = concurrentDownload == 1 ? (IFileDownloader) new SimpleFileDownloader(fileInfo.HttpLink, tempFileName) : new ChunkFileDownloader(fileInfo.HttpLink, tempFileName, GameScannerTempPath, concurrentDownload); if (progress != null) { fileDownloader.ProgressChanged += (sender, eventArg) => { switch (fileDownloader.State) { case FileDownloaderState.Invalid: case FileDownloaderState.Download: progress.Report(new ScanSubProgress( ScanSubProgressStep.Download, fileDownloader.DownloadProgress * 0.99, new ScanDownloadProgress(fileDownloader.DownloadSize, fileDownloader.BytesDownloaded, fileDownloader.DownloadSpeed))); break; case FileDownloaderState.Finalize: progress.Report(new ScanSubProgress( ScanSubProgressStep.Download, 99, new ScanDownloadProgress(fileDownloader.DownloadSize, fileDownloader.BytesDownloaded, 0))); break; case FileDownloaderState.Complete: progress.Report(new ScanSubProgress( ScanSubProgressStep.Download, 100, new ScanDownloadProgress(fileDownloader.DownloadSize, fileDownloader.BytesDownloaded, 0))); break; case FileDownloaderState.Error: case FileDownloaderState.Abort: break; default: throw new ArgumentOutOfRangeException(nameof(fileDownloader.State), fileDownloader.State, null); } } } ; await fileDownloader.DownloadAsync(ct); //#3 Check Downloaded File ct.ThrowIfCancellationRequested(); Progress <double> subProgressCheckDown = null; if (progress != null) { progress.Report(new ScanSubProgress(ScanSubProgressStep.CheckDownload, 0)); subProgressCheckDown = new Progress <double>(); subProgressCheckDown.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.CheckDownload, d)); }; } try { await EnsureValidGameFile(tempFileName, fileInfo.BinSize, fileInfo.BinCrc32, ct, subProgressCheckDown); } catch { if (File.Exists(tempFileName)) { File.Delete(tempFileName); } throw; } //#4 Extract downloaded file ct.ThrowIfCancellationRequested(); if (L33TZipUtils.IsL33TZipFile(tempFileName)) { var tempFileName2 = $"{tempFileName.Replace(".tmp", string.Empty)}.ext.tmp"; // Progress <double> extractProgress = null; if (progress != null) { progress.Report(new ScanSubProgress( ScanSubProgressStep.ExtractDownload, 0)); extractProgress = new Progress <double>(); extractProgress.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.ExtractDownload, d)); }; } await L33TZipUtils.ExtractL33TZipFileAsync(tempFileName, tempFileName2, ct, extractProgress); //#4.1 Check Extracted File ct.ThrowIfCancellationRequested(); Progress <double> subProgressCheckExt = null; if (progress != null) { progress.Report(new ScanSubProgress( ScanSubProgressStep.CheckExtractDownload, 0)); subProgressCheckExt = new Progress <double>(); subProgressCheckExt.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.CheckExtractDownload, d)); }; } await EnsureValidGameFile(tempFileName2, fileInfo.Size, fileInfo.Crc32, ct, subProgressCheckExt); File.Delete(tempFileName); tempFileName = tempFileName2; } //#5 Move new file to game folder ct.ThrowIfCancellationRequested(); progress?.Report(new ScanSubProgress( ScanSubProgressStep.Finalize, 0)); if (File.Exists(filePath)) { File.Delete(filePath); } else { var pathName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(pathName) && !Directory.Exists(pathName)) { Directory.CreateDirectory(pathName); } } File.Move(tempFileName, filePath); //#6 End progress?.Report(new ScanSubProgress( ScanSubProgressStep.End, 100)); return(true); }
private static async Task <bool> ScanAndRepairFile(GameFileInfo fileInfo, string gameFilePath, IProgress <ScanAndRepairFileProgress> progress, CancellationToken ct) { try { var filePath = Path.Combine(gameFilePath, fileInfo.FileName); ct.ThrowIfCancellationRequested(); //#1 File Check progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 1, new ExLog(LogLevel.Info, "-------------------------\r\n" + $"[{fileInfo.FileName}]\r\n" + "-------------------------\r\n" + " - Checking file..."))); if (RunFileCheck(filePath, fileInfo.Size, fileInfo.Crc32)) { goto end; } progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 5, new ExLog(LogLevel.Warn, " Warning: File is missing or invalid."))); ct.ThrowIfCancellationRequested(); //#6 Download File progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 6, new ExLog(LogLevel.Info, " - File downloading..."))); var dowloadProgress = new Progress <DownloadFileProgress>(); if (progress != null) { dowloadProgress.ProgressChanged += (o, ea) => { progress.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 6 + Convert.ToInt32(Math.Floor((double)ea.ProgressPercentage / 100 * (65 - 6))), ea)); } } ; var tempFileName = Path.Combine(GetTempPath(), Path.GetRandomFileName()); var x = new DownloadFileUtils(new Uri(fileInfo.HttpLink), tempFileName, dowloadProgress); await x.DoDownload(ct); ct.ThrowIfCancellationRequested(); //#65 Check Downloaded File progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 65, new ExLog(LogLevel.Info, " - Checking downloaded file..."))); if (!RunFileCheck(tempFileName, fileInfo.BinSize, fileInfo.BinCrc32)) { if (File.Exists(tempFileName)) { File.Delete(tempFileName); } throw new Exception("Downloaded file is invalid!"); } ct.ThrowIfCancellationRequested(); //#70 Extract downloaded file var tmpFilePath = tempFileName; var tempFileName2 = Path.Combine(GetTempPath(), Path.GetRandomFileName()); if (ZipUtils.IsL33TZipFile(tempFileName)) { ct.ThrowIfCancellationRequested(); // progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 70, new ExLog(LogLevel.Info, " - Extract downloaded file..."))); var extractProgress = new Progress <ZipFileProgress>(); if (progress != null) { extractProgress.ProgressChanged += (o, ea) => { progress.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 70 + Convert.ToInt32(Math.Floor((double)ea.ProgressPercentage / 100 * (90 - 70))), ea)); } } ; await ZipUtils.DoExtractL33TZipFile(tempFileName, tempFileName2, extractProgress, ct); ct.ThrowIfCancellationRequested(); //#90 Check Downloaded File if (!RunFileCheck(tempFileName2, fileInfo.Size, fileInfo.Crc32)) { if (File.Exists(tempFileName)) { File.Delete(tempFileName); } if (File.Exists(tempFileName2)) { File.Delete(tempFileName2); } throw new Exception("Extracted file is invalid!"); } tmpFilePath = tempFileName2; } else if (ZipUtils.IsL66TZipFile(tempFileName)) { ct.ThrowIfCancellationRequested(); // progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 70, new ExLog(LogLevel.Info, " - Extract downloaded file..."))); var extractProgress = new Progress <ZipFileProgress>(); if (progress != null) { extractProgress.ProgressChanged += (o, ea) => { progress.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 70 + Convert.ToInt32(Math.Floor((double)ea.ProgressPercentage / 100 * (90 - 70))), ea)); } } ; await ZipUtils.DoExtractL66TZipFile(tempFileName, tempFileName2, extractProgress, ct); ct.ThrowIfCancellationRequested(); //#90 Check Downloaded File if (!RunFileCheck(tempFileName2, fileInfo.Size, fileInfo.Crc32)) { if (File.Exists(tempFileName)) { File.Delete(tempFileName); } if (File.Exists(tempFileName2)) { File.Delete(tempFileName2); } throw new Exception("Extracted file is invalid!"); } tmpFilePath = tempFileName2; } ct.ThrowIfCancellationRequested(); //#95 Move new file to game folder progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 95, new ExLog(LogLevel.Info, " - Moving new file..."))); if (File.Exists(filePath)) { File.Delete(filePath); } var pathName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(pathName) && !Directory.Exists(pathName)) { Directory.CreateDirectory(pathName); } File.Move(tmpFilePath, filePath); //#99 Removing temporary file progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 99, new ExLog(LogLevel.Info, " - Clean-up temporary files..."))); if (File.Exists(tmpFilePath)) { File.Delete(tmpFilePath); } if (File.Exists(tempFileName)) { File.Delete(tempFileName); } if (File.Exists(tempFileName2)) { File.Delete(tempFileName2); } end: //#100 progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 100)); } catch (AggregateException e) { progress?.Report(new ScanAndRepairFileProgress(fileInfo.FileName, 100, new ExLog(LogLevel.Info, "-------------------------\r\n" + "!!! Error !!!\r\n" + "-------------------------\r\n" + $"{e.Message}"))); return(false); } return(true); }
public static async Task <bool> ScanAndRepairFile(GameFileInfo fileInfo, string gameFilePath, bool useChunkDownloader = false, IProgress <ScanSubProgress> progress = null, #pragma warning disable IDE0034 // Simplifier l'expression 'default' CancellationToken ct = default(CancellationToken)) #pragma warning restore IDE0034 // Simplifier l'expression 'default' { var filePath = Path.Combine(gameFilePath, fileInfo.FileName); //#1 Check File ct.ThrowIfCancellationRequested(); progress?.Report(new ScanSubProgress(ScanSubProgressStep.Check, 0)); Progress <double> subProgressCheck = null; if (progress != null) { subProgressCheck = new Progress <double>(); subProgressCheck.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.Check, d)); }; } if (await RunFileCheck(filePath, fileInfo.Size, fileInfo.Crc32, ct, subProgressCheck)) { progress?.Report(new ScanSubProgress(ScanSubProgressStep.End, 100)); return(true); } //#2 Download File ct.ThrowIfCancellationRequested(); progress?.Report(new ScanSubProgress(ScanSubProgressStep.Download, 0)); var tempFileName = Path.Combine(GameScannerTempPath, $"{fileInfo.FileName.GetHashCode():X4}.tmp"); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } var fileDownloader = useChunkDownloader && fileInfo.BinSize > ChunkFileDownloader.ChunkSizeLimit ? new ChunkFileDownloader(fileInfo.HttpLink, tempFileName, GameScannerTempPath) : (IFileDownloader) new SimpleFileDownloader(fileInfo.HttpLink, tempFileName); if (progress != null) { fileDownloader.ProgressChanged += (sender, eventArg) => { switch (fileDownloader.State) { case FileDownloaderState.Invalid: case FileDownloaderState.Download: progress.Report(new ScanSubProgress( ScanSubProgressStep.Download, fileDownloader.DwnlProgress * 0.99, new ScanDownloadProgress(fileDownloader.DwnlSize, fileDownloader.DwnlSizeCompleted, fileDownloader.DwnlSpeed))); break; case FileDownloaderState.Finalize: progress.Report(new ScanSubProgress( ScanSubProgressStep.Download, 99, new ScanDownloadProgress(fileDownloader.DwnlSize, fileDownloader.DwnlSizeCompleted, 0))); break; case FileDownloaderState.Complete: progress.Report(new ScanSubProgress( ScanSubProgressStep.Download, 100, new ScanDownloadProgress(fileDownloader.DwnlSize, fileDownloader.DwnlSizeCompleted, 0))); break; case FileDownloaderState.Error: case FileDownloaderState.Abort: break; default: throw new ArgumentOutOfRangeException(nameof(fileDownloader.State), fileDownloader.State, null); } } } ; try { await fileDownloader.Download(ct); } catch (Exception e) { throw new Exception($"Downloaded file '{fileInfo.FileName}' failed!\r\n" + $"{e.Message}"); } //#3 Check Downloaded File ct.ThrowIfCancellationRequested(); Progress <double> subProgressCheckDown = null; if (progress != null) { progress.Report(new ScanSubProgress(ScanSubProgressStep.CheckDownload, 0)); subProgressCheckDown = new Progress <double>(); subProgressCheckDown.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.CheckDownload, d)); }; } if (!await RunFileCheck(tempFileName, fileInfo.BinSize, fileInfo.BinCrc32, ct, subProgressCheckDown)) { if (File.Exists(tempFileName)) { File.Delete(tempFileName); } throw new Exception($"Downloaded file '{fileInfo.FileName}' is invalid!"); } //#4 Extract downloaded file ct.ThrowIfCancellationRequested(); if (L33TZipUtils.IsL33TZipFile(tempFileName)) { var tempFileName2 = $"{tempFileName.Replace(".tmp", string.Empty)}.ext.tmp"; // Progress <double> extractProgress = null; if (progress != null) { progress.Report(new ScanSubProgress( ScanSubProgressStep.ExtractDownload, 0)); extractProgress = new Progress <double>(); extractProgress.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.ExtractDownload, d)); }; } await L33TZipUtils.DoExtractL33TZipFile(tempFileName, tempFileName2, ct, extractProgress); //#4.1 Check Extracted File ct.ThrowIfCancellationRequested(); Progress <double> subProgressCheckExt = null; if (progress != null) { // progress.Report(new ScanSubProgress( ScanSubProgressStep.CheckExtractDownload, 0)); subProgressCheckExt = new Progress <double>(); subProgressCheckExt.ProgressChanged += (o, d) => { progress.Report(new ScanSubProgress( ScanSubProgressStep.CheckExtractDownload, d)); }; } if (!await RunFileCheck(tempFileName2, fileInfo.Size, fileInfo.Crc32, ct, subProgressCheckExt)) { throw new Exception($"Extracted file '{fileInfo.FileName}' is invalid!"); } tempFileName = tempFileName2; } //#5 Move new file to game folder ct.ThrowIfCancellationRequested(); progress?.Report(new ScanSubProgress( ScanSubProgressStep.Finalize, 0)); if (File.Exists(filePath)) { File.Delete(filePath); } else { var pathName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(pathName) && !Directory.Exists(pathName)) { Directory.CreateDirectory(pathName); } } File.Move(tempFileName, filePath); //#6 End progress?.Report(new ScanSubProgress( ScanSubProgressStep.End, 100)); return(true); }