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();
            }
        }
Exemple #2
0
        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);
        }