public override void Write(Stream destination) { using (CriTableWriter writer = CriTableWriter.Create(destination, CriTableWriterSettings.AdxSettings)) { string tableName = "AAX"; switch (Mode) { case CriAaxArchiveMode.Adx: tableName = "AAX"; break; case CriAaxArchiveMode.Dsp: tableName = "ADPCM_WII"; break; case CriAaxArchiveMode.Wav: tableName = "SWLPCM"; break; } writer.WriteStartTable(tableName); writer.WriteField("data", typeof(byte[])); writer.WriteField("lpflg", typeof(byte)); foreach (CriAaxEntry entry in entries.OrderBy(entry => entry.Flag)) { writer.WriteRow(true, entry.FilePath, (byte)entry.Flag); } writer.WriteEndTable(); } }
public override void Write(Stream destination) { string GetToolVersion() { AssemblyName assemblyName = Assembly.GetEntryAssembly().GetName(); return($"{assemblyName.Name}, {assemblyName.Version.ToString()}"); } DataPool vldPool = new DataPool(Align, 2048); vldPool.ProgressChanged += OnProgressChanged; using (CriCpkSection cpkSection = new CriCpkSection(destination, "CPK ", enableMask)) { cpkSection.Writer.WriteStartTable("CpkHeader"); cpkSection.Writer.WriteField("UpdateDateTime", typeof(ulong)); cpkSection.Writer.WriteField("FileSize", typeof(ulong)); cpkSection.Writer.WriteField("ContentOffset", typeof(ulong)); cpkSection.Writer.WriteField("ContentSize", typeof(ulong)); if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId) { cpkSection.Writer.WriteField("TocOffset", typeof(ulong)); cpkSection.Writer.WriteField("TocSize", typeof(ulong)); cpkSection.Writer.WriteField("TocCrc", typeof(uint), null); cpkSection.Writer.WriteField("EtocOffset", typeof(ulong)); cpkSection.Writer.WriteField("EtocSize", typeof(ulong)); } else { cpkSection.Writer.WriteField("TocOffset", typeof(ulong), null); cpkSection.Writer.WriteField("TocSize", typeof(ulong), null); cpkSection.Writer.WriteField("TocCrc", typeof(uint), null); cpkSection.Writer.WriteField("EtocOffset", typeof(ulong), null); cpkSection.Writer.WriteField("EtocSize", typeof(ulong), null); } if (mode == CriCpkMode.Id || mode == CriCpkMode.FileNameAndId) { cpkSection.Writer.WriteField("ItocOffset", typeof(ulong)); cpkSection.Writer.WriteField("ItocSize", typeof(ulong)); cpkSection.Writer.WriteField("ItocCrc", typeof(uint), null); } else { cpkSection.Writer.WriteField("ItocOffset", typeof(ulong), null); cpkSection.Writer.WriteField("ItocSize", typeof(ulong), null); cpkSection.Writer.WriteField("ItocCrc", typeof(uint), null); } cpkSection.Writer.WriteField("GtocOffset", typeof(ulong), null); cpkSection.Writer.WriteField("GtocSize", typeof(ulong), null); cpkSection.Writer.WriteField("GtocCrc", typeof(uint), null); cpkSection.Writer.WriteField("EnabledPackedSize", typeof(ulong)); cpkSection.Writer.WriteField("EnabledDataSize", typeof(ulong)); cpkSection.Writer.WriteField("TotalDataSize", typeof(ulong), null); cpkSection.Writer.WriteField("Tocs", typeof(uint), null); cpkSection.Writer.WriteField("Files", typeof(uint)); cpkSection.Writer.WriteField("Groups", typeof(uint)); cpkSection.Writer.WriteField("Attrs", typeof(uint)); cpkSection.Writer.WriteField("TotalFiles", typeof(uint), null); cpkSection.Writer.WriteField("Directories", typeof(uint), null); cpkSection.Writer.WriteField("Updates", typeof(uint), null); cpkSection.Writer.WriteField("Version", typeof(ushort)); cpkSection.Writer.WriteField("Revision", typeof(ushort)); cpkSection.Writer.WriteField("Align", typeof(ushort)); cpkSection.Writer.WriteField("Sorted", typeof(ushort)); cpkSection.Writer.WriteField("EID", typeof(ushort), null); cpkSection.Writer.WriteField("CpkMode", typeof(uint)); cpkSection.Writer.WriteField("Tvers", typeof(string)); if (!string.IsNullOrEmpty(Comment)) { cpkSection.Writer.WriteField("Comment", typeof(string)); } else { cpkSection.Writer.WriteField("Comment", typeof(string), null); } cpkSection.Writer.WriteField("Codec", typeof(uint)); cpkSection.Writer.WriteField("DpkItoc", typeof(uint)); MemoryStream tocMemoryStream = null; MemoryStream itocMemoryStream = null; MemoryStream etocMemoryStream = null; if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId) { tocMemoryStream = new MemoryStream(); etocMemoryStream = new MemoryStream(); var orderedEntries = entries.OrderBy(entry => entry.Name).ToList(); using (CriCpkSection tocSection = new CriCpkSection(tocMemoryStream, "TOC ", enableMask)) using (CriCpkSection etocSection = new CriCpkSection(etocMemoryStream, "ETOC", enableMask)) { tocSection.Writer.WriteStartTable("CpkTocInfo"); tocSection.Writer.WriteField("DirName", typeof(string)); tocSection.Writer.WriteField("FileName", typeof(string)); tocSection.Writer.WriteField("FileSize", typeof(uint)); tocSection.Writer.WriteField("ExtractSize", typeof(uint)); tocSection.Writer.WriteField("FileOffset", typeof(ulong)); tocSection.Writer.WriteField("ID", typeof(uint)); tocSection.Writer.WriteField("UserString", typeof(string)); etocSection.Writer.WriteStartTable("CpkEtocInfo"); etocSection.Writer.WriteField("UpdateDateTime", typeof(ulong)); etocSection.Writer.WriteField("LocalDir", typeof(string)); foreach (CriCpkEntry entry in orderedEntries) { tocSection.Writer.WriteRow(true, (entry.DirectoryName).Replace('\\', '/'), entry.Name, (uint)entry.Length, (uint)entry.Length, (ulong)(vldPool.Length - 2048), entry.Id, entry.Comment); etocSection.Writer.WriteRow(true, CpkDateTimeFromDateTime(entry.UpdateDateTime), entry.DirectoryName); vldPool.Put(entry.FilePath); } tocSection.Writer.WriteEndTable(); etocSection.Writer.WriteEndTable(); } if (mode == CriCpkMode.FileNameAndId) { itocMemoryStream = new MemoryStream(); using (CriCpkSection itocSection = new CriCpkSection(itocMemoryStream, "ITOC", enableMask)) { itocSection.Writer.WriteStartTable("CpkExtendId"); itocSection.Writer.WriteField("ID", typeof(int)); itocSection.Writer.WriteField("TocIndex", typeof(int)); foreach (CriCpkEntry entry in orderedEntries) { itocSection.Writer.WriteRow(true, (int)entry.Id, orderedEntries.IndexOf(entry)); } itocSection.Writer.WriteEndTable(); } } } else if (mode == CriCpkMode.Id) { itocMemoryStream = new MemoryStream(); using (CriCpkSection itocSection = new CriCpkSection(itocMemoryStream, "ITOC", enableMask)) { itocSection.Writer.WriteStartTable("CpkItocInfo"); itocSection.Writer.WriteField("FilesL", typeof(uint)); itocSection.Writer.WriteField("FilesH", typeof(uint)); itocSection.Writer.WriteField("DataL", typeof(byte[])); itocSection.Writer.WriteField("DataH", typeof(byte[])); List <CriCpkEntry> filesL = entries.Where(entry => entry.Length < ushort.MaxValue).ToList(); List <CriCpkEntry> filesH = entries.Where(entry => entry.Length > ushort.MaxValue).ToList(); itocSection.Writer.WriteStartRow(); using (MemoryStream dataMemoryStream = new MemoryStream()) using (CriTableWriter dataWriter = CriTableWriter.Create(dataMemoryStream)) { dataWriter.WriteStartTable("CpkItocL"); dataWriter.WriteField("ID", typeof(ushort)); dataWriter.WriteField("FileSize", typeof(ushort)); dataWriter.WriteField("ExtractSize", typeof(ushort)); foreach (CriCpkEntry entry in filesL) { dataWriter.WriteRow(true, (ushort)entry.Id, (ushort)entry.Length, (ushort)entry.Length); } dataWriter.WriteEndTable(); itocSection.Writer.WriteValue("DataL", dataMemoryStream.ToArray()); } using (MemoryStream dataMemoryStream = new MemoryStream()) using (CriTableWriter dataWriter = CriTableWriter.Create(dataMemoryStream)) { dataWriter.WriteStartTable("CpkItocH"); dataWriter.WriteField("ID", typeof(ushort)); dataWriter.WriteField("FileSize", typeof(uint)); dataWriter.WriteField("ExtractSize", typeof(uint)); foreach (CriCpkEntry entry in filesH) { dataWriter.WriteRow(true, (ushort)entry.Id, (uint)entry.Length, (uint)entry.Length); } dataWriter.WriteEndTable(); itocSection.Writer.WriteValue("DataH", dataMemoryStream.ToArray()); } itocSection.Writer.WriteValue("FilesL", (uint)filesL.Count); itocSection.Writer.WriteValue("FilesH", (uint)filesH.Count); itocSection.Writer.WriteEndRow(); itocSection.Writer.WriteEndTable(); } foreach (CriCpkEntry entry in entries.OrderBy(entry => entry.Id)) { vldPool.Put(entry.FilePath); } } else { throw new NotImplementedException($"Unimplemented CPK mode ({mode})"); } cpkSection.Writer.WriteStartRow(); cpkSection.Writer.WriteValue("UpdateDateTime", CpkDateTimeFromDateTime(DateTime.Now)); cpkSection.Writer.WriteValue("ContentOffset", (ulong)2048); cpkSection.Writer.WriteValue("ContentSize", (ulong)(vldPool.Length - 2048)); if (tocMemoryStream != null) { cpkSection.Writer.WriteValue("TocOffset", (ulong)vldPool.Put(tocMemoryStream)); cpkSection.Writer.WriteValue("TocSize", (ulong)tocMemoryStream.Length); } if (itocMemoryStream != null) { cpkSection.Writer.WriteValue("ItocOffset", (ulong)vldPool.Put(itocMemoryStream)); cpkSection.Writer.WriteValue("ItocSize", (ulong)itocMemoryStream.Length); } if (etocMemoryStream != null) { cpkSection.Writer.WriteValue("EtocOffset", (ulong)vldPool.Put(etocMemoryStream)); cpkSection.Writer.WriteValue("EtocSize", (ulong)etocMemoryStream.Length); } long totalDataSize = 0; foreach (CriCpkEntry entry in entries) { totalDataSize += entry.Length; } cpkSection.Writer.WriteValue("EnabledPackedSize", totalDataSize); cpkSection.Writer.WriteValue("EnabledDataSize", totalDataSize); cpkSection.Writer.WriteValue("Files", (uint)entries.Count); cpkSection.Writer.WriteValue("Version", (ushort)7); cpkSection.Writer.WriteValue("Revision", (ushort)2); cpkSection.Writer.WriteValue("Align", Align); cpkSection.Writer.WriteValue("Sorted", (ushort)1); cpkSection.Writer.WriteValue("CpkMode", (uint)mode); cpkSection.Writer.WriteValue("Tvers", GetToolVersion()); cpkSection.Writer.WriteValue("Comment", Comment); cpkSection.Writer.WriteValue("FileSize", (ulong)vldPool.Length); cpkSection.Writer.WriteEndRow(); cpkSection.Writer.WriteEndTable(); } DataStream.Pad(destination, 2042); DataStream.WriteCString(destination, "(c)CRI", 6); vldPool.Write(destination); }