public static async Task DdtBytes2TgaAsync(byte[] source, string path) { var data = source; if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } DdtFile ddt = new DdtFile(data, false); PngBitmapEncoder encoder = new PngBitmapEncoder(); byte[] raw_image = new byte[4 * ddt.BaseWidth * ddt.BaseHeight]; ddt.Bitmap.CopyPixels(raw_image, 4 * ddt.BaseWidth, 0); var tga = new TGAImage(ddt.BaseWidth, ddt.BaseHeight, (byte)ddt.Usage, (byte)ddt.Alpha, (byte)ddt.Format, ddt.MipmapLevels, raw_image); var file_name = Path.GetFileNameWithoutExtension(path); file_name = file_name + ".(" + tga.image_id[0].ToString() + "," + tga.image_id[1].ToString() + "," + tga.image_id[2].ToString() + "," + tga.image_id[3].ToString() + ").tga"; await File.WriteAllBytesAsync(Path.Combine(Path.GetDirectoryName(path), file_name), tga.ToByteArray()); }
public static async Task <GameFileInfo> GenerateGameFileInfo(string file, string fileName, string outputFolder, string baseHttpLink, CancellationToken ct = default) { if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } if (!baseHttpLink.EndsWith("/")) { baseHttpLink += "/"; } var binFileName = $"{fileName.ToLower().GetHashCode():X4}.bin"; var outFileName = Path.Combine(outputFolder, binFileName); await L33TZipUtils.CompressFileAsL33TZipAsync(file, outFileName, ct); var fileCrc = await Crc32Utils.DoGetCrc32FromFile(file, ct); var fileLength = new FileInfo(file).Length; var externalLocation = Path.Combine(baseHttpLink, binFileName).Replace("\\", "/"); var outFileCrc = await Crc32Utils.DoGetCrc32FromFile(outFileName, ct); var outFileLength = new FileInfo(outFileName).Length; return(new GameFileInfo(fileName, fileCrc, fileLength, externalLocation, outFileCrc, outFileLength)); }
public static async Task Ddt2PngAsync(string ddtFile) { var outname = ddtFile.ToLower().Replace(".ddt", ".png"); using (var fileStream = new FileStream(outname, FileMode.Create)) { // DdtFile ddt = new DdtFile(File.ReadAllBytes(ddtFile)); BitmapEncoder encoder = new PngBitmapEncoder(); var data = await File.ReadAllBytesAsync(ddtFile); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } //await File.WriteAllBytesAsync("test", data); encoder.Frames.Add(BitmapFrame.Create(new DdtFile(data, false).Bitmap)); encoder.Save(fileStream); } }
public async Task saveFiles(List <BarEntry> files, string savePath, bool Decompress, CancellationToken token, ExportDDT settings) { ResetProgress(); if (files.Count == 0) { return; } using var input = File.OpenRead(barFilePath); long filesSize = files.Sum(x => (long)x.FileSize2); foreach (var file in files) { if (token.IsCancellationRequested) { while (extractingState == 1) { await Task.Delay(1000); } } if (token.IsCancellationRequested && extractingState == 2) { ResetProgress(); return; } // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); Directory.CreateDirectory(Path.Combine(savePath, Path.GetDirectoryName(file.FileNameWithRoot))); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); // if (file.Extension != ".XMB" && (L33TZipUtils.IsL33TZipFile(data) || Alz4Utils.IsAlz4File(data)) && Decompress) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } } await File.WriteAllBytesAsync(Path.Combine(savePath, file.FileNameWithRoot), data); CurrentProgress += (double)file.FileSize2 / filesSize; } ResetProgress(); }
private static async Task <FileInfo> EnsureFileIsExtracted(FileInfo file) { if (file.FullName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase) && L33TZipUtils.IsL33TZipFile(file.FullName)) { var data = await L33TZipUtils.ExtractL33TZipFileAsync(file.FullName); File.Delete(file.FullName); File.WriteAllBytes(file.FullName, data); return(new FileInfo(file.FullName)); } return(file); }
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); }
public async Task readFile(BarEntry file) { // Firstly, is the file parameter null? PreviewDdt = null; Preview = null; PreviewImage = null; if (file == null) { return; } if (file.Extension == ".WAV" /* || file.Extension == ".MP3"*/) { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); //File.WriteAllBytes(file.fileNameWithoutPath, data); audio = new MemoryStream(data); if (file.isCompressed) { // AudioFileReader audioFileReader = new AudioFileReader(); // DirectSoundOut directSoundOut = new DirectSoundOut(); // audioFileReader. audio = new MemoryStream(data); } else { audio = new MemoryStream(data); } return; } if (file.Extension == ".DDT") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } PreviewDdt = new DdtFile(data, true); return; } if (file.Extension == ".BMP" || file.Extension == ".PNG" || file.Extension == ".CUR" || file.Extension == ".JPG") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } var bitmap = new BitmapImage(); using (var stream = new MemoryStream(data)) { bitmap.BeginInit(); bitmap.StreamSource = stream; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); } PreviewImage = bitmap; return; } if (file.Extension == ".XMB") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } //File.WriteAllBytes(file.fileNameWithoutPath, data); Preview = new Document(); Preview.SyntaxHighlighting = "XML"; Preview.Text = await XMBFile.XmbToXmlAsync(data); NotifyPropertyChanged("Preview"); return; } if (file.Extension == ".XAML" || file.Extension == ".XML" || file.Extension == ".SHP" || file.Extension == ".LGT" || file.Extension == ".XS" || file.Extension == ".TXT" || file.Extension == ".CFG" || file.Extension == ".PY") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } Preview = new Document(); Preview.Text = System.Text.Encoding.UTF8.GetString(data); if (file.Extension == ".XS") { Preview.SyntaxHighlighting = "C++"; } else { Preview.SyntaxHighlighting = "XML"; } NotifyPropertyChanged("Preview"); return; } return; }
public static async Task CreateXMBFileL33T(string filename) { using var output = new MemoryStream(); var writer = new BinaryWriter(output, Encoding.Default, true); writer.Write((byte)88); writer.Write((byte)49); writer.Write(0); writer.Write((byte)88); writer.Write((byte)82); writer.Write(4); writer.Write(8); XmlDocument file = new XmlDocument(); file.Load(filename); XmlNode rootElement = file.FirstChild; // Get the list of element/attribute names, sorted by first appearance List <XmlString> ElementNames = new List <XmlString>(); List <XmlString> AttributeNames = new List <XmlString>(); await Task.Run(() => { ExtractStrings(file.DocumentElement, ref ElementNames, ref AttributeNames); }); // Output element names int NumElements = ElementNames.Count; writer.Write(NumElements); for (int i = 0; i < NumElements; ++i) { writer.Write(ElementNames[i].Content.Length); writer.Write(Encoding.Unicode.GetBytes(ElementNames[i].Content)); } int NumAttributes = AttributeNames.Count; writer.Write(NumAttributes); for (int i = 0; i < NumAttributes; ++i) { writer.Write(AttributeNames[i].Content.Length); writer.Write(Encoding.Unicode.GetBytes(AttributeNames[i].Content)); } // Output root node, plus all descendants await Task.Run(() => { WriteNode(ref writer, rootElement, ElementNames, AttributeNames); }); // Fill in data-length field near the beginning long DataEnd = writer.BaseStream.Position; writer.BaseStream.Seek(2, SeekOrigin.Begin); int Length = (int)(DataEnd - (2 + 4)); writer.Write(Length); writer.BaseStream.Seek(DataEnd, SeekOrigin.Begin); await L33TZipUtils.CompressBytesAsL33TZipAsync(output.ToArray(), filename + ".xmb"); }
private async void convertFiles(object sender, RoutedEventArgs e) { mainMenu.IsEnabled = false; SpinnerConvert.Visibility = Visibility.Visible; tbConvert.Text = "Converting"; OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Multiselect = true; string operationType = (sender as MenuItem).Tag.ToString(); //await DdtFileUtils.Ddt2PngAsync(@"D:\Development\Resource Manager\Resource Manager\bin\Release\netcoreapp3.1\Art\ui\alerts\alert_treatyend_bump.ddt"); if (operationType == "topng") { openFileDialog.Filter = "Age of Empires 3 ddt files (*.ddt)|*.ddt"; if (openFileDialog.ShowDialog() == true) { foreach (var file in openFileDialog.FileNames) { try { await DdtFileUtils.Ddt2PngAsync(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "toxml") { openFileDialog.Filter = "Age of Empires 3 xmb files (*.xmb)|*.xmb"; if (openFileDialog.ShowDialog() == true) { foreach (var file in openFileDialog.FileNames) { try { var data = await File.ReadAllBytesAsync(file); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XMBFile xmb = await XMBFile.LoadXMBFile(stream); var newName = Path.ChangeExtension(file, ""); xmb.file.Save(newName); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "toxmbde") { openFileDialog.Filter = "Age of Empires 3 xml files (*.xml)|*.xml"; if (openFileDialog.ShowDialog() == true) { foreach (var file in openFileDialog.FileNames) { try { await XMBFile.CreateXMBFileALZ4(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "toxmbcc") { openFileDialog.Filter = "Age of Empires 3 xml files (*.xml)|*.xml"; if (openFileDialog.ShowDialog() == true) { foreach (var file in openFileDialog.FileNames) { try { await XMBFile.CreateXMBFileL33T(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } tbConvert.Text = "Convert"; SpinnerConvert.Visibility = Visibility.Collapsed; mainMenu.IsEnabled = true; }
public async Task saveFiles(List <BarEntry> files, string savePath, bool Decompress, CancellationToken token, bool convertDDT, bool convertXMB) { ResetProgress(); if (files.Count == 0) { return; } using var input = File.OpenRead(barFilePath); long filesSize = files.Sum(x => (long)x.FileSize2); foreach (var file in files) { if (token.IsCancellationRequested) { while (extractingState == 1) { await Task.Delay(1000); } } if (token.IsCancellationRequested && extractingState == 2) { ResetProgress(); return; } // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); Directory.CreateDirectory(Path.Combine(savePath, Path.GetDirectoryName(file.FileNameWithRoot))); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (file.Extension != ".XMB" && (L33TZipUtils.IsL33TZipFile(data) || Alz4Utils.IsAlz4File(data)) && Decompress) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } } if (file.Extension == ".WAV" || file.Extension == ".MP3") { if (file.isCompressed == 2) { data = await soundUtils.DecryptSound(data); } } await File.WriteAllBytesAsync(Path.Combine(savePath, file.FileNameWithRoot), data); if (file.Extension == ".XMB" && convertXMB) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XMBFile xmb = await XMBFile.LoadXMBFile(stream); var newName = Path.ChangeExtension(Path.Combine(savePath, file.FileNameWithRoot), ""); xmb.file.Save(newName); } if (file.Extension == ".DDT" && convertDDT) { await DdtFileUtils.DdtBytes2PngAsync(data, Path.Combine(savePath, file.FileNameWithRoot)); } CurrentProgress += (double)file.FileSize2 / filesSize; } ResetProgress(); }
private static async Task ConvertFile(bool convertFile, string tempFileName, BarEntry barFileInfo, string filePath) { //Convert file if (convertFile) { if (L33TZipUtils.IsL33TZipFile(tempFileName) && !barFileInfo.FileName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase)) { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); await L33TZipUtils.ExtractL33TZipFileAsync(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; } if (barFileInfo.FileName.EndsWith(".xmb", StringComparison.OrdinalIgnoreCase)) { try { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); XmbFileUtils.XmbToXml(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; filePath = filePath.Substring(0, filePath.Length - 4); } catch (Exception) { // } } else if (barFileInfo.FileName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase) && !L33TZipUtils.IsL33TZipFile(tempFileName)) { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); await L33TZipUtils.CompressFileAsL33TZipAsync(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; } } //Move new file if (File.Exists(filePath)) { File.Delete(filePath); } File.Move(tempFileName, filePath); File.SetCreationTimeUtc(filePath, new DateTime(barFileInfo.LastWriteTime.Year, barFileInfo.LastWriteTime.Month, barFileInfo.LastWriteTime.Day, barFileInfo.LastWriteTime.Hour, barFileInfo.LastWriteTime.Minute, barFileInfo.LastWriteTime.Second)); File.SetLastWriteTimeUtc(filePath, new DateTime(barFileInfo.LastWriteTime.Year, barFileInfo.LastWriteTime.Month, barFileInfo.LastWriteTime.Day, barFileInfo.LastWriteTime.Hour, barFileInfo.LastWriteTime.Minute, barFileInfo.LastWriteTime.Second)); }
public static void CreateBarFile(IReadOnlyCollection <FileInfo> fileInfos, string inputPath, string outputFileName, string rootDir, bool ignoreLastWriteTime = true, bool xmlToXmb = true) { if (inputPath.EndsWith(Path.DirectorySeparatorChar.ToString())) { inputPath = inputPath.Substring(0, inputPath.Length - 1); } var folder = Path.GetDirectoryName(outputFileName); if (folder != null && !Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var newFilesInfos = new List <FileInfo>(); foreach (var file in fileInfos.ToArray()) { if (file.FullName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase)) { if (L33TZipUtils.IsL33TZip(file.FullName)) { var data = L33TZipUtils.DecompressL33TZip(file.FullName); File.Delete(file.FullName); File.WriteAllBytes(file.FullName, data); newFilesInfos.Add(new FileInfo(file.FullName)); } else { newFilesInfos.Add(file); } } else if (xmlToXmb && file.FullName.EndsWith(".quest", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".region", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".tactics", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".character", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".dataset", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".empire", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".spawneritem", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".groupingset", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".set", StringComparison.OrdinalIgnoreCase) || file.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) { if (XmbFile.IsXmlFile(file.FullName)) { XmbFileUtils.XmlFileToXmbFile(file.FullName, file.FullName + ".xmb"); File.Delete(file.FullName); newFilesInfos.Add(new FileInfo(file.FullName + ".xmb")); } else { newFilesInfos.Add(file); } } else { newFilesInfos.Add(file); } } using var fileStream = File.Open(outputFileName, FileMode.Create, FileAccess.Write, FileShare.None); using var writer = new BinaryWriter(fileStream); //Write Bar Header var header = new BarFileHeader(Path.GetFileName(outputFileName), newFilesInfos); writer.Write(header.ToByteArray()); //Write Files var barEntrys = new List <BarEntry>(); foreach (var file in newFilesInfos) { var filePath = file.FullName; barEntrys.Add(new BarEntry(inputPath, file, (int)writer.BaseStream.Position, ignoreLastWriteTime)); using var fileStream2 = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); using var binReader = new BinaryReader(fileStream2); var buffer = new byte[4096]; int read; while ((read = binReader.Read(buffer, 0, buffer.Length)) > 0) { writer.Write(buffer, 0, read); } } //Write Bar Entrys var end = new BarFileBody(rootDir, barEntrys); writer.Write(end.ToByteArray()); }
public static void ExtractBarFiles(string inputFile, string outputPath, bool convertFile = true) { if (!File.Exists(inputFile)) { throw new FileNotFoundException($"File '{inputFile}' not found!", inputFile); } if (!outputPath.EndsWith(Path.DirectorySeparatorChar.ToString())) { outputPath = outputPath + Path.DirectorySeparatorChar; } BarFileBody barFilesInfo; using (var fileStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { using var binReader = new BinaryReader(fileStream); //Read Header binReader.BaseStream.Seek(0, SeekOrigin.Begin); //Seek to header var barFileHeader = new BarFileHeader(binReader); //Read Files Info binReader.BaseStream.Seek(barFileHeader.FilesTableOffset, SeekOrigin.Begin); //Seek to file table barFilesInfo = new BarFileBody(binReader); } var exceptions = new BlockingCollection <Exception>(); Parallel.ForEach(barFilesInfo.Entries.ToArray(), barFileInfo => { try { using var fileStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read); using var binReader = new BinaryReader(fileStream); binReader.BaseStream.Seek(barFileInfo.Offset, SeekOrigin.Begin); //Seek to file var path = Path.Combine(outputPath, barFilesInfo.RootPath, Path.GetDirectoryName(barFileInfo.FileName) ?? string.Empty); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var filePath = Path.Combine(outputPath, barFilesInfo.RootPath, barFileInfo.FileName); //Extract to tmp file var tempFileName = Path.GetTempFileName(); using (var fileStreamFinal = File.Open(tempFileName, FileMode.Create, FileAccess.Write, FileShare.None)) { using var final = new BinaryWriter(fileStreamFinal); var buffer = new byte[4096]; int read; var totalread = 0L; while ((read = binReader.Read(buffer, 0, buffer.Length)) > 0) { if (read > barFileInfo.FileSize) { totalread = barFileInfo.FileSize; final.Write(buffer, 0, barFileInfo.FileSize); } else if (totalread + read <= barFileInfo.FileSize) { totalread += read; final.Write(buffer, 0, read); } else if (totalread + read > barFileInfo.FileSize) { var leftToRead = barFileInfo.FileSize - totalread; totalread = barFileInfo.FileSize; final.Write(buffer, 0, Convert.ToInt32(leftToRead)); } if (totalread >= barFileInfo.FileSize) { break; } } } //Convert file if (convertFile) { if (L33TZipUtils.IsL33TZip(tempFileName) && !barFileInfo.FileName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase)) { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); L33TZipUtils.DecompressL33TZip(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; } if (barFileInfo.FileName.EndsWith(".xmb", StringComparison.OrdinalIgnoreCase)) { try { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); XmbFileUtils.XmbFileToXmlFile(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; filePath = filePath.Substring(0, filePath.Length - 4); } catch (Exception) { // } } else if (barFileInfo.FileName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase) && !L33TZipUtils.IsL33TZip(tempFileName)) { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); L33TZipUtils.CompressFileAsL33TZipAsync(tempFileName, tempFileName2).GetAwaiter() .GetResult(); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; } } //Move new file if (File.Exists(filePath)) { File.Delete(filePath); } // File.Move(tempFileName, filePath); // File.SetCreationTimeUtc(filePath, new DateTime(barFileInfo.LastWriteTime.Year, barFileInfo.LastWriteTime.Month, barFileInfo.LastWriteTime.Day, barFileInfo.LastWriteTime.Hour, barFileInfo.LastWriteTime.Minute, barFileInfo.LastWriteTime.Second)); File.SetLastWriteTimeUtc(filePath, new DateTime(barFileInfo.LastWriteTime.Year, barFileInfo.LastWriteTime.Month, barFileInfo.LastWriteTime.Day, barFileInfo.LastWriteTime.Hour, barFileInfo.LastWriteTime.Minute, barFileInfo.LastWriteTime.Second)); } catch (Exception e) { exceptions.Add(e); } }); exceptions.CompleteAdding(); if (exceptions.Count > 0) { throw new AggregateException(exceptions.ToArray()); } }
public static void ExtractBarFile(string inputFile, string file, string outputPath, bool convertFile = true) { if (string.IsNullOrWhiteSpace(file)) { throw new ArgumentNullException(nameof(file), "Value cannot be null or empty."); } if (!File.Exists(inputFile)) { throw new FileNotFoundException($"File '{inputFile}' not found!", inputFile); } if (!outputPath.EndsWith(Path.DirectorySeparatorChar.ToString())) { outputPath = outputPath + Path.DirectorySeparatorChar; } BarFile barFilesInfo; using (var fileStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var binReader = new BinaryReader(fileStream)) { //Read Header binReader.BaseStream.Seek(0, SeekOrigin.Begin); //Seek to header var barFileHeader = new BarFileHeader(binReader); //Read Files Info binReader.BaseStream.Seek(barFileHeader.FilesTableOffset, SeekOrigin.Begin); //Seek to file table barFilesInfo = new BarFile(binReader); } } var barFileInfo = barFilesInfo.BarFileEntrys.First( key => string.Equals(key.FileName, file, StringComparison.OrdinalIgnoreCase)); using (var fileStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var binReader = new BinaryReader(fileStream)) { binReader.BaseStream.Seek(barFileInfo.Offset, SeekOrigin.Begin); //Seek to file var path = Path.Combine(outputPath, barFilesInfo.RootPath, Path.GetDirectoryName(barFileInfo.FileName) ?? string.Empty); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var filePath = Path.Combine(outputPath, barFilesInfo.RootPath, barFileInfo.FileName); //Extract to tmp file var tempFileName = Path.GetTempFileName(); using (var fileStreamFinal = File.Open(tempFileName, FileMode.Create, FileAccess.Write, FileShare.None)) { using (var final = new BinaryWriter(fileStreamFinal)) { var buffer = new byte[4096]; int read; var totalread = 0L; while ((read = binReader.Read(buffer, 0, buffer.Length)) > 0) { if (read > barFileInfo.FileSize) { totalread = barFileInfo.FileSize; final.Write(buffer, 0, barFileInfo.FileSize); } else if (totalread + read <= barFileInfo.FileSize) { totalread += read; final.Write(buffer, 0, read); } else if (totalread + read > barFileInfo.FileSize) { var leftToRead = barFileInfo.FileSize - totalread; totalread = barFileInfo.FileSize; final.Write(buffer, 0, Convert.ToInt32(leftToRead)); } if (totalread >= barFileInfo.FileSize) { break; } } } } //Convert file if (convertFile) { if (L33TZipUtils.IsL33TZipFile(tempFileName) && !barFileInfo.FileName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase)) { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); L33TZipUtils.ExtractL33TZipFile(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; } if (barFileInfo.FileName.EndsWith(".xmb", StringComparison.OrdinalIgnoreCase)) { try { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); XmbFileUtils.XmbToXml(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; filePath = filePath.Substring(0, filePath.Length - 4); } catch (Exception) { // } } else if (barFileInfo.FileName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase) && !L33TZipUtils.IsL33TZipFile(tempFileName)) { var rnd = new Random(Guid.NewGuid().GetHashCode()); var tempFileName2 = Path.Combine(Path.GetTempPath(), $"{Path.GetFileName(barFileInfo.FileName)}-{rnd.Next()}.tmp"); L33TZipUtils.CreateL33TZipFile(tempFileName, tempFileName2); if (File.Exists(tempFileName)) { File.Delete(tempFileName); } tempFileName = tempFileName2; } } //Move new file if (File.Exists(filePath)) { File.Delete(filePath); } // File.Move(tempFileName, filePath); // File.SetCreationTimeUtc(filePath, new DateTime(barFileInfo.LastWriteTime.Year, barFileInfo.LastWriteTime.Month, barFileInfo.LastWriteTime.Day, barFileInfo.LastWriteTime.Hour, barFileInfo.LastWriteTime.Minute, barFileInfo.LastWriteTime.Second)); File.SetLastWriteTimeUtc(filePath, new DateTime(barFileInfo.LastWriteTime.Year, barFileInfo.LastWriteTime.Month, barFileInfo.LastWriteTime.Day, barFileInfo.LastWriteTime.Hour, barFileInfo.LastWriteTime.Minute, barFileInfo.LastWriteTime.Second)); } } }
public static void CreateBarFile(IReadOnlyCollection <FileInfo> fileInfos, string inputPath, string outputFileName, string rootdir, bool ignoreLastWriteTime = true) { if (inputPath.EndsWith(Path.DirectorySeparatorChar.ToString())) { inputPath = inputPath.Substring(0, inputPath.Length - 1); } var folder = Path.GetDirectoryName(outputFileName); if (folder != null && !Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var newFilesInfos = new List <FileInfo>(); foreach (var file in fileInfos.ToArray()) { if (file.FullName.EndsWith(".age4scn", StringComparison.OrdinalIgnoreCase) && L33TZipUtils.IsL33TZipFile(file.FullName)) { var data = L33TZipUtils.ExtractL33TZipFile(file.FullName); File.Delete(file.FullName); File.WriteAllBytes(file.FullName, data); newFilesInfos.Add(new FileInfo(file.FullName)); } else { newFilesInfos.Add(file); } } using (var fileStream = File.Open(outputFileName, FileMode.Create, FileAccess.Write, FileShare.None)) { using (var writer = new BinaryWriter(fileStream)) { //Write Bar Header var header = new BarFileHeader(Path.GetFileName(outputFileName), newFilesInfos); writer.Write(header.ToByteArray()); //Write Files var barEntrys = new List <BarEntry>(); foreach (var file in newFilesInfos) { var filePath = file.FullName; barEntrys.Add(new BarEntry(inputPath, file, (int)writer.BaseStream.Position, ignoreLastWriteTime)); using (var fileStream2 = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var binReader = new BinaryReader(fileStream2)) { var buffer = new byte[4096]; int read; while ((read = binReader.Read(buffer, 0, buffer.Length)) > 0) { writer.Write(buffer, 0, read); } } } } //Write Bar Entrys var end = new BarFile(rootdir, barEntrys); writer.Write(end.ToByteArray()); } } }
public async void GetCustomValues(string filename) { if (!File.Exists(filename)) { throw new Exception("BAR file does not exist!"); } using var file = File.OpenRead(filename); var reader = new BinaryReader(file); reader.BaseStream.Seek(entry.Offset, SeekOrigin.Begin); byte[] data = reader.ReadBytes(entry.FileSize2); await Task.Run(() => { entry.CRC32 = Crc32Algorithm.Compute(data); }); reader.BaseStream.Seek(entry.Offset, SeekOrigin.Begin); HeaderText = new string(reader.ReadChars(4)); reader.BaseStream.Seek(entry.Offset, SeekOrigin.Begin); Header = reader.ReadInt32(); if (entry.Extension == ".DDT") { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } PreviewDdt = new DdtFile(data, true); var flagList = new List <string>(); if (PreviewDdt.Usage.HasFlag(DdtFileTypeUsage.AlphaTest)) { flagList.Add(DdtFileTypeUsage.AlphaTest.ToString()); } if (PreviewDdt.Usage.HasFlag(DdtFileTypeUsage.LowDetail)) { flagList.Add(DdtFileTypeUsage.LowDetail.ToString()); } if (PreviewDdt.Usage.HasFlag(DdtFileTypeUsage.Bump)) { flagList.Add(DdtFileTypeUsage.Bump.ToString()); } if (PreviewDdt.Usage.HasFlag(DdtFileTypeUsage.Cube)) { flagList.Add(DdtFileTypeUsage.Cube.ToString()); } if (flagList.Count > 0) { DdtUsage = ((byte)PreviewDdt.Usage).ToString() + " (" + string.Join('+', flagList) + ")"; } else { DdtUsage = ((byte)PreviewDdt.Usage).ToString(); } DdtAlpha = ((byte)PreviewDdt.Alpha).ToString() + " (" + PreviewDdt.Alpha.ToString() + ")"; DdtFormat = ((byte)PreviewDdt.Format).ToString() + " (" + PreviewDdt.Format.ToString() + ")"; gpDDT.Visibility = Visibility.Visible; } }
private async void convertFiles(object sender, RoutedEventArgs e) { mainMenu.IsEnabled = false; SpinnerConvert.Visibility = Visibility.Visible; tbConvert.Text = "Converting"; OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = Settings.Default.lastConvertedPath; openFileDialog.Multiselect = true; string operationType = (sender as MenuItem).Tag.ToString(); //await DdtFileUtils.Ddt2PngAsync(@"D:\Development\Resource Manager\Resource Manager\bin\Release\netcoreapp3.1\Art\ui\alerts\alert_treatyend_bump.ddt"); if (operationType == "totga") { openFileDialog.Filter = "Age of Empires 3 ddt files (*.ddt)|*.ddt"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { await DdtFileUtils.Ddt2TgaAsync(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "topng") { openFileDialog.Filter = "Age of Empires 3 ddt files (*.ddt)|*.ddt"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { await DdtFileUtils.Ddt2PngAsync(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "toxml") { openFileDialog.Filter = "Age of Empires 3 xmb files (*.xmb)|*.xmb"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { var data = await File.ReadAllBytesAsync(file); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XMBFile xmb = await XMBFile.LoadXMBFile(stream); var newName = Path.ChangeExtension(file, ""); xmb.file.Save(newName); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "jsontoxml") { openFileDialog.Filter = "JSON files (*.json)|*.json"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { var data = await File.ReadAllBytesAsync(file); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } string json = await File.ReadAllTextAsync(file); var xml = JsonConvert.DeserializeXmlNode(json); var newName = Path.ChangeExtension(file, ""); xml.Save(newName); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "xmbtojson") { openFileDialog.Filter = "Age of Empires 3 xmb files (*.xmb)|*.xmb"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { var data = await File.ReadAllBytesAsync(file); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XMBFile xmb = await XMBFile.LoadXMBFile(stream); string json = JsonConvert.SerializeXmlNode(xmb.file); await File.WriteAllTextAsync(Path.ChangeExtension(file, "json"), json); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "xmltojson") { openFileDialog.Filter = "Age of Empires 3 xml files (*.*)|*.*"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { XmlDocument xml = new XmlDocument(); xml.Load(file); string json = JsonConvert.SerializeXmlNode(xml); await File.WriteAllTextAsync(Path.ChangeExtension(file, "json"), json); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "jsontoxmblegacy") { openFileDialog.Filter = "JSON files (*.json)|*.json"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { string json = await File.ReadAllTextAsync(file); var xml = JsonConvert.DeserializeXmlNode(json); await XMBFile.CreateXMBFileL33T(xml, file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "jsontoxmbde") { openFileDialog.Filter = "JSON files (*.json)|*.json"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { string json = await File.ReadAllTextAsync(file); var xml = JsonConvert.DeserializeXmlNode(json); await XMBFile.CreateXMBFileALZ4(xml, file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "toxmbde") { openFileDialog.Filter = "Age of Empires 3 xml files (*.*)|*.*"; if (openFileDialog.ShowDialog() == true) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); foreach (var file in openFileDialog.FileNames) { try { await XMBFile.CreateXMBFileALZ4(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } if (operationType == "toxmbcc") { openFileDialog.Filter = "Age of Empires 3 xml files (*.*)|*.*"; if (openFileDialog.ShowDialog() == true) { foreach (var file in openFileDialog.FileNames) { Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName); Settings.Default.Save(); try { await XMBFile.CreateXMBFileL33T(file); } catch (Exception ex) { MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error); } } } } tbConvert.Text = "Convert"; SpinnerConvert.Visibility = Visibility.Collapsed; mainMenu.IsEnabled = true; }
public async Task saveFiles(List <BarEntry> files, string savePath, bool Decompress, CancellationToken token, bool convertDDTToPNG, bool convertDDTToTGA, bool convertXMB, bool OneFolder, bool SavePNGasBMP, bool AutoJSONConversion, Color OverlayColor) { ResetProgress(); if (files.Count == 0) { return; } using var input = File.OpenRead(barFilePath); long filesSize = files.Sum(x => (long)x.FileSize2); foreach (var file in files) { if (token.IsCancellationRequested) { while (extractingState == 1) { await Task.Delay(1000); } } if (token.IsCancellationRequested && extractingState == 2) { ResetProgress(); return; } // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); string ExtractPath = Path.Combine(savePath, file.FileNameWithRoot); if (OneFolder) { ExtractPath = Path.Combine(savePath, file.fileNameWithoutPath); } Directory.CreateDirectory(Path.GetDirectoryName(ExtractPath)); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); // XMB and decompress if (file.Extension != ".XMB" && (L33TZipUtils.IsL33TZipFile(data) || Alz4Utils.IsAlz4File(data)) && Decompress) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } } // WAV or MP3 if (file.Extension == ".WAV" || file.Extension == ".MP3") { if (file.isCompressed == 2) { data = await soundUtils.DecryptSound(data); } } // Save PNG as BMP, skip saving as PNG if (file.Extension == ".PNG" && SavePNGasBMP) { using var memory = new MemoryStream(data); Bitmap img = new Bitmap(memory); PixelFormat fmt1 = img.PixelFormat; byte bpp1 = 4; Rectangle rect = new Rectangle(Point.Empty, new Size(img.Width, img.Height)); BitmapData bmpData = img.LockBits(rect, ImageLockMode.ReadWrite, fmt1); int size1 = bmpData.Stride * bmpData.Height; byte[] pixels = new byte[size1]; Marshal.Copy(bmpData.Scan0, pixels, 0, size1); for (int y = 0; y < img.Height; y++) { for (int x = 0; x < img.Width; x++) { int index = y * bmpData.Stride + x * bpp1; var alpha = pixels[index + 3]; if (alpha < 255) { pixels[index] = (byte)(pixels[index] * OverlayColor.B / 255); //b pixels[index + 1] = (byte)(pixels[index + 1] * OverlayColor.G / 255); //g pixels[index + 2] = (byte)(pixels[index + 2] * OverlayColor.R / 255); //r pixels[index + 3] = 255; } } } Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length); img.UnlockBits(bmpData); using (Graphics g = Graphics.FromImage(img)) { g.DrawImage(new Bitmap(memory), Point.Empty); } img.Save(ExtractPath, System.Drawing.Imaging.ImageFormat.Png); CurrentProgress += (double)file.FileSize2 / filesSize; continue; } // Save data await File.WriteAllBytesAsync(ExtractPath, data); // Additionaly convert xmb if (file.Extension == ".XMB" && convertXMB) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XMBFile xmb = await XMBFile.LoadXMBFile(stream); xmb.file.Save(Path.ChangeExtension(ExtractPath, "")); } // Additionaly convert xmb -> json if (file.Extension == ".XMB" && AutoJSONConversion) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XMBFile xmb = await XMBFile.LoadXMBFile(stream); string json = JsonConvert.SerializeXmlNode(xmb.file); await File.WriteAllTextAsync(Path.ChangeExtension(ExtractPath, "json"), json); } // Additionaly convert xml -> json if (file.Extension == ".XML" && AutoJSONConversion) { if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } using MemoryStream stream = new MemoryStream(data); XmlDocument xml = new XmlDocument(); xml.Load(stream); string json = JsonConvert.SerializeXmlNode(xml); await File.WriteAllTextAsync(Path.ChangeExtension(ExtractPath, "json"), json); } // Additionaly convert ddt to png if (file.Extension == ".DDT" && convertDDTToPNG) { await DdtFileUtils.DdtBytes2PngAsync(data, ExtractPath); } // Additionaly convert ddt to tga if (file.Extension == ".DDT" && convertDDTToTGA) { await DdtFileUtils.DdtBytes2TgaAsync(data, ExtractPath); } CurrentProgress += (double)file.FileSize2 / filesSize; } ResetProgress(); }
public async Task readFile(BarEntry file) { // Firstly, is the file parameter null? PreviewDdt = null; Preview = null; PreviewImage = null; if (file == null) { return; } if (file.Extension == ".WAV" || file.Extension == ".MP3") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (file.isCompressed == 2) { audio = new MemoryStream(await soundUtils.DecryptSound(data)); } else { audio = new MemoryStream(data); } return; } if (file.Extension == ".DDT") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } PreviewDdt = new DdtFile(data, true); return; } if (file.Extension == ".BMP" || file.Extension == ".TGA" || file.Extension == ".PNG" || file.Extension == ".CUR" || file.Extension == ".JPG") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } var bitmap = new BitmapImage(); using (var stream = new MemoryStream(data)) { if (file.Extension == ".TGA") { IImage image = await Task.Run(() => Pfim.Pfim.FromStream(stream)); var pinnedArray = GCHandle.Alloc(image.Data, GCHandleType.Pinned); var addr = pinnedArray.AddrOfPinnedObject(); var bsource = BitmapSource.Create(image.Width, image.Height, 96.0, 96.0, PixelFormat(image), null, addr, image.DataLen, image.Stride); PngBitmapEncoder encoder = new PngBitmapEncoder(); MemoryStream memoryStream = new MemoryStream(); encoder.Frames.Add(BitmapFrame.Create(bsource)); encoder.Save(memoryStream); memoryStream.Position = 0; bitmap.BeginInit(); bitmap.StreamSource = memoryStream; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); memoryStream.Close(); } /*else if (file.Extension == ".PNG") * { * System.Drawing.Image image = System.Drawing.Image.FromStream(stream); * using var memory = new MemoryStream(); * image.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp); * memory.Seek(0, SeekOrigin.Begin); * bitmap.BeginInit(); * bitmap.CacheOption = BitmapCacheOption.OnLoad; * bitmap.StreamSource = memory; * bitmap.EndInit(); * }*/ else { bitmap.BeginInit(); bitmap.StreamSource = stream; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); } } PreviewImage = bitmap; return; } if (file.Extension == ".XMB") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } //File.WriteAllBytes(file.fileNameWithoutPath, data); Preview = new Document(); Preview.SyntaxHighlighting = "XML"; Preview.Text = await XMBFile.XmbToXmlAsync(data); NotifyPropertyChanged("Preview"); return; } if (file.Extension == ".XAML" || file.Extension == ".XML" || file.Extension == ".SHP" || file.Extension == ".LGT" || file.Extension == ".XS" || file.Extension == ".TXT" || file.Extension == ".CFG" || file.Extension == ".PY" || file.Extension == ".TACTICS") { using FileStream input = File.OpenRead(barFilePath); // Locate the file within the BAR file. input.Seek(file.Offset, SeekOrigin.Begin); var data = new byte[file.FileSize2]; await input.ReadAsync(data, 0, data.Length); if (Alz4Utils.IsAlz4File(data)) { data = await Alz4Utils.ExtractAlz4BytesAsync(data); } else { if (L33TZipUtils.IsL33TZipFile(data)) { data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data); } } Preview = new Document(); Preview.Text = System.Text.Encoding.UTF8.GetString(data); if (file.Extension == ".XS") { Preview.SyntaxHighlighting = "C++"; } else { Preview.SyntaxHighlighting = "XML"; } NotifyPropertyChanged("Preview"); return; } return; }
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); }