public EndianIO GetResourceIO(int patchFileNumber) { var resPath = ResourceFilePath(patchFileNumber); if (!resourceIOs.ContainsKey(resPath)) { if (!File.Exists(resPath)) { return(null); } var io = new EndianIO(resPath, FileMode.Open); io.Stream.Position = 0; var magic = io.Reader.ReadUInt32(); if ((magic & 0xFFFFFF00) != 0x52455300) { io.Close(); return(null); } resourceIOs.Add(resPath, io); } return(resourceIOs[resPath]); }
public void Close() { if (indexIO != null) { indexIO.Close(); indexIO = null; } if (resourceIOs != null) { foreach (var kvp in resourceIOs) { kvp.Value.Close(); } resourceIOs.Clear(); resourceIOs = null; } }
public void Rebuild(string destResourceFile, string replaceFromFolder = "", bool keepCompressed = false) { if (File.Exists(destResourceFile)) { File.Delete(destResourceFile); } if (!String.IsNullOrEmpty(replaceFromFolder)) { replaceFromFolder = replaceFromFolder.Replace("/", "\\"); if (!replaceFromFolder.EndsWith("\\")) { replaceFromFolder += "\\"; } } var destResources = new EndianIO(destResourceFile, FileMode.CreateNew); byte[] header = { Header_Version, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (PatchFileNumber > 0) { header = new byte[] { Header_Version, 0x53, 0x45, 0x52 } } ; // patch files start at 0x4 instead destResources.Writer.Write(header); var addedFiles = new List <string>(); foreach (var file in Entries) { var replacePath = (String.IsNullOrEmpty(replaceFromFolder) ? String.Empty : Path.Combine(replaceFromFolder, file.GetFullName())); if (File.Exists(replacePath + ";" + file.FileType)) { replacePath += ";" + file.FileType; } bool isReplacing = !string.IsNullOrEmpty(replaceFromFolder) && File.Exists(replacePath); if (file.PatchFileNumber != PatchFileNumber && !isReplacing) { continue; // file is located in a different patch resource and we aren't replacing it, so skip it } bool needToPad = destResources.Stream.Length % 0x10 != 0; if (PatchFileNumber > 0 && destResources.Stream.Length == 4) { needToPad = false; // for some reason patch files start at 0x4 instead of 0x10 } if (file.IsCompressed && !isReplacing && PatchFileNumber > 0) // compressed files not padded in patch files? { needToPad = false; } if (needToPad) { long numPadding = 0x10 - (destResources.Stream.Length % 0x10); destResources.Stream.SetLength(destResources.Stream.Length + numPadding); } if (file.Size <= 0 && file.CompressedSize <= 0) { // patch indexes have offsets for 0-byte files set to 0, but in normal indexes it's the current resource file length file.Offset = PatchFileNumber > 0 ? 0 : destResources.Stream.Length; continue; } var offset = destResources.Stream.Length; destResources.Stream.Position = offset; if (isReplacing) { file.PatchFileNumber = PatchFileNumber; addedFiles.Add(replacePath); using (var fs = File.OpenRead(replacePath)) file.CompressedSize = file.Size = (int)Utility.StreamCopy(destResources.Stream, fs, 40960, fs.Length); } else { file.CompressedSize = (int)CopyEntryDataToStream(file, destResources.Stream, !keepCompressed); } file.Offset = offset; } // now add any files that weren't replaced if (!String.IsNullOrEmpty(replaceFromFolder)) { addFilesFromFolder(replaceFromFolder, replaceFromFolder, destResources, ref addedFiles); } // read the fileIds.txt file if it exists, and set the IDs var idFile = Path.Combine(replaceFromFolder, "fileIds.txt"); if (File.Exists(idFile)) { var lines = File.ReadAllLines(idFile); foreach (var line in lines) { if (String.IsNullOrEmpty(line.Trim())) { continue; } var sepIdx = line.LastIndexOf('='); if (sepIdx < 0) { continue; // todo: warn user? } var fileName = line.Substring(0, sepIdx).Trim(); var fileId = line.Substring(sepIdx + 1).Trim(); int id = -1; if (!int.TryParse(fileId, out id)) { Console.WriteLine($"Warning: file {fileName} defined in fileIds.txt but has invalid id!"); continue; } var file = Entries.Find(s => s.GetFullName() == fileName); if (file == null) { file = Entries.Find(s => s.GetFullName().Replace("\\", "/") == fileName); } if (file != null) { file.ID = id; } else { Console.WriteLine($"Warning: file {fileName} defined in fileIds.txt but doesn't exist?"); } } } destResources.Close(); Save(); }