static Stream ProcessCCMesh(IPackfileEntry oldFile, string oldName, string newName) { MemoryStream outStream = new MemoryStream(); using (Stream inStream = oldFile.GetStream()) { VFile.VFile vFile = new VFile.VFile(inStream); StaticMesh mesh = new StaticMesh(inStream); for (int i = 0; i < vFile.References.Count; i++) { string reference = vFile.References[i]; if (textureNameMap.ContainsKey(reference)) { vFile.References[i] = textureNameMap[reference]; } } string[] textureNames = new string[mesh.TextureNames.Count]; mesh.TextureNames.Keys.CopyTo(textureNames, 0); foreach (string textureName in textureNames) { if (textureNameMap.ContainsKey(textureName)) { mesh.RenameTexture(textureName, textureNameMap[textureName]); } } vFile.Save(outStream); mesh.Save(outStream); } return(outStream); }
public void RemoveFile(IPackfileEntry entry) { Files.Remove(entry); if (m_Streams != null && m_Streams.ContainsKey(entry.Name)) { m_Streams.Remove(entry.Name); } }
public void Update(Container container) { Dictionary <string, int> fileLookup = new Dictionary <string, int>(); for (int i = 0; i < m_Files.Count; i++) { fileLookup.Add(m_Files[i].Name, i); } container.PackfileBaseOffset = (uint)CalculateDataStartOffset(); container.TotalCompressedPackfileReadSize = (int)FileData.CompressedDataSize; foreach (Primitive primitive in container.Primitives) { if (!fileLookup.ContainsKey(primitive.Name)) { continue; } IPackfileEntry iEntry = m_Files[fileLookup[primitive.Name]]; PackfileEntry entry = (PackfileEntry)iEntry; primitive.Data.CPUSize = entry.Data.Size; string gpuFile = ""; string extension = Path.GetExtension(primitive.Name); string gpuExtension = ""; switch (extension) { default: { if (extension.StartsWith(".c")) { gpuExtension = ".g" + extension.Remove(0, 2); } break; } } gpuFile = Path.ChangeExtension(primitive.Name, gpuExtension); if (fileLookup.ContainsKey(gpuFile)) { IPackfileEntry iGpuEntry = m_Files[fileLookup[gpuFile]]; PackfileEntry gpuEntry = (PackfileEntry)iGpuEntry; primitive.Data.GPUSize = (uint)gpuEntry.Size; } } for (int i = 0; i < container.PrimitiveSizes.Count; i++) { var sizes = container.PrimitiveSizes[i]; var primitiveData = container.Primitives[i]; sizes.CPUSize = primitiveData.Data.CPUSize; sizes.GPUSize = primitiveData.Data.GPUSize; container.PrimitiveSizes[i] = sizes; } }
static Stream ProcessClothSim(IPackfileEntry oldFile, string newName) { MemoryStream outStream = new MemoryStream(); using (Stream inStream = oldFile.GetStream()) { ClothSimulationFile file = new ClothSimulationFile(inStream); file.Header.Name = newName; file.Save(outStream); } return(outStream); }
static Stream ProcessPeg(IPackfileEntry pegEntry, string newName) { textureNameMap.Clear(); using (Stream pegStream = pegEntry.GetStream()) { PegFile peg = new PegFile(pegStream); string sharedPrefix = FilterPegEntryFilename(peg.Entries[0].Filename); foreach (PegEntry entry in peg.Entries) { while (!FilterPegEntryFilename(entry.Filename).StartsWith(sharedPrefix)) { sharedPrefix = sharedPrefix.Substring(0, sharedPrefix.Length - 1); } } foreach (PegEntry entry in peg.Entries) { string newFilename = null; if (sharedPrefix == "") { newFilename = newName + "_" + entry.Filename; } else { newFilename = entry.Filename.Replace(sharedPrefix, newName + "_").ToLowerInvariant(); if (newFilename.StartsWith("cf_cf_") || newFilename.StartsWith("cf_cm_") || newFilename.StartsWith("cm_cf_") || newFilename.StartsWith("cm_cm_")) { newFilename = newFilename.Remove(3, 3); } } if (!textureNameMap.ContainsKey(entry.Filename)) { textureNameMap.Add(entry.Filename, newFilename); } entry.Filename = newFilename; } MemoryStream outStream = new MemoryStream(); peg.Save(outStream); return(outStream); } }
public void Save(Stream stream) { long dataStart = CalculateDataStartOffset(); stream.Seek(dataStart, SeekOrigin.Begin); long fileStart = 0; long compressedSize = 0; long uncompressedSize = 0; // Output file data ZlibStream dataStream = null; if (IsCompressed && IsCondensed) { dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true); dataStream.FlushMode = FlushType.Sync; } long compressedStart = 0; for (int i = 0; i < Files.Count; i++) { IPackfileEntry entry = Files[i]; Stream fs = m_Streams[entry.Name]; bool isLast = (i == (Files.Count - 1)); PackfileEntry pfE = (PackfileEntry)entry; var data = pfE.Data; data.Start = (uint)fileStart; data.Size = (uint)fs.Length; data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1; if (this.IsCompressed) { data.Flags = PackfileEntryFlags.Compressed; } if (IsCompressed && IsCondensed) { fs.CopyTo(dataStream); dataStream.Flush(); long afterData = dataStream.TotalOut; data.CompressedSize = (uint)(afterData - compressedStart); compressedStart = afterData; if (IsStr2) { fileStart += data.Size.Align(16); uncompressedSize += data.Size.Align(16); compressedSize += data.CompressedSize; } else { fileStart += data.Size; //.Align(16); if (!isLast) { uncompressedSize += data.Size; //.Align(16); //uint toSkip = data.Size.Align(16) - data.Size; // for (int j = 0; j < toSkip; j++) //dataStream.WriteByte(0); } else { uncompressedSize += data.Size; } compressedSize += data.CompressedSize; } } else if (IsCondensed) { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size.Align(16); if (isLast) { uncompressedSize += data.Size; } else { uint toSkip = data.Size.Align(16) - data.Size; uncompressedSize += data.Size.Align(16); stream.Seek(toSkip, SeekOrigin.Current); } } else if (IsCompressed) { long beforeData = stream.Position; using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true)) { dataStream.FlushMode = FlushType.Sync; fs.CopyTo(dataStream); dataStream.Flush(); } long afterData = stream.Position; data.CompressedSize = (uint)(afterData - beforeData); fileStart += data.CompressedSize; uncompressedSize += data.Size; compressedSize += data.CompressedSize; } else { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size; uncompressedSize += data.Size; } fs.Close(); pfE.Data = data; } if (IsCompressed && IsCondensed) { dataStream.Close(); } // Output file names stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); long startOffset = CalculateEntryNamesOffset(); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.Align(2); pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset); stream.WriteAsciiNullTerminatedString(entry.Name); stream.Seek(1, SeekOrigin.Current); stream.Align(2); } long nameSize = stream.Position - CalculateEntryNamesOffset(); // Output file info stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.WriteStruct(pfE.Data); } long dirSize = stream.Position - GetEntryDataOffset(); // Output header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x0A; FileData.HeaderChecksum = 0; FileData.FileSize = (uint)stream.Length; FileData.NumFiles = (uint)Files.Count; FileData.DirSize = (uint)dirSize; FileData.FilenameSize = (uint)nameSize; FileData.DataSize = (uint)uncompressedSize; if (IsCompressed) { FileData.CompressedDataSize = (uint)compressedSize; } else { FileData.CompressedDataSize = 0xFFFFFFFF; } stream.WriteStruct(FileData); uint checksum = 0; byte[] checksumBuffer = new byte[0x1C]; stream.Seek(0x0C, SeekOrigin.Begin); stream.Read(checksumBuffer, 0, checksumBuffer.Length); checksum = Hashes.CrcVolition(checksumBuffer); stream.Seek(0x08, SeekOrigin.Begin); stream.WriteUInt32(checksum); stream.Flush(); }