/// <summary> /// Imports a raw File to a RedEngine file (e.g. .dds to .xbm, .fbx to .mesh) /// </summary> /// <param name="rawRelative"></param> /// <param name="args"></param> /// <param name="outDir">can be a depotpath, or if null the parent directory of the rawfile</param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public bool Import(RedRelativePath rawRelative, GlobalImportArgs args, DirectoryInfo outDir = null) { #region checks if (rawRelative is null or { Exists : false })
private bool Rebuild(Stream redfileStream, IEnumerable <FileInfo> buffers) => throw new TodoException();/*AppendBuffersToFile(redfileStream); * * return true; * * void AppendBuffersToFile(Stream fileStream) * { * var isResource = _wolvenkitFileService.IsCr2wFile(redfileStream); * if (!isResource) * { * return; * } * * using var reader = new CR2WReader(redfileStream); * _ = reader.ReadFile(out var cr2w, false); * * var existingBuffers = cr2w.Debug.BufferInfos.ToList(); * * // sort buffers numerically * var bufferlist = buffers.ToList(); * if (bufferlist.All(_ => _.Extension == ".buffer")) * { * bufferlist = bufferlist * .OrderBy(_ => int.Parse(Path.GetExtension(_.FullName.Remove(_.FullName.Length - 7))[1..])) * .ToList(); * } * if (bufferlist.All(_ => _.Extension == ".dds")) * { * // ml_w_knife__combat__grip1_01_masksset_0.dds * bufferlist = bufferlist * .OrderBy(n => Regex.Replace(n.Name, @"\d+", n => n.Value.PadLeft(4, '0'))) * //.OrderBy(_ => int.Parse(Path.GetExtension(_.FullName.Remove(_.FullName.Length - 4))[1..])) * .ToList(); * } * * for (var i = 0; i < bufferlist.Count; i++) * { * var buffer = bufferlist[i]; * if (!buffer.Exists) * { * throw new FileNotFoundException($"Could not find file {buffer.FullName} anymore."); * } * * var inbuffer = ReadBuffer(buffer); * if (inbuffer.Length < 1) * { * continue; * } * * uint flags = 0; * if (i < existingBuffers.Count) * { * flags = existingBuffers[i].flags; * } * * cr2w.Buffers.Add(RedBuffer.CreateBuffer(flags, inbuffer)); * } * * // write cr2w * redfileStream.Seek(0, SeekOrigin.Begin); * using var writer = new CR2WWriter(redfileStream); * writer.WriteFile(cr2w); * } * * static byte[] ReadBuffer(FileInfo buffer) * { * using var fs = new FileStream(buffer.FullName, FileMode.Open, FileAccess.Read); * using var br = new BinaryReader(fs); * var bext = buffer.Extension.ToLower(); * * // if dds file, delete the * if (bext != ".buffer") * { * switch (bext) * { * case ".dds": * // check if dx10 * fs.Seek(84, SeekOrigin.Begin); * var fourcc = br.ReadInt32(); * // delete dds header * if (fourcc == 808540228) //is dx10 * { * fs.Seek(148, SeekOrigin.Begin); * return br.ReadBytes((int)fs.Length - 148); * } * else * { * fs.Seek(128, SeekOrigin.Begin); * return br.ReadBytes((int)fs.Length - 128); * } * } * } * else * { * return fs.ToByteArray(); * } * * return Array.Empty<byte>(); * }*/ /// <summary> /// Rebuilds a single raw buffer into its redfile /// </summary> /// <param name="rawRelativePath"></param> /// <param name="outDir"></param> /// <returns></returns> public bool RebuildBuffer(RedRelativePath rawRelativePath, DirectoryInfo outDir = null) { var ext = rawRelativePath.Extension; // only buffers can be rebuilt if (ext != "buffer") { return(false); } if (outDir is not { Exists : true })
private void ImportTaskInner(string path, string outDir, bool keep) { #region checks if (string.IsNullOrEmpty(path)) { _loggerService.Warning("Please fill in an input path."); return; } if (!string.IsNullOrEmpty(outDir) && !Directory.Exists(outDir)) { _loggerService.Warning("Please fill in a valid outdirectory path."); return; } var rawFile = new FileInfo(path); var inputDirInfo = new DirectoryInfo(path); if (!rawFile.Exists && !inputDirInfo.Exists) { _loggerService.Warning("Input path does not exist."); return; } var isDirectory = !rawFile.Exists; var basedir = rawFile.Exists ? new FileInfo(path).Directory : inputDirInfo; #endregion checks // create import settings var settings = new GlobalImportArgs().Register( _commonImportArgs.Value, _xbmImportArgs.Value, _gltfImportArgs.Value ); settings.Get <CommonImportArgs>().Keep = keep; settings.Get <XbmImportArgs>().Keep = keep; settings.Get <GltfImportArgs>().Keep = keep; var outDirectory = string.IsNullOrEmpty(outDir) ? null : new DirectoryInfo(outDir); // a directory was selected to import if (isDirectory) { _modTools.ImportFolder(basedir, settings, outDirectory); } // just a single file was selected else { var rawRelative = new RedRelativePath(rawFile.Directory, rawFile.GetRelativePath(rawFile.Directory)); // check if the file can be directly imported // if not, rebuild the single file if (!Enum.TryParse(rawRelative.Extension, true, out ERawFileFormat extAsEnum)) { // buffers can not be rebuilt on their own if (!settings.Get <CommonImportArgs>().Keep) { return; } // outdir needs to be the parent dir of the redfile to rebuild !! (user needs to take care of that) if (_modTools.RebuildBuffer(rawRelative, outDirectory)) { _loggerService.Success($"Successfully imported {path} to {outDirectory.FullName}"); } else { _loggerService.Error($"Failed to import {path}"); } } // the raw file can be imported directly else { if (_modTools.Import(rawRelative, settings, outDirectory)) { _loggerService.Success($"Successfully imported {path}"); } else { _loggerService.Error($"Failed to import {path}"); } } } }
public void Test_ImportExport(ECookedFileFormat extension) { var ext = $".{extension.ToString()}"; var infiles = s_groupedFiles[ext].ToList(); var modtools = ServiceLocator.Default.ResolveType <ModTools>(); var resultDir = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory, "temp")); if (!resultDir.Exists) { Directory.CreateDirectory(resultDir.FullName); } var logDir = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory, "logs")); if (!logDir.Exists) { Directory.CreateDirectory(logDir.FullName); } var isKeep = bool.Parse(s_config.GetSection(s_KEEP).Value); var isettings = new GlobalImportArgs().Register( new XbmImportArgs() { Keep = isKeep }, new MeshImportArgs() { Keep = isKeep }, new CommonImportArgs() { Keep = isKeep } ); var esettings = new GlobalExportArgs(); var uncookfails = new List <FileEntry>(); var importfails = new List <FileEntry>(); var equalfails = new List <FileEntry>(); // random tests var random = new Random(); var limit = Math.Min(int.Parse(s_config.GetSection(s_LIMIT).Value), infiles.Count); var filesToTest = infiles.OrderBy(a => random.Next()).Take(limit).ToList(); for (var i = 0; i < filesToTest.Count; i++) { var fileEntry = filesToTest[i]; // skip files without buffers var hasBuffers = (fileEntry.SegmentsEnd - fileEntry.SegmentsStart) > 1; if (!hasBuffers) { continue; } var ar = fileEntry.Archive as Archive; using var cr2wstream = new MemoryStream(); ar.CopyFileToStream(cr2wstream, fileEntry.NameHash64, false); var originalBytes = cr2wstream.ToByteArray(); // uncook var resUncook = modtools.UncookSingle(fileEntry.Archive as Archive, fileEntry.Key, resultDir, esettings, resultDir); if (!resUncook) { uncookfails.Add(fileEntry); Cleanup(); continue; } // rebuild var allfiles = resultDir.GetFiles("*", SearchOption.AllDirectories); var rawfile = allfiles.FirstOrDefault(_ => _.Extension != ext); if (rawfile == null) { Assert.Fail($"No raw file found in {resultDir}"); } var redrelative = new RedRelativePath(rawfile.Directory, rawfile.Name); var resImport = modtools.Import(redrelative, isettings); if (!resImport) { importfails.Add(fileEntry); Cleanup(); continue; } // compare var redfile = allfiles.FirstOrDefault(_ => _.Extension == ext); if (redfile == null) { Assert.Fail($"No red file found in {resultDir}"); } var newbytes = File.ReadAllBytes(redfile.FullName); if (!originalBytes.SequenceEqual(newbytes)) { equalfails.Add(fileEntry); var filename = Path.GetFileName(fileEntry.FileName); var dbgOriginalFile = Path.Combine(logDir.FullName, filename); var dbgNewFile = Path.Combine(logDir.FullName, $"{filename}.new"); File.WriteAllBytes(dbgOriginalFile, originalBytes); File.WriteAllBytes(dbgNewFile, newbytes); } else { } // clean temp dir Cleanup(); } if (uncookfails.Count > 0) { foreach (var fileEntry in uncookfails) { Console.WriteLine($"Failed to uncook - {fileEntry.FileName}"); } } if (importfails.Count > 0) { foreach (var fileEntry in importfails) { Console.WriteLine($"Failed to import - {fileEntry.FileName}"); } } if (equalfails.Count > 0) { foreach (var fileEntry in equalfails) { Console.WriteLine($"Not binary equal - {fileEntry.FileName}"); } } Assert.AreEqual(0, uncookfails.Count + importfails.Count + equalfails.Count); // cleanup var allf = resultDir.GetFiles("*", SearchOption.AllDirectories); foreach (var fileInfo in allf) { fileInfo.Delete(); } var alld = resultDir.GetDirectories(); foreach (var directoryInfo in alld) { directoryInfo.Delete(true); } void Cleanup() { var allfiles = resultDir.GetFiles("*", SearchOption.AllDirectories); try { foreach (var fileInfo in allfiles) { fileInfo.Delete(); } } catch (Exception e) { Console.WriteLine(e); throw; } } }