private static int ExportTaskInner(string path, EUncookExtension uncookext) { #region checks if (string.IsNullOrEmpty(path)) { logger.LogString("Please fill in an input path.", Logtype.Error); return(0); } var inputFileInfo = new FileInfo(path); if (!inputFileInfo.Exists) { logger.LogString("Input file does not exist.", Logtype.Error); return(0); } #endregion Stopwatch watch = new(); watch.Restart(); if (ModTools.Export(new FileInfo(path), uncookext)) { watch.Stop(); logger.LogString($"Successfully exported {path} in {watch.ElapsedMilliseconds.ToString()}ms.", Logtype.Success); } else { watch.Stop(); logger.LogString($"Failed to export {path}.", Logtype.Error); } return(1); }
//[DataRow("lang_ar_text.archive")] //[DataRow("lang_cs_text.archive")] //[DataRow("lang_de_text.archive")] //[DataRow("lang_en_text.archive")] //[DataRow("lang_en_voice.archive")] //[DataRow("lang_es-es_text.archive")] //[DataRow("lang_es-mx_text.archive")] //[DataRow("lang_fr_text.archive")] //[DataRow("lang_hu_text.archive")] //[DataRow("lang_it_text.archive")] //[DataRow("lang_ja_text.archive")] //[DataRow("lang_ko_text.archive")] //[DataRow("lang_pl_text.archive")] //[DataRow("lang_pt_text.archive")] //[DataRow("lang_ru_text.archive")] //[DataRow("lang_th_text.archive")] //[DataRow("lang_tr_text.archive")] //[DataRow("lang_zh-cn_text.archive")] //[DataRow("lang_zh-tw_text.archive")] public void Test_Unbundle(string archivename) { var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory); Directory.CreateDirectory(resultDir); var results = new ConcurrentBag <ArchiveTestResult>(); var archiveFullName = Path.Combine(s_gameDirectoryPath, "archive", "pc", "content", archivename); var archive = s_bm.Archives.Lookup(archiveFullName).Value as Archive; Parallel.ForEach(archive.Files, keyvalue => { var(hash, _) = keyvalue; try { using (var ms = new MemoryStream()) { ModTools.ExtractSingleToStream(archive, hash, ms); } results.Add(new ArchiveTestResult() { ArchiveName = archivename, Hash = hash.ToString(), Success = true }); } catch (Exception e) { results.Add(new ArchiveTestResult() { ArchiveName = archivename, Hash = hash.ToString(), Success = false, ExceptionType = e.GetType(), Message = $"{e.Message}" }); } }); var totalCount = archive.Files.Count; // Check success var successCount = results.Count(r => r.Success); var sb = new StringBuilder(); sb.AppendLine($"Successfully unbundled: {successCount} / {totalCount} ({(int)(successCount / (double)totalCount * 100)}%)"); var success = results.All(r => r.Success); if (success) { return; } var msg = $"Successful Writes: {successCount} / {totalCount}. "; Assert.Fail(msg); }
private static int ExportTaskInner(string path, EUncookExtension uncookext) { #region checks if (string.IsNullOrEmpty(path)) { logger.LogString("Please fill in an input path.", Logtype.Error); return(0); } var inputFileInfo = new FileInfo(path); if (!inputFileInfo.Exists) { logger.LogString("Input file does not exist.", Logtype.Error); return(0); } #endregion if (ModTools.Export(new FileInfo(path), uncookext) == 1) { logger.LogString($"Successfully exported {path}.", Logtype.Success); } else { logger.LogString($"Failed to export {path}.", Logtype.Error); } return(1); }
public void DumpExtensionInfo() { var parser = ServiceLocator.Default.ResolveType <Red4ParserService>(); var results = new Dictionary <string, ConcurrentDictionary <string, ulong> >(); foreach (var e in s_groupedFiles) { results.Add(e.Key, new ConcurrentDictionary <string, ulong>()); } var excludedExtensions = new List <string>() { ".wem", ".bin", ".bnk", ".opuspak", ".opusinfo", ".bk2", ".dat" }; // Run Test foreach (var item in s_groupedFiles.Where(_ => !excludedExtensions.Contains(_.Key))) { var ext = item.Key; var files = item.Value; Parallel.ForEach(files, file => { var hash = file.Key; var archive = file.Archive as Archive; try { using var originalMemoryStream = new MemoryStream(); ModTools.ExtractSingleToStream(archive, hash, originalMemoryStream); var originalFile = parser.TryReadRED4FileHeaders(originalMemoryStream); if (originalFile != null) { var c = originalFile.StringDictionary[1]; results[ext].TryAdd(c, 0); } else { } } catch (Exception) { } }); } var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory); Directory.CreateDirectory(resultDir); using var sw = new StringWriter(); foreach (var(key, classes) in results) { sw.WriteLine($"{key}: {string.Join(",", classes.Keys.ToList())}"); } File.WriteAllText(Path.Combine(resultDir, "classes.txt"), sw.ToString()); }
public OpusTools(Archive soundbanks, string modFolder, string rawFolder, bool useMod = false) //audio_2_soundbanks.archive { _soundBanks = soundbanks; _modFolder = new DirectoryInfo(modFolder); _rawFolder = new DirectoryInfo(rawFolder); _isModded = useMod; if (!Directory.Exists(Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks"))) { Directory.CreateDirectory(Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks")); } if (!Directory.Exists(_rawFolder.FullName)) { Directory.CreateDirectory(_rawFolder.FullName); } if (_isModded) { var infoFile = Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks\\sfx_container.opusinfo"); if (File.Exists(infoFile)) { var ms = new MemoryStream(File.ReadAllBytes(infoFile)); var br = new BinaryReader(ms); ms.Position = 0; if (BitConverter.ToString(br.ReadBytes(3)) != "53-4E-44") { _isModded = false; } else { Info = new OpusInfo(ms); } } else { _isModded = false; } } if (!_isModded) { var hash = FNV1A64HashAlgorithm.HashString("base\\sound\\soundbanks\\sfx_container.opusinfo"); var ms = new MemoryStream(); if (_soundBanks.Files.ContainsKey(hash)) { ModTools.ExtractSingleToStream(_soundBanks, hash, ms); Info = new OpusInfo(ms); } else { Info = new OpusInfo(); } } }
private static void PackTaskInner(string path, string outpath, int cp = 0) { #region checks if (string.IsNullOrEmpty(path)) { logger.LogString("Please fill in an input path.", Logtype.Error); return; } var inputDirInfo = new DirectoryInfo(path); if (!Directory.Exists(path) || !inputDirInfo.Exists) { logger.LogString("Input path does not exist.", Logtype.Error); return; } var basedir = inputDirInfo; if (basedir?.Parent == null) { return; } DirectoryInfo outDir; if (string.IsNullOrEmpty(outpath)) { outDir = basedir.Parent; } else { outDir = new DirectoryInfo(outpath); if (!outDir.Exists) { outDir = Directory.CreateDirectory(outpath); } } #endregion checks var ar = ModTools.Pack(basedir, outDir); if (ar != null) { logger.LogString($"Finished packing {ar.ArchiveAbsolutePath}.", Logtype.Success); } else { logger.LogString($"Packing failed.", Logtype.Error); } return; }
/// <summary> /// Runs Emergency 5 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_RunEmergency_Click(object sender, RoutedEventArgs e) { ModTools.writeJsonModFile(dataContext.InstalledMods, dataContext.AppDataModificationsJsonFile); EmergencyInstallation myEmergencyInstallation = new EmergencyInstallation(); try { System.Diagnostics.Process.Start(myEmergencyInstallation.getEmergencyInstallationPath() + @"\bin\em5_launcher.exe"); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
protected void SetupImage() { using var ddsstream = new MemoryStream(); try { if (ModTools.ConvertRedClassToDdsStream(_data, ddsstream, out _)) { _ = LoadImageFromStream(ddsstream); } } catch (Exception e) { Console.WriteLine(e.Message); throw; } }
public bool ExportOpusUsingHash(uint opusHash) { if (!_isModded) { for (uint i = 0; i < Info.OpusCount; i++) { if (Info.OpusHashes[i] == opusHash) { var containerHash = FNV1A64HashAlgorithm.HashString("base\\sound\\soundbanks\\sfx_container_" + Info.PackIndices[i] + ".opuspak"); var ms = new MemoryStream(); ModTools.ExtractSingleToStream(_soundBanks, containerHash, ms); Info.WriteOpusFromPak(ms, _rawFolder, i); return(true); } if (Info.OpusCount == i + 1) { return(false); } } } else { for (uint i = 0; i < Info.OpusCount; i++) { if (Info.OpusHashes[i] == opusHash) { var pakFile = Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks\\sfx_container_" + Info.PackIndices[i] + ".opuspak"); if (File.Exists(pakFile)) { var ms = new MemoryStream(File.ReadAllBytes(pakFile)); Info.WriteOpusFromPak(ms, _rawFolder, i); return(true); } else { return(false); } } if (Info.OpusCount == i + 1) { return(false); } } } return(false); }
/// <summary> /// Handels the clicks on the down arrow /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnDecreaseOrderingIndex_Click(object sender, RoutedEventArgs e) { // if nothing is selected // if (liModificationList.SelectedIndex == -1 | (liModificationList.SelectedIndex - 1 == -1)) { MessageBox.Show("Übersetzung", Properties.Resources.changeOrderingIndexDialogeTitle, MessageBoxButton.OK, MessageBoxImage.Error); return; } // store the number of the current selected item to send it into decreasing and reselecting // decrease the ordering index and sort our collection to display the result withthe decreaseOrderingIndex method // int currentlySelected = liModificationList.SelectedIndex; ModTools.decreaseOrderingIndex(currentlySelected, dataContext.InstalledMods); // also let it selcted liModificationList.SelectedItem = liModificationList.Items[currentlySelected - 1]; }
private RawMaterial ContainRawMaterial(CMaterialInstance cMaterialInstance, string Name, List <Archive> archives) { RawMaterial rawMaterial = new RawMaterial(); rawMaterial.Name = Name; rawMaterial.BaseMaterial = cMaterialInstance.BaseMaterial.DepotPath; List <CMaterialInstance> BaseMaterials = new List <CMaterialInstance>(); string path = cMaterialInstance.BaseMaterial.DepotPath; while (!Path.GetExtension(path).Contains("mt")) { ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); BaseMaterials.Add(mi.Chunks[0].Data as CMaterialInstance); path = (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath; break; } } } string type = Path.GetFileName(path); BaseMaterials.Reverse(); for (int i = 0; i < BaseMaterials.Count; i++) { MATERIAL.ContainRawMaterialEnum(ref rawMaterial, BaseMaterials[i], type); } MATERIAL.ContainRawMaterialEnum(ref rawMaterial, cMaterialInstance, type); return(rawMaterial); }
private static void RebuildTaskInner(string path, bool buffers, bool textures, bool import, bool keep, bool clean, bool unsaferaw ) { #region checks if (string.IsNullOrEmpty(path)) { logger.LogString("Please fill in an input path", Logtype.Error); return; } var inputDirInfo = new DirectoryInfo(path); if (!Directory.Exists(path) || !inputDirInfo.Exists) { logger.LogString("Input path does not exist", Logtype.Error); return; } var basedir = inputDirInfo; if (basedir?.Parent == null) { return; } #endregion ModTools.Recombine(basedir, buffers, textures, import, keep, clean, unsaferaw); return; }
private static void Cr2wTaskInner(string path, string outpath, bool chunks, string pattern = "", string regex = "") { #region checks if (string.IsNullOrEmpty(path)) { logger.LogString("Please fill in an input path.", Logtype.Error); return; } var inFileInfo = new FileInfo(path); var inDirInfo = new DirectoryInfo(path); var isDirectory = !inFileInfo.Exists && inDirInfo.Exists; var isFile = inFileInfo.Exists && !inDirInfo.Exists; if (!isDirectory && !isFile) { logger.LogString("Input file does not exist.", Logtype.Error); return; } #endregion Stopwatch watch = new(); watch.Restart(); // get all files var fileInfos = isDirectory ? inDirInfo.GetFiles("*", SearchOption.AllDirectories).ToList() : new List <FileInfo> { inFileInfo }; // check search pattern then regex IEnumerable <FileInfo> finalmatches = fileInfos; if (!string.IsNullOrEmpty(pattern)) { finalmatches = fileInfos.MatchesWildcard(item => item.FullName, pattern); } if (!string.IsNullOrEmpty(regex)) { var searchTerm = new System.Text.RegularExpressions.Regex($@"{regex}"); var queryMatchingFiles = from file in finalmatches let matches = searchTerm.Matches(file.FullName) where matches.Count > 0 select file; finalmatches = queryMatchingFiles; } var finalMatchesList = finalmatches.ToList(); logger.LogString($"Found {finalMatchesList.Count} files to dump.", Logtype.Important); Thread.Sleep(1000); int progress = 0; logger.LogProgress(0); Parallel.ForEach(finalMatchesList, fileInfo => { var outputDirInfo = string.IsNullOrEmpty(outpath) ? fileInfo.Directory : new DirectoryInfo(outpath); if (outputDirInfo == null || !outputDirInfo.Exists) { logger.LogString("Output directory is not valid.", Logtype.Error); return; } if (chunks) { var f = File.ReadAllBytes(fileInfo.FullName); using var fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read); var cr2w = ModTools.TryReadCr2WFile(fs); if (cr2w == null) { return; } //write File.WriteAllText(Path.Combine(outputDirInfo.FullName, $"{fileInfo.Name}.json"), JsonConvert.SerializeObject(cr2w, Formatting.Indented, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, PreserveReferencesHandling = PreserveReferencesHandling.None, TypeNameHandling = TypeNameHandling.None })); } Interlocked.Increment(ref progress); logger.LogProgress(progress / (float)finalMatchesList.Count); }); watch.Stop(); logger.LogString( $"Finished. Dumped {finalMatchesList.Count} files to json in {watch.ElapsedMilliseconds.ToString()}ms.", Logtype.Success); }
private void GetMateriaEntries(CR2WFile cr2w, Stream meshStream, ref List <string> primaryDependencies, ref List <string> materialEntryNames, ref List <CMaterialInstance> materialEntries, List <Archive> archives) { var cmesh = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First(); List <CMaterialInstance> ExternalMaterial = new List <CMaterialInstance>(); for (int i = 0; i < cmesh.ExternalMaterials.Count; i++) { string path = cmesh.ExternalMaterials[i].DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); ExternalMaterial.Add(mi.Chunks[0].Data as CMaterialInstance); for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } for (int i = 0; i < cmesh.PreloadExternalMaterials.Count; i++) { string path = cmesh.PreloadExternalMaterials[i].DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); ExternalMaterial.Add(mi.Chunks[0].Data as CMaterialInstance); for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } List <CMaterialInstance> LocalMaterial = new List <CMaterialInstance>(); bool isbuffered = true; if (cmesh.LocalMaterialBuffer.RawDataHeaders.Count == 0) { isbuffered = false; } if (isbuffered) { MemoryStream materialStream = GetMaterialStream(meshStream, cr2w); byte[] bytes = materialStream.ToArray(); for (int i = 0; i < cmesh.LocalMaterialBuffer.RawDataHeaders.Count; i++) { UInt32 offset = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Offset.Value; UInt32 size = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Size.Value; MemoryStream ms = new MemoryStream(bytes, (int)offset, (int)size); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); for (int e = 0; e < mi.Imports.Count; e++) { if (!primaryDependencies.Contains(mi.Imports[e].DepotPathStr)) { primaryDependencies.Add(mi.Imports[e].DepotPathStr); } } LocalMaterial.Add(mi.Chunks[0].Data as CMaterialInstance); } } else { for (int i = 0; i < cr2w.Chunks.Count; i++) { if (cr2w.Chunks[i].REDType == "CMaterialInstance") { LocalMaterial.Add(cr2w.Chunks[i].Data as CMaterialInstance); } } for (int i = 0; i < cr2w.Imports.Count; i++) { if (!primaryDependencies.Contains(cr2w.Imports[i].DepotPathStr)) { primaryDependencies.Add(cr2w.Imports[i].DepotPathStr); } } } int Count = cmesh.MaterialEntries.Count; for (int i = 0; i < Count; i++) { var Entry = cmesh.MaterialEntries[i]; materialEntryNames.Add(Entry.Name.Value); if (Entry.IsLocalInstance.Value) { materialEntries.Add(LocalMaterial[Entry.Index.Value]); } else { materialEntries.Add(ExternalMaterial[Entry.Index.Value]); } } foreach (var m in materialEntries) { string path = m.BaseMaterial.DepotPath; while (!Path.GetExtension(path).Contains("mt")) { ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); path = (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath; for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } ulong mt = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(mt)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, mt, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } }
public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, Archive ar) { if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any() || cr2w.Buffers.Count < 1) { return(false); } ulong hash = FNV1A64HashAlgorithm.HashString("base\\characters\\common\\skin\\old_mat_instances\\skin_ma_a__head.mi"); if (!ar.Files.ContainsKey(hash)) { return(false); } var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); _wolvenkitFileService.TryReadRED4File(ms); ms.Seek(0, SeekOrigin.Begin); var obj = JsonConvert.DeserializeObject <MatData>(_matData); var materialbuffer = new MemoryStream(); List <UInt32> offsets = new List <UInt32>(); List <UInt32> sizes = new List <UInt32>(); List <string> names = new List <string>(); if (obj.Materials.Count < 1) { return(false); } for (int i = 0; i < obj.Materials.Count; i++) { var mat = obj.Materials[i]; names.Add(mat.Name); var mi = _wolvenkitFileService.TryReadRED4File(ms); ms.Seek(0, SeekOrigin.Begin); MATERIAL.WriteMatToMeshEnum(ref mi, ref mat); (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath = mat.BaseMaterial; offsets.Add((UInt32)materialbuffer.Position); var m = new MemoryStream(); var b = new BinaryWriter(m); mi.Write(b); materialbuffer.Write(m.ToArray(), 0, (int)m.Length); sizes.Add((UInt32)m.Length); } var blob = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First(); // remove existing data while (blob.MaterialEntries.Count != 0) { blob.MaterialEntries.Remove(blob.MaterialEntries[blob.MaterialEntries.Count - 1]); } while (blob.LocalMaterialBuffer.RawDataHeaders.Count != 0) { blob.LocalMaterialBuffer.RawDataHeaders.Remove(blob.LocalMaterialBuffer.RawDataHeaders[blob.LocalMaterialBuffer.RawDataHeaders.Count - 1]); } while (blob.PreloadLocalMaterialInstances.Count != 0) { blob.PreloadLocalMaterialInstances.Remove(blob.PreloadLocalMaterialInstances[blob.PreloadLocalMaterialInstances.Count - 1]); } while (blob.PreloadExternalMaterials.Count != 0) { blob.PreloadExternalMaterials.Remove(blob.PreloadExternalMaterials[blob.PreloadExternalMaterials.Count - 1]); } while (blob.ExternalMaterials.Count != 0) { blob.ExternalMaterials.Remove(blob.ExternalMaterials[blob.ExternalMaterials.Count - 1]); } while (blob.LocalMaterialInstances.Count != 0) { blob.LocalMaterialInstances.Remove(blob.LocalMaterialInstances[blob.LocalMaterialInstances.Count - 1]); } // for (int i = 0; i < names.Count; i++) { var c = new CMeshMaterialEntry(cr2w, blob.MaterialEntries, Convert.ToString(i)) { IsSerialized = true, }; c.IsLocalInstance = new CBool(cr2w, c, "isLocalInstance") { Value = true, IsSerialized = true }; c.Name = new CName(cr2w, c, "name") { Value = names[i], IsSerialized = true }; c.Index = new CUInt16(cr2w, c, "index") { Value = (UInt16)i, IsSerialized = true }; blob.MaterialEntries.Add(c); var m = new meshLocalMaterialHeader(cr2w, blob.LocalMaterialBuffer.RawDataHeaders, Convert.ToString(i)) { IsSerialized = true }; m.Offset = new CUInt32(cr2w, m, "offset") { Value = offsets[i], IsSerialized = true }; m.Size = new CUInt32(cr2w, m, "size") { Value = sizes[i], IsSerialized = true }; blob.LocalMaterialBuffer.RawDataHeaders.Add(m); } var compressed = new MemoryStream(); using var buff = new BinaryWriter(compressed); var(zsize, crc) = buff.CompressAndWrite(materialbuffer.ToArray()); bool check = false; check = blob.LocalMaterialBuffer.RawData.IsSerialized; if (!check) { blob.LocalMaterialBuffer.RawData = new DataBuffer(cr2w, blob.LocalMaterialBuffer, "rawData") { IsSerialized = true }; blob.LocalMaterialBuffer.RawData.Buffer = new CUInt16(cr2w, blob.LocalMaterialBuffer.RawData, "Buffer") { Value = (UInt16)(cr2w.Buffers.Count + 1), IsSerialized = true }; uint idx = (uint)cr2w.Buffers.Count; cr2w.Buffers.Add(new CR2WBufferWrapper(new CR2WBuffer() { flags = 0, index = idx, offset = 0, diskSize = zsize, memSize = (UInt32)materialbuffer.Length, crc32 = crc })); cr2w.Buffers[(int)idx].ReadData(new BinaryReader(compressed)); cr2w.Buffers[(int)idx].Offset = cr2w.Buffers[(int)idx - 1].Offset + cr2w.Buffers[(int)idx - 1].DiskSize; } else { UInt16 p = (blob.LocalMaterialBuffer.RawData.Buffer.Value); cr2w.Buffers[p - 1].DiskSize = zsize; cr2w.Buffers[p - 1].Crc32 = crc; cr2w.Buffers[p - 1].MemSize = (UInt32)materialbuffer.Length; var off = cr2w.Buffers[p - 1].Offset; cr2w.Buffers[p - 1].Offset = 0; cr2w.Buffers[p - 1].ReadData(new BinaryReader(compressed)); cr2w.Buffers[p - 1].Offset = off; } return(true); }
private void ParseMaterials(CR2WFile cr2w, Stream meshStream, DirectoryInfo outDir, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds) { List <string> primaryDependencies = new List <string>(); List <string> materialEntryNames = new List <string>(); List <CMaterialInstance> materialEntries = new List <CMaterialInstance>(); GetMateriaEntries(cr2w, meshStream, ref primaryDependencies, ref materialEntryNames, ref materialEntries, archives); List <string> mlSetupNames = new List <string>(); List <Multilayer_Setup> mlSetups = new List <Multilayer_Setup>(); List <string> mlTemplateNames = new List <string>(); List <Multilayer_LayerTemplate> mlTemplates = new List <Multilayer_LayerTemplate>(); List <HairProfile> HairProfiles = new List <HairProfile>(); List <string> HairProfileNames = new List <string>(); List <string> TexturesList = new List <string>(); var exportArgs = new GlobalExportArgs().Register( new XbmExportArgs() { UncookExtension = eUncookExtension }, new MlmaskExportArgs() { UncookExtension = eUncookExtension } ); for (int i = 0; i < primaryDependencies.Count; i++) { if (Path.GetExtension(primaryDependencies[i]) == ".xbm") { if (!TexturesList.Contains(primaryDependencies[i])) { TexturesList.Add(primaryDependencies[i]); } ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { if (!File.Exists(Path.Combine(matRepo, primaryDependencies[i].Replace("xbm", exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(primaryDependencies[i]) == ".mlmask") { if (!TexturesList.Contains(primaryDependencies[i])) { TexturesList.Add(primaryDependencies[i]); } ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { if (!File.Exists(Path.Combine(matRepo, primaryDependencies[i].Replace(".mlmask", $"_0.{exportArgs.Get<XbmExportArgs>().UncookExtension.ToString()}")))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(primaryDependencies[i]) == ".hp") { if (!HairProfileNames.Contains(Path.GetFileName(primaryDependencies[i]))) { HairProfileNames.Add(Path.GetFileName(primaryDependencies[i])); ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var hp = _wolvenkitFileService.TryReadCr2WFile(ms); HairProfiles.Add(new HairProfile(hp.Chunks[0].Data as CHairProfile, Path.GetFileName(primaryDependencies[i]))); break; } } } } if (Path.GetExtension(primaryDependencies[i]) == ".mlsetup") { ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mls = _wolvenkitFileService.TryReadCr2WFile(ms); mlSetupNames.Add(Path.GetFileName(primaryDependencies[i])); mlSetups.Add(mls.Chunks[0].Data as Multilayer_Setup); for (int e = 0; e < mls.Imports.Count; e++) { if (Path.GetExtension(mls.Imports[e].DepotPathStr) == ".xbm") { if (!TexturesList.Contains(mls.Imports[e].DepotPathStr)) { TexturesList.Add(mls.Imports[e].DepotPathStr); } ulong hash1 = FNV1A64HashAlgorithm.HashString(mls.Imports[e].DepotPathStr); foreach (Archive arr in archives) { if (arr.Files.ContainsKey(hash1)) { if (!File.Exists(Path.Combine(matRepo, mls.Imports[e].DepotPathStr.Replace("xbm", exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(arr, hash1, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(mls.Imports[e].DepotPathStr) == ".mltemplate") { ulong hash2 = FNV1A64HashAlgorithm.HashString(mls.Imports[e].DepotPathStr); foreach (Archive arr in archives) { if (arr.Files.ContainsKey(hash2)) { var mss = new MemoryStream(); ModTools.ExtractSingleToStream(arr, hash2, mss); var mlt = _wolvenkitFileService.TryReadCr2WFile(mss); mlTemplateNames.Add(Path.GetFileName(mls.Imports[e].DepotPathStr)); mlTemplates.Add(mlt.Chunks[0].Data as Multilayer_LayerTemplate); for (int eye = 0; eye < mlt.Imports.Count; eye++) { if (!TexturesList.Contains(mlt.Imports[eye].DepotPathStr)) { TexturesList.Add(mlt.Imports[eye].DepotPathStr); } ulong hash3 = FNV1A64HashAlgorithm.HashString(mlt.Imports[eye].DepotPathStr); foreach (Archive arrr in archives) { if (arrr.Files.ContainsKey(hash3)) { if (!File.Exists(Path.Combine(matRepo, mlt.Imports[eye].DepotPathStr.Replace("xbm", exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(arrr, hash3, new DirectoryInfo(matRepo), exportArgs); } } break; } } } break; } } } } break; } } } } List <RawMaterial> RawMaterials = new List <RawMaterial>(); for (int i = 0; i < materialEntries.Count; i++) { RawMaterials.Add(ContainRawMaterial(materialEntries[i], materialEntryNames[i], archives)); } List <Setup> MaterialSetups = new List <Setup>(); for (int i = 0; i < mlSetups.Count; i++) { MaterialSetups.Add(new Setup(mlSetups[i], mlSetupNames[i])); } List <Template> MaterialTemplates = new List <Template>(); for (int i = 0; i < mlTemplates.Count; i++) { MaterialTemplates.Add(new Template(mlTemplates[i], mlTemplateNames[i])); } var obj = new { MaterialRepo = matRepo, Materials = RawMaterials, HairProfiles = HairProfiles, MaterialSetups = MaterialSetups, MaterialTemplates = MaterialTemplates }; var settings = new JsonSerializerSettings(); settings.NullValueHandling = NullValueHandling.Ignore; settings.Formatting = Formatting.Indented; string str = JsonConvert.SerializeObject(obj, settings); File.WriteAllLines(Path.Combine(outDir.FullName, "Textures.txt"), TexturesList); File.WriteAllText(Path.Combine(outDir.FullName, "Material.json"), str); }
public MATERIAL(Red4ParserService fileservice, ModTools modtools) { _wolvenkitFileService = fileservice; _modTools = modtools; }
public static int DumpTaskInner(string path, bool imports, bool missinghashes, bool texinfo, bool classinfo, bool dump, bool list) { #region checks if (string.IsNullOrEmpty(path)) { ConsoleFunctions.logger.LogString("Please fill in an input path.", Logtype.Error); return(0); } var isDirectory = false; var inputFileInfo = new FileInfo(path); var inputDirInfo = new DirectoryInfo(path); if (!inputFileInfo.Exists) { if (!inputDirInfo.Exists) { return(0); } else { isDirectory = true; } } #endregion checks var archives = new List <Archive>(); if (isDirectory) { archives.AddRange(inputDirInfo .GetFiles("*.archive", SearchOption.AllDirectories) .Select(_ => new Archive(_.FullName))); } else { archives.Add(new Archive(inputFileInfo.FullName)); } var mainController = ServiceLocator.Default.ResolveType <IHashService>(); var logger = ServiceLocator.Default.ResolveType <ILoggerService>(); var typedict = new ConcurrentDictionary <string, IEnumerable <string> >(); // Parallel foreach (var ar in archives) { if (classinfo) { // using var mmf = MemoryMappedFile.CreateFromFile(ar.Filepath, FileMode.Open, // ar.Filepath.GetHashMD5(), 0, // MemoryMappedFileAccess.Read); var fileinfo = ar.Files.Values; var query = fileinfo.GroupBy( ext => Path.GetExtension(ext.FileName), file => file, (ext, finfo) => new { Key = ext, File = fileinfo.Where(_ => Path.GetExtension(_.FileName) == ext) }).ToList(); var total = query.Count; logger.LogString($"Exporting {total} bundle entries "); Thread.Sleep(1000); int progress = 0; logger.LogProgress(0); // foreach extension Parallel.ForEach(query, result => { if (!string.IsNullOrEmpty(result.Key)) { Parallel.ForEach(result.File, fi => { using var ms = new MemoryStream(); ar.CopyFileToStream(ms, fi.NameHash64, false); var cr2w = ModTools.TryReadCr2WFile(ms); if (cr2w == null) { return; } foreach (var o in cr2w.Chunks.Select(chunk => (chunk as CR2WExportWrapper).GetDumpObject(ms)) .Where(o => o != null)) { Register(o); } }); } Interlocked.Increment(ref progress); logger.LogProgress(progress / (float)total); logger.LogString($"Dumped extension {result.Key}", Logtype.Normal); }); } if (imports || texinfo) { // using var mmf = MemoryMappedFile.CreateFromFile(ar.Filepath, FileMode.Open, // ar.Filepath.GetHashMD5(), 0, // MemoryMappedFileAccess.Read); var fileDictionary = new ConcurrentDictionary <ulong, Cr2wChunkInfo>(); var texDictionary = new ConcurrentDictionary <ulong, Cr2wTextureInfo>(); // get info var count = ar.FileCount; logger.LogString($"Exporting {count} bundle entries "); Thread.Sleep(1000); int progress = 0; logger.LogProgress(0); Parallel.For(0, count, i => { var(hash, fileEntry) = ar.Files.ToList()[i]; var filename = string.IsNullOrEmpty(fileEntry.FileName) ? hash.ToString() : fileEntry.FileName; if (imports) { using var ms = new MemoryStream(); ar.CopyFileToStream(ms, fileEntry.NameHash64, false); var cr2w = ModTools.TryReadCr2WFileHeaders(ms); if (cr2w == null) { return; } var obj = new Cr2wChunkInfo { Filename = filename, Imports = cr2w.Imports }; fileDictionary.AddOrUpdate(hash, obj, (arg1, o) => obj); } if (texinfo) { if (!string.IsNullOrEmpty(fileEntry.FileName) && fileEntry.FileName.Contains(".xbm")) { using var ms = new MemoryStream(); ar.CopyFileToStream(ms, fileEntry.NameHash64, false); var cr2w = ModTools.TryReadCr2WFile(ms); if (cr2w?.Chunks.FirstOrDefault()?.data is not CBitmapTexture xbm || !(cr2w.Chunks[1]?.data is rendRenderTextureBlobPC blob)) { return; } // create dds header var texinfoObj = new Cr2wTextureInfo() { Filename = filename, width = blob.Header.SizeInfo.Width.Value, height = blob.Header.SizeInfo.Height.Value, mips = blob.Header.TextureInfo.MipCount.Value, slicecount = blob.Header.TextureInfo.SliceCount.Value, alignment = blob.Header.TextureInfo.DataAlignment.Value, compression = xbm.Setup.Compression, Group = xbm.Setup.Group, rawFormat = xbm.Setup.RawFormat, }; texDictionary.AddOrUpdate(hash, texinfoObj, (arg1, o) => texinfoObj); } } Interlocked.Increment(ref progress); logger.LogProgress(progress / (float)count); });
private void UnbundleTaskInner(string path, string outpath, string hash, string pattern, string regex, bool DEBUG_decompress = false) { #region checks if (string.IsNullOrEmpty(path)) { _loggerService.Warning("Please fill in an input path."); return; } var inputFileInfo = new FileInfo(path); var inputDirInfo = new DirectoryInfo(path); if (!inputFileInfo.Exists && !inputDirInfo.Exists) { _loggerService.Warning("Input path does not exist."); return; } if (inputFileInfo.Exists && inputFileInfo.Extension != ".archive") { _loggerService.Warning("Input file is not an .archive."); return; } else if (inputDirInfo.Exists && inputDirInfo.GetFiles().All(_ => _.Extension != ".archive")) { _loggerService.Warning("No .archive file to process in the input directory."); return; } var isDirectory = !inputFileInfo.Exists; var basedir = inputFileInfo.Exists ? new FileInfo(path).Directory : inputDirInfo; #endregion checks List <FileInfo> archiveFileInfos; if (isDirectory) { _archiveManager.LoadFromFolder(basedir); // TODO: use the manager here? archiveFileInfos = _archiveManager.Archives.Items.Select(_ => new FileInfo(_.ArchiveAbsolutePath)).ToList(); } else { archiveFileInfos = new List <FileInfo> { inputFileInfo }; } foreach (var fileInfo in archiveFileInfos) { // get outdirectory DirectoryInfo outDir; if (string.IsNullOrEmpty(outpath)) { outDir = new DirectoryInfo(Path.Combine( basedir.FullName, fileInfo.Name.Replace(".archive", ""))); } else { outDir = new DirectoryInfo(outpath); if (!outDir.Exists) { outDir = new DirectoryInfo(outpath); } if (inputDirInfo.Exists) { outDir = new DirectoryInfo(Path.Combine( outDir.FullName, fileInfo.Name.Replace(".archive", ""))); } } // read archive var ar = Red4ParserServiceExtensions.ReadArchive(fileInfo.FullName, _hashService); var isHash = ulong.TryParse(hash, out var hashNumber); // run if (!isHash && File.Exists(hash)) { var hashlist = File.ReadAllLines(hash) .ToList().Select(_ => ulong.TryParse(_, out var res) ? res : 0); _loggerService.Info($"Extracing all files from the hashlist ({hashlist.Count()}hashes) ..."); foreach (var hashNum in hashlist) { var r = ModTools.ExtractSingle(ar, hashNum, outDir, DEBUG_decompress); if (r > 0) { _loggerService.Success($" {ar.ArchiveAbsolutePath}: Extracted one file: {hashNum}"); } else { _loggerService.Info($" {ar.ArchiveAbsolutePath}: No file found with hash {hashNum}"); } } _loggerService.Success($"Bulk extraction from hashlist file completed."); } else if (isHash && hashNumber != 0) { var r = ModTools.ExtractSingle(ar, hashNumber, outDir, DEBUG_decompress); if (r > 0) { _loggerService.Success($" {ar.ArchiveAbsolutePath}: Extracted one file: {hashNumber}"); } else { _loggerService.Info($" {ar.ArchiveAbsolutePath}: No file found with hash {hashNumber}"); } } else { _modTools.ExtractAll(ar, outDir, pattern, regex, DEBUG_decompress); } } return; }
private static void Test_Extension(string extension) { var parsers = _host.Services.GetRequiredService <Red4ParserService>(); var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory); Directory.CreateDirectory(resultDir); foreach (var file in Directory.GetFiles(resultDir)) { File.Delete(file); } var results = new ConcurrentBag <ArchiveTestResult>(); var files = s_groupedFiles[extension].ToList(); #if IS_PARALLEL Parallel.ForEach(files, file => #else foreach (var file in files) #endif { var hash = file.Key; var archive = file.Archive as Archive; ArgumentNullException.ThrowIfNull(archive); try { #region convert to json using var originalMemoryStream = new MemoryStream(); ModTools.ExtractSingleToStream(archive, hash, originalMemoryStream); if (!parsers.TryReadRed4File(originalMemoryStream, out var originalFile)) { #if IS_PARALLEL return; #else continue; #endif } var dto = new RedFileDto(originalFile); var json = RedJsonSerializer.Serialize(dto); if (string.IsNullOrEmpty(json)) { throw new SerializationException(); } #endregion #region convert back from json var newdto = RedJsonSerializer.Deserialize <RedFileDto>(json); if (newdto == null) { throw new SerializationException(); } var newFile = newdto.Data; #endregion #region compare // old file var header = originalFile.MetaData; var objectsend = (int)header.ObjectsEnd; var originalBytes = originalMemoryStream.ToByteArray().Take(objectsend); // write the new file using var newMemoryStream = new MemoryStream(); using var writer = new CR2WWriter(newMemoryStream); writer.WriteFile(newFile); // hack to compare buffers var newBytes = newMemoryStream.ToByteArray(); newMemoryStream.Seek(0, SeekOrigin.Begin); var dbg = parsers.ReadRed4File(newMemoryStream); //var newExportStartOffset = (int)dbg.Chunks.FirstOrDefault().GetOffset(); // var originalExportStartOffset = (int)originalFile.Chunks.FirstOrDefault().GetOffset(); // if (!originalBytes.Skip(160).SequenceEqual(newBytes.Skip(160))) // { // // check again skipping the tables // if (originalExportStartOffset == newExportStartOffset) // { // if (!originalBytes.Skip(originalExportStartOffset).SequenceEqual(newBytes.Skip(newExportStartOffset))) // { //#if WRITE // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.o.bin"), originalBytes.ToArray()); // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.bin"), newBytes.ToArray()); //#endif // throw new SerializationException("Exports not equal"); // } // else // { // } // } // else // { //#if WRITE // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.o.bin"), originalBytes.ToArray()); // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.bin"), newBytes.ToArray()); //#endif // throw new SerializationException("Header not equal"); // } // } // else // { // } #endregion results.Add(new ArchiveTestResult() { ArchiveName = archive.Name, Hash = hash.ToString(), Success = true }); } catch (Exception e) { Console.WriteLine($"{hash} - {e.Message} - {e.StackTrace}"); results.Add(new ArchiveTestResult() { ArchiveName = archive.Name, Hash = hash.ToString(), Success = false, ExceptionType = e.GetType(), Message = $"{e.Message}" }); } #if IS_PARALLEL });
public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.TryReadRED4File(targetStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(false); } RawArmature Rig = null; MemoryStream meshbuffer = MESH.GetMeshBufferStream(targetStream, cr2w); MeshesInfo meshinfo = MESH.GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = MESH.ContainRawMesh(meshbuffer, meshinfo, true); int subMeshC = expMeshes.Count; var buffers = cr2w.Buffers; var blob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First(); string baseMeshPath = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First().BaseMesh.DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(baseMeshPath); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var meshStream = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, meshStream); var meshCr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (meshCr2w == null || !meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { break; } MESH.MeshBones meshBones = new MESH.MeshBones(); meshBones.boneCount = meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count; if (meshBones.boneCount != 0) // for rigid meshes { meshBones.Names = RIG.GetboneNames(meshCr2w); meshBones.WorldPosn = MESH.GetMeshBonesPosn(meshCr2w); } Rig = MESH.GetNonParentedRig(meshBones); MemoryStream ms = MESH.GetMeshBufferStream(meshStream, meshCr2w); meshinfo = MESH.GetMeshesinfo(meshCr2w); expMeshes = MESH.ContainRawMesh(ms, meshinfo, true); subMeshC = expMeshes.Count; if (meshBones.boneCount == 0) // for rigid meshes { for (int i = 0; i < expMeshes.Count; i++) { expMeshes[i].weightcount = 0; } } MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones); break; } } MemoryStream diffsbuffer = new MemoryStream(); MemoryStream mappingbuffer = new MemoryStream(); MemoryStream texbuffer = new MemoryStream(); if (blob.DiffsBuffer.IsSerialized) { targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin); targetStream.DecompressAndCopySegment(diffsbuffer, buffers[blob.DiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.DiffsBuffer.Buffer.Value - 1].MemSize); } if (blob.MappingBuffer.IsSerialized) { targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin); targetStream.DecompressAndCopySegment(mappingbuffer, buffers[blob.MappingBuffer.Buffer.Value - 1].DiskSize, buffers[blob.MappingBuffer.Buffer.Value - 1].MemSize); } if (blob.TextureDiffsBuffer.IsSerialized) { targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin); targetStream.DecompressAndCopySegment(texbuffer, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].MemSize); } TargetsInfo targetsInfo = GetTargetInfos(cr2w, subMeshC); List <RawTargetContainer[]> expTargets = new List <RawTargetContainer[]>(); for (int i = 0; i < targetsInfo.NumTargets; i++) { UInt32[] temp_NumVertexDiffsInEachChunk = new UInt32[subMeshC]; UInt32[] temp_NumVertexDiffsMappingInEachChunk = new UInt32[subMeshC]; for (int e = 0; e < subMeshC; e++) { temp_NumVertexDiffsInEachChunk[e] = targetsInfo.NumVertexDiffsInEachChunk[i, e]; temp_NumVertexDiffsMappingInEachChunk[e] = targetsInfo.NumVertexDiffsMappingInEachChunk[i, e]; } expTargets.Add(ContainRawTargets(diffsbuffer, mappingbuffer, temp_NumVertexDiffsInEachChunk, temp_NumVertexDiffsMappingInEachChunk, targetsInfo.TargetStartsInVertexDiffs[i], targetsInfo.TargetStartsInVertexDiffsMapping[i], targetsInfo.TargetPositionDiffOffset[i], targetsInfo.TargetPositionDiffScale[i], subMeshC)); } string[] names = new string[targetsInfo.NumTargets]; for (int i = 0; i < targetsInfo.NumTargets; i++) { names[i] = targetsInfo.Names[i] + "_" + targetsInfo.RegionNames[i]; } List <MemoryStream> textureStreams = ContainTextureStreams(cr2w, texbuffer); ModelRoot model = RawTargetsToGLTF(expMeshes, expTargets, names, Rig); if (WolvenTesting.IsTesting) { return(true); } model.Extras = SharpGLTF.IO.JsonContent.Serialize(new { BaseMesh = targetsInfo.BaseMesh }); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } var dir = new DirectoryInfo(outfile.FullName.Replace(Path.GetExtension(outfile.FullName), string.Empty) + "_Textures"); if (textureStreams.Count > 0) { Directory.CreateDirectory(dir.FullName); } for (int i = 0; i < textureStreams.Count; i++) { File.WriteAllBytes(dir.FullName + "\\" + Path.GetFileNameWithoutExtension(outfile.FullName) + i + ".dds", textureStreams[i].ToArray()); } targetStream.Dispose(); targetStream.Close(); return(true); }
public bool ExportAnim(Stream animStream, List <Archive> archives, FileInfo outfile, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.TryReadRED4File(animStream); if (!cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().Any()) { return(false); } var blob = cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().First(); List <MemoryStream> animDataBuffers = new List <MemoryStream>(); foreach (var chk in blob.AnimationDataChunks) { UInt16 bufferIdx = chk.Buffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); var ms = new MemoryStream(); animStream.DecompressAndCopySegment(ms, b.DiskSize, b.MemSize); animDataBuffers.Add(ms); } RawArmature Rig = null; { ulong hash = FNV1A64HashAlgorithm.HashString(blob.Rig.DepotPath); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); Rig = new RIG(_wolvenkitFileService).ProcessRig(ms); break; } } } if (Rig.BoneCount < 1) { return(false); } var model = ModelRoot.CreateModel(); var skin = model.CreateSkin(); skin.BindJoints(RIG.ExportNodes(ref model, Rig).Values.ToArray()); for (int i = 0; i < blob.Animations.Count; i++) { var setEntry = (blob.Animations[i].GetReference().Data as animAnimSetEntry); var animAnimDes = (setEntry.Animation.GetReference().Data as animAnimation); if (animAnimDes.AnimationType.Value != Enums.animAnimationType.Normal) { continue; } switch (animAnimDes.AnimBuffer.GetReference().REDType) { case "animAnimationBufferSimd": { var animBuff = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferSimd); var bufferIdx = animBuff.DefferedBuffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); var defferedBuffer = new MemoryStream(); animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize); SIMD.AddAnimationSIMD(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer); } break; case "animAnimationBufferCompressed": { var animBuff = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferCompressed); var dataAddr = animBuff.DataAddress; Byte[] bytes = new Byte[dataAddr.ZeInBytes.Value]; animDataBuffers[(int)dataAddr.UnkIndex.Value].Seek(dataAddr.FsetInBytes.Value, SeekOrigin.Begin); animDataBuffers[(int)dataAddr.UnkIndex.Value].Read(bytes, 0, (int)dataAddr.ZeInBytes.Value); var defferedBuffer = new MemoryStream(bytes); SPLINE.AddAnimationSpline(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer); } break; default: break; } } if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } return(true); }
public bool ImportWavs(params string[] wavFiles) { if (wavFiles.Length < 1) { return(false); } var foundids = new List <uint>(); foreach (var wav in wavFiles) { try { var idddd = Convert.ToUInt32(Path.GetFileNameWithoutExtension(wav)); foundids.Add(idddd); } catch { } } var validids = new List <uint>(); for (var i = 0; i < foundids.Count; i++) { for (var e = 0; e < Info.OpusCount; e++) { if (Info.OpusHashes[e] == foundids[i]) { validids.Add(foundids[i]); break; } } } if (validids.Count < 1) { return(false); } var modStreams = new Stream[Info.PackIndices[Info.OpusCount - 1] + 1]; for (var i = 0; i < validids.Count; i++) { var name = Path.Combine(_rawFolder.FullName, Convert.ToString(validids[i]) + ".opus"); var proc = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "opus-tools\\opusenc.exe")) { WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory, Arguments = $" \"{name.Replace("opus", "wav")}\" \"{name}\" --serial 42 --quiet --padding 0 --vbr --comp 10 --framesize 20 ", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true, }; using (var p = Process.Start(proc)) { p.WaitForExit(); } var procnew = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "opus-tools\\opusdec.exe")) { WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory, Arguments = $" \"{name}\" \"{name.Replace("opus", "wav")}\"", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true, }; using (var p = Process.Start(procnew)) { p.WaitForExit(); } var procn = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "opus-tools\\opusenc.exe")) { WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory, Arguments = $" \"{name.Replace("opus", "wav")}\" \"{name}\" --serial 42 --quiet --padding 0 --vbr --comp 10 --framesize 20 ", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true, }; using (var p = Process.Start(procn)) { p.WaitForExit(); } if (File.Exists(name)) { for (var e = 0; e < Info.OpusCount; e++) { if (validids[i] == Info.OpusHashes[e]) { int pakIdx = Info.PackIndices[e]; if (modStreams[pakIdx] == null) { var pakName = "base\\sound\\soundbanks\\sfx_container_" + pakIdx + ".opuspak"; if (_isModded && File.Exists(Path.Combine(_modFolder.FullName, pakName))) { modStreams[pakIdx] = new MemoryStream(File.ReadAllBytes(Path.Combine(_modFolder.FullName, pakName))); } else { var containerHash = FNV1A64HashAlgorithm.HashString(pakName); modStreams[pakIdx] = new MemoryStream(); ModTools.ExtractSingleToStream(_soundBanks, containerHash, modStreams[pakIdx]); } } Info.WriteOpusToPak(new MemoryStream(File.ReadAllBytes(name)), ref modStreams[pakIdx], validids[i], new MemoryStream(File.ReadAllBytes(name.Replace("opus", "wav")))); } } } } var writeinfo = false; for (var i = 0; i < modStreams.Length; i++) { if (modStreams[i] != null) { var pakName = "base\\sound\\soundbanks\\sfx_container_" + i + ".opuspak"; var temp = modStreams[i]; temp.Position = 0; var bytes = new byte[temp.Length]; temp.Read(bytes, 0, Convert.ToInt32(temp.Length)); File.WriteAllBytes(Path.Combine(_modFolder.FullName, pakName), bytes); writeinfo = true; } } if (writeinfo) { Info.WriteOpusInfo(new DirectoryInfo(Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks"))); return(true); } return(false); }
// Close the whole application if mainwindow is closed // private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { ModTools.writeJsonModFile(dataContext.InstalledMods, dataContext.AppDataModificationsJsonFile); App.Current.Shutdown(); }