public void Save(FpmfArchive archive, string directoryPath) { DirectoryInfo directory = new DirectoryInfo(directoryPath); if (!directory.Exists) { throw new FileNotFoundException($"Directory: {directoryPath} not found."); } string relativeArchiveDir = archive.DatPath .Replace("/%08x.dat", "") .Replace("./", "") .Replace('/', Path.DirectorySeparatorChar); string rootPath = Path.Combine(directory.FullName, relativeArchiveDir); List <FpmfArchiveFile> files = archive.GetFiles(); foreach (FpmfArchiveFile file in files) { string relativeFilePath = file.FilePath .Replace(".\\", "") .Replace('\\', Path.DirectorySeparatorChar); string filePath = Path.Combine(rootPath, relativeFilePath); FileInfo fileInfo = new FileInfo(filePath); if (!Directory.Exists(fileInfo.DirectoryName)) { Directory.CreateDirectory(fileInfo.DirectoryName); } File.WriteAllBytes(filePath, file.Data); } }
public void Header(string hedFilePath, string outPath) { if (outPath.LastIndexOf("\\") != outPath.Length - 1) { outPath += "\\"; } string type = hedFilePath.Substring(hedFilePath.LastIndexOf("\\") + 1, hedFilePath.LastIndexOf(".") - hedFilePath.LastIndexOf("\\") - 1).Replace("\\data", ""); FileInfo hedFile = new FileInfo(hedFilePath); if (!hedFile.Exists) { throw new FileNotFoundException($"File: {hedFilePath} not found."); } IBuffer hedBuffer = new StreamBuffer(hedFile.FullName); if (hedBuffer.Size < 12) { throw new Exception("File to small"); } hedBuffer.SetPositionStart(); byte[] magicBytes = hedBuffer.ReadBytes(4); for (int i = 0; i < 4; i++) { if (magicBytes[i] != _MagicBytes[i]) { throw new Exception("Invalid File"); } } FpmfArchive archive = new FpmfArchive(); archive.size = hedBuffer.ReadUInt32(); uint unknown0 = hedBuffer.ReadUInt32(); hedBuffer = DecryptHed(hedBuffer); BinaryWriter tmpwriter = new BinaryWriter(File.Open(outPath + type + "_header.bin", FileMode.Create)); tmpwriter.Write(magicBytes); tmpwriter.Write(archive.size); tmpwriter.Write(unknown0); tmpwriter.Write(hedBuffer.GetAllBytes()); tmpwriter.Flush(); tmpwriter.Close(); }
public FpmfArchive Open(string hedFilePath) { FileInfo hedFile = new FileInfo(hedFilePath); if (!hedFile.Exists) { throw new FileNotFoundException($"File: {hedFilePath} not found."); } IBuffer hedBuffer = new StreamBuffer(hedFile.FullName); if (hedBuffer.Size < 12) { throw new Exception("File to small"); } hedBuffer.SetPositionStart(); byte[] magicBytes = hedBuffer.ReadBytes(4); for (int i = 0; i < 4; i++) { if (magicBytes[i] != MagicBytes[i]) { throw new Exception("Invalid File"); } } FpmfArchive archive = new FpmfArchive(); archive.Size = hedBuffer.ReadUInt32(); uint unknown0 = hedBuffer.ReadUInt32(); hedBuffer = DecryptHed(hedBuffer); hedBuffer.SetPositionStart(); uint unknown1 = hedBuffer.ReadUInt32(); uint unknown2 = hedBuffer.ReadUInt32(); byte unknown3 = hedBuffer.ReadByte(); byte unknown4 = hedBuffer.ReadByte(); uint unknown5 = hedBuffer.ReadUInt32(); uint unknown6 = hedBuffer.ReadUInt32(); int strLen = hedBuffer.ReadByte(); archive.DatPath = hedBuffer.ReadString(strLen); uint unknown7 = hedBuffer.ReadUInt32(); uint unknown8 = hedBuffer.ReadUInt32(); uint unknown9 = hedBuffer.ReadUInt32(); uint unknown10 = hedBuffer.ReadUInt32(); uint keyLen = hedBuffer.ReadUInt32(); archive.Key = hedBuffer.ReadBytes((int)keyLen); uint unknown11 = hedBuffer.ReadUInt32(); uint unknown12 = hedBuffer.ReadUInt32(); uint numFiles = hedBuffer.ReadUInt32(); string relativeArchiveDir = archive.DatPath .Replace("/%08x.dat", "") .Replace("./", "") .Replace('/', Path.DirectorySeparatorChar); string hedPath = hedFile.FullName.Replace(".hed", ""); string rootPath = hedPath.Replace(relativeArchiveDir, ""); DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); if (!rootDirectory.Exists) { throw new FileNotFoundException( $"Could not determinate root path. (Rel:{relativeArchiveDir} Hed:{hedPath} Root:{rootPath}"); } _logger.Info($"Using Root:{rootPath}"); Dictionary <uint, IBuffer> datBufferPool = new Dictionary <uint, IBuffer>(); for (int i = 0; i < numFiles; i++) { FpmfArchiveFile archiveFile = new FpmfArchiveFile(); strLen = hedBuffer.ReadByte(); archiveFile.DirectoryPath = hedBuffer.ReadString(strLen); strLen = hedBuffer.ReadByte(); archiveFile.FilePath = hedBuffer.ReadString(strLen); archiveFile.DatNumber = hedBuffer.ReadUInt32(); archiveFile.Offset = hedBuffer.ReadUInt32(); archiveFile.Size = hedBuffer.ReadUInt32(); uint unknown13 = hedBuffer.ReadUInt32(); uint unknown14 = hedBuffer.ReadUInt32(); _logger.Info($"Processing: {archiveFile.FilePath}"); IBuffer datBuffer; if (datBufferPool.ContainsKey(archiveFile.DatNumber)) { datBuffer = datBufferPool[archiveFile.DatNumber]; } else { string datFileName = archive.DatPath .Replace("%08x", $"{archiveFile.DatNumber:X8}") .Replace("./", "") .Replace('/', Path.DirectorySeparatorChar); string datFilePath = Path.Combine(rootDirectory.FullName, datFileName); FileInfo datFile = new FileInfo(datFilePath); if (!datFile.Exists) { throw new FileNotFoundException($"File: {datFilePath} not found."); } datBuffer = new StreamBuffer(datFile.FullName); datBufferPool.Add(archiveFile.DatNumber, datBuffer); } IBuffer decrypted = DecryptDat(datBuffer, archiveFile.Offset, archiveFile.Size, archive.Key); archiveFile.Data = decrypted.GetAllBytes(); archive.AddFile(archiveFile); } return(archive); }
private void SavePack(FpmfArchive archive, string inPath, string outPath, string archiveName) { Directory.CreateDirectory(outPath); IBuffer fileBuff = new StreamBuffer(); IBuffer headerBuff = new StreamBuffer(); List <FpmfArchiveFile> archiveFiles = archive.GetFiles(); foreach (FpmfArchiveFile archiveFile in archiveFiles) { fileBuff.WriteByte((byte)archiveFile.directoryPathSize); fileBuff.WriteCString(archiveFile.directoryPath); fileBuff.Position = fileBuff.Position - 1; fileBuff.WriteByte((byte)archiveFile.filePathSize); fileBuff.WriteCString(archiveFile.filePath); fileBuff.Position = fileBuff.Position - 1; fileBuff.WriteUInt32(archiveFile.datNumber); fileBuff.WriteUInt32(archiveFile.offset); fileBuff.WriteUInt32(archiveFile.size); fileBuff.WriteUInt32(archiveFile.unknown0); fileBuff.WriteUInt32(archiveFile.unknown1); } headerBuff.WriteBytes(_MagicBytes); headerBuff.WriteInt32(0); headerBuff.WriteUInt32(archive.unknown0); headerBuff.WriteUInt32(archive.unknown1); headerBuff.WriteUInt32(archive.unknown2); headerBuff.WriteByte(archive.unknown3); headerBuff.WriteByte(archive.unknown4); headerBuff.WriteUInt32(archive.unknown5); headerBuff.WriteInt32(archive.datPath.Length + 9); headerBuff.WriteByte((byte)archive.datPath.Length); headerBuff.WriteCString(archive.datPath); headerBuff.Position = headerBuff.Position - 1; uint type = 0; switch (archiveName) { case "script": case "settings": case "item": case "interface": type = 1; break; case "help_end": type = 2; break; } headerBuff.WriteUInt32(type); headerBuff.WriteUInt32(archive.unknown8); headerBuff.WriteUInt32(archive.unknown9); headerBuff.WriteUInt32(archive.unknown10); headerBuff.WriteInt32(archive.key.Length); headerBuff.WriteBytes(archive.key); headerBuff.WriteUInt32(archive.unknown11); headerBuff.WriteInt32(fileBuff.Size + 4); headerBuff.WriteUInt32(archive.numFiles); headerBuff.WriteBytes(fileBuff.GetAllBytes()); headerBuff = EncryptHed(headerBuff); string hedPath = outPath.Substring(0, outPath.LastIndexOf("\\")) + ".hed"; BinaryWriter headerWriter = new BinaryWriter(File.Open(hedPath, FileMode.Create)); headerBuff.Position = 4; headerBuff.WriteInt32(headerBuff.Size - 12); headerWriter.Write(headerBuff.GetAllBytes(), 0, headerBuff.Size); headerWriter.Flush(); headerWriter.Close(); BinaryWriter datWriter = new BinaryWriter(File.Open(outPath + "\\" + "00000000.dat", FileMode.Create)); IBuffer outBuff = new StreamBuffer(); foreach (FpmfArchiveFile archiveFile in archiveFiles) { string inputFile = inPath + "\\" + archiveName + archiveFile.filePath.Substring(1); IBuffer datFileReader = new StreamBuffer(inputFile); datFileReader = EncryptDat(datFileReader, archive.key); outBuff.WriteBytes(datFileReader.GetAllBytes()); } datWriter.Write(outBuff.GetAllBytes(), 0, outBuff.Size); datWriter.Flush(); datWriter.Close(); }
public void Pack(string inPath, string outPath, string archiveName, string archivePath = "") { uint fileTime = 0x506fa78e; string dirPath = archivePath; if (archivePath.Length > 0) { if (!dirPath.StartsWith("\\")) { dirPath = "\\" + dirPath; archivePath = "\\" + archivePath; } if (!dirPath.EndsWith("\\")) { dirPath = dirPath + "\\"; archivePath = archivePath + "\\"; } dirPath = ".\\" + archiveName + dirPath + "%08x.dat"; } else { dirPath = ".\\" + archiveName + "\\" + "%08x.dat"; } dirPath = dirPath.Replace("\\", "/"); FpmfArchive archive = new FpmfArchive(); if (inPath.EndsWith("\\")) { inPath = inPath.Substring(0, inPath.Length - 1); } uint currentOffset = 0; string baseArchivePath = inPath + "\\" + archiveName + archivePath; string[] inFiles = Directory.GetFiles(baseArchivePath, "*", SearchOption.AllDirectories); archive.numFiles = (uint)inFiles.Length; archive.datPath = dirPath; archive.datPathLen = dirPath.Length; foreach (string inFile in inFiles) { IBuffer inReader = new StreamBuffer(inFile); FpmfArchiveFile datFile = new FpmfArchiveFile(); datFile.size = (uint)inReader.Size; datFile.datNumber = 0; datFile.offset = currentOffset; IBuffer encryptedBuff = EncryptDat(inReader, archive.key); datFile.data = encryptedBuff.GetAllBytes(); datFile.filePath = inFile.Replace(inPath + "\\" + archiveName, "."); datFile.filePathSize = (uint)datFile.filePath.Length; datFile.directoryPath = ".\\" + archiveName + "\\"; datFile.directoryPathSize = (uint)datFile.directoryPath.Length; datFile.unknown0 = fileTime; datFile.unknown1 = 0; archive.AddFile(datFile); currentOffset += datFile.size; } if (archivePath.Length > 0) { outPath = outPath + "\\" + archiveName + archivePath; } else { outPath = outPath + "\\" + archiveName + "\\"; } SavePack(archive, inPath, outPath, archiveName); }
public FpmfArchive Open(string hedFilePath, string outPath = "") { FileInfo hedFile = new FileInfo(hedFilePath); if (!hedFile.Exists) { throw new FileNotFoundException($"File: {hedFilePath} not found."); } IBuffer hedBuffer = new StreamBuffer(hedFile.FullName); if (hedBuffer.Size < 12) { throw new Exception("File to small"); } hedBuffer.SetPositionStart(); byte[] magicBytes = hedBuffer.ReadBytes(4); for (int i = 0; i < 4; i++) { if (magicBytes[i] != MagicBytes[i]) { throw new Exception("Invalid File"); } } FpmfArchive archive = new FpmfArchive(); archive.Size = hedBuffer.ReadUInt32(); uint unknown0 = hedBuffer.ReadUInt32(); //BinaryWriter tmpwriter = new BinaryWriter(File.Open("C:\\Users\\kevin\\Desktop\\GameFilesSteamTest\\script_encrypted.hed", FileMode.Create)); //tmpwriter.Write(hedBuffer.GetAllBytes()); //tmpwriter.Flush(); //tmpwriter.Close(); hedBuffer = DecryptHed(hedBuffer); //tmpwriter = new BinaryWriter(File.Open("C:\\Users\\kevin\\Desktop\\GameFilesSteamTest\\script_unencrypted.hed", FileMode.Create)); //tmpwriter.Write(magicBytes); //tmpwriter.Write(archive.Size); //tmpwriter.Write(unknown0); //tmpwriter.Write(hedBuffer.GetAllBytes()); //tmpwriter.Flush(); //tmpwriter.Close(); hedBuffer.SetPositionStart(); uint unknown1 = hedBuffer.ReadUInt32(); uint unknown2 = hedBuffer.ReadUInt32(); byte unknown3 = hedBuffer.ReadByte(); byte unknown4 = hedBuffer.ReadByte(); uint unknown5 = hedBuffer.ReadUInt32(); uint unknown6 = hedBuffer.ReadUInt32(); int strLen = hedBuffer.ReadByte(); archive.DatPath = hedBuffer.ReadString(strLen); uint unknown7 = hedBuffer.ReadUInt32(); uint unknown8 = hedBuffer.ReadUInt32(); uint unknown9 = hedBuffer.ReadUInt32(); uint unknown10 = hedBuffer.ReadUInt32(); uint keyLen = hedBuffer.ReadUInt32(); archive.Key = hedBuffer.ReadBytes((int)keyLen); uint unknown11 = hedBuffer.ReadUInt32(); uint unknown12 = hedBuffer.ReadUInt32(); uint numFiles = hedBuffer.ReadUInt32(); //headerBuff.SetPositionStart(); string relativeArchiveDir = archive.DatPath .Replace("/%08x.dat", "") .Replace("./", "") .Replace('/', Path.DirectorySeparatorChar); string hedPath = hedFile.FullName.Replace(".hed", ""); string hedName = hedPath.Substring(hedPath.LastIndexOf("\\") + 1); string rootPath = hedPath.Replace(relativeArchiveDir, ""); DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); if (!rootDirectory.Exists) { throw new FileNotFoundException( $"Could not determinate root path. (Rel:{relativeArchiveDir} Hed:{hedPath} Root:{rootPath}"); } Logger.Info($"Using Root:{rootPath}"); Dictionary <uint, IBuffer> datBufferPool = new Dictionary <uint, IBuffer>(); for (int i = 0; i < numFiles; i++) { FpmfArchiveFile archiveFile = new FpmfArchiveFile(); strLen = hedBuffer.ReadByte(); archiveFile.DirectoryPath = hedBuffer.ReadString(strLen); strLen = hedBuffer.ReadByte(); archiveFile.FilePath = hedBuffer.ReadString(strLen); archiveFile.DatNumber = hedBuffer.ReadUInt32(); archiveFile.Offset = hedBuffer.ReadUInt32(); archiveFile.Size = hedBuffer.ReadUInt32(); uint unknown13 = hedBuffer.ReadUInt32(); uint unknown14 = hedBuffer.ReadUInt32(); uint unknown15 = addFileName(archiveFile.FilePath); uint unknown16 = addFileName(archiveFile.DirectoryPath); Logger.Info($"Processing: {archiveFile.FilePath}"); IBuffer datBuffer; if (datBufferPool.ContainsKey(archiveFile.DatNumber)) { datBuffer = datBufferPool[archiveFile.DatNumber]; } else { string datFileName = archive.DatPath .Replace("%08x", $"{archiveFile.DatNumber:X8}") .Replace("./", "") .Replace('/', Path.DirectorySeparatorChar); string datFilePath = Path.Combine(rootDirectory.FullName, datFileName); FileInfo datFile = new FileInfo(datFilePath); if (!datFile.Exists) { throw new FileNotFoundException($"File: {datFilePath} not found."); } datBuffer = new StreamBuffer(datFile.FullName); datBufferPool.Add(archiveFile.DatNumber, datBuffer); } IBuffer decrypted = DecryptDat(datBuffer, archiveFile.Offset, archiveFile.Size, archive.Key); if (archiveFile.FilePath.Contains("\\item.csv")) { decrypted = OpenWoItm(decrypted); } archiveFile.Data = decrypted.GetAllBytes(); archive.AddFile(archiveFile); } return(archive); }