/// <summary> /// Pack all files in folder to a CAMFile Object /// </summary> /// <param name="source"></param> /// <returns></returns> public static CAMFile Pack(string source) { var camFile = new CAMFile(); var extSections = Directory.GetFiles(source).GroupBy(p => Path.GetExtension(p)).Reverse().ToArray(); var sections = new CAMSection[extSections.Length]; var totalFileCount = 0; var fileShift = 0; for (int i = 0; i < extSections.Length; ++i) { var ext = extSections[i]; var section = new CAMSection(); var list = ext.ToArray(); section.IndexOffset = 12 + 4 + 4 + extSections.Length * 8 + i * 8 + fileShift * (20 + 4 + 4); section.Extension = ext.Key.TrimStart('.'); section.FilesData = new CAMData[list.Length]; for (int j = 0; j < section.FilesData.Length; ++j) { var fs = new FileStream(list[j], FileMode.Open); var data = new CAMData(); data.FileName = Path.GetFileNameWithoutExtension(list[j]); data.Size = (int)fs.Length; data.Data = new byte[fs.Length]; fs.Read(data.Data, 0, data.Size); section.FilesData[j] = data; ++totalFileCount; } sections[i] = section; fileShift += totalFileCount; } camFile.Sections = sections; camFile.SectionCount = extSections.Length; camFile.ContentOffset = extSections.Length * 8 + totalFileCount * (20 + 4 + 4); // SectionCount * 8(FileCount) + TotalFileCount * ( 20(text) + 4(offset) + 4(size) ) var fileSizeShift = 0; foreach (var section in sections) { foreach (var fileData in section.FilesData) { fileData.Offset = camFile.ContentOffset + fileSizeShift; fileSizeShift += fileData.Size; } } return(camFile); }
/// <summary> /// Generate CAMFile object from a cam File /// </summary> /// <param name="fs"></param> /// <returns></returns> public static CAMFile Read(Stream fs) { using var reader = new BinaryReader(fs); //Skip file header reader.BaseStream.Seek(12, SeekOrigin.Begin); var camFile = new CAMFile(); camFile.SectionCount = reader.ReadInt32(); // How many types. camFile.ContentOffset = reader.ReadInt32(); // First file offset = 0x12(FileHeader) + 0x04(SectionCount) + 0x04(ContentOffset) + 0x04 * SectionCount + ContentOffset camFile.Sections = new CAMSection[camFile.SectionCount]; for (int i = 0; i < camFile.Sections.Length; ++i) { var item = new CAMSection(); var code = reader.ReadBytes(4); item.Extension = Encoding.ASCII.GetString(code); item.IndexOffset = reader.ReadInt32(); camFile.Sections[i] = item; } for (int i = 0; i < camFile.Sections.Length; ++i) { var length = reader.ReadInt64(); // How many files with this Ext camFile.Sections[i].FilesData = new CAMData[length]; for (int j = 0; j < length; ++j) { var item = new CAMData(); var code = reader.ReadBytes(20);// voodoo item.FileName = Encoding.ASCII.GetString(code); item.Offset = reader.ReadInt32(); item.Size = reader.ReadInt32(); var current = fs.Position;// save position item.Data = new byte[item.Size]; fs.Seek(item.Offset, SeekOrigin.Begin); fs.Read(item.Data, 0, item.Size); fs.Seek(current, SeekOrigin.Begin); camFile.Sections[i].FilesData[j] = item; } } return(camFile); }