static bool ClonePackfile(IGameInstance sriv, string packfileName, string clothSimFilename, string outputFolder, IAssetAssemblerFile newAsm, string oldName, string newName, string newStr2Filename) { using (Stream oldStream = sriv.OpenPackfileFile(packfileName)) { if (oldStream == null) { return(false); } IContainer oldContainer = FindContainer(sriv, packfileName); if (oldContainer == null) { return(false); } oldContainer.Name = Path.GetFileNameWithoutExtension(newStr2Filename); using (IPackfile oldPackfile = Packfile.FromStream(oldStream, true)) { using (IPackfile newPackfile = Packfile.FromVersion(0x0A, true)) { newPackfile.IsCompressed = true; newPackfile.IsCondensed = true; Stream pegStream = null; var pegEntry = FindPackfileEntry(oldPackfile, ".cpeg_pc"); if (pegEntry != null) { pegStream = ProcessPeg(pegEntry, newName); } foreach (var file in oldPackfile.Files) { string extension = Path.GetExtension(file.Name); IPrimitive primitive = FindPrimitive(oldContainer, file.Name); switch (extension) { case ".ccmesh_pc": { Stream newCcmeshStream = ProcessCCMesh(file, oldName, newName); string newMeshName = newName + extension; newPackfile.AddFile(newCcmeshStream, newMeshName); primitive.Name = newMeshName; break; } case ".cpeg_pc": { string newPegName = newName + extension; newPackfile.AddFile(pegStream, newPegName); primitive.Name = newPegName; break; } case ".cmorph_pc": { string morphSuffix = Path.GetFileNameWithoutExtension(file.Name).Split('_').Last(); string newFilename = newName + "_" + morphSuffix + extension; Stream fStream = file.GetStream(); // copy the morph to the output folder (fixes some odd issues with the morph not applying when loaded from save) using (Stream s = File.Create(Path.Combine(outputFolder, newFilename))) { fStream.CopyTo(s); } fStream.Seek(0, SeekOrigin.Begin); newPackfile.AddFile(fStream, newFilename); primitive.Name = newFilename; break; } case ".sim_pc": { string newFilename = newName + extension; Stream newStream = ProcessClothSim(file, newName); newPackfile.AddFile(newStream, newFilename); primitive.Name = newFilename; break; } case ".gcmesh_pc": case ".gpeg_pc": case ".rig_pc": { string newFilename = newName + extension; newPackfile.AddFile(file.GetStream(), newFilename); if (primitive != null) { primitive.Name = newFilename; } break; } default: throw new Exception(String.Format("Unrecognised extension: {0}", extension)); } } newAsm.Containers.Add(oldContainer); using (Stream s = File.Create(newStr2Filename)) { newPackfile.Save(s); } newPackfile.Update(oldContainer); } } } return(true); }
static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage:"); Console.WriteLine("EditPackfile <source> <destination> <new file 1> <new file 2>..."); return; } string sourcePath = args[0]; string destinationPath = args[1]; List <string> newFiles = new List <string>(); for (int i = 2; i < args.Length; i++) { newFiles.Add(args[i]); } string sourceExtension = Path.GetExtension(sourcePath); bool sourceIsStr2 = sourceExtension.ToLowerInvariant() == ".str2_pc"; Dictionary <string, NewFileEntry> filenameToPathMap = new Dictionary <string, NewFileEntry>(StringComparer.OrdinalIgnoreCase); foreach (string newFile in newFiles) { filenameToPathMap.Add(Path.GetFileName(newFile), new NewFileEntry(newFile)); } using (Stream sourceStream = File.OpenRead(sourcePath)) { using (IPackfile source = Packfile.FromStream(sourceStream, sourceIsStr2)) { using (IPackfile destination = Packfile.FromVersion(source.Version, sourceIsStr2)) { destination.IsCompressed = source.IsCompressed; destination.IsCondensed = source.IsCondensed; foreach (IPackfileEntry entry in source.Files) { string filename = entry.Name; if (filenameToPathMap.ContainsKey(filename)) { NewFileEntry newFilePath = filenameToPathMap[filename]; destination.AddFile(File.OpenRead(newFilePath.Path), entry.Name); newFilePath.Inserted = true; Console.WriteLine("Replaced {0}.", filename); } else { destination.AddFile(entry.GetStream(), entry.Name); } } foreach (var pair in filenameToPathMap) { NewFileEntry nfe = pair.Value; if (!nfe.Inserted) { string filename = Path.GetFileName(nfe.Path); destination.AddFile(File.OpenRead(nfe.Path), filename); Console.WriteLine("Inserted {0}.", filename); } } using (Stream destinationStream = File.Create(destinationPath)) { destination.Save(destinationStream); } } } } #if DEBUG Console.ReadLine(); #endif }