private static void Pack2014(string sourcePath, string saveFileName, Platform platform, bool updateSng, bool updateManifest, bool fixShowlights = true)
        {
            using (var psarc = new PSARC.PSARC())
            using (var psarcStream = new MemoryStreamExtension())
            {
                if (updateSng)
                    UpdateSng2014(sourcePath, platform, fixShowlights: fixShowlights);
                if (updateManifest)
                    UpdateManifest2014(sourcePath, platform);

                WalkThroughDirectory("", sourcePath, (a, b) =>
               {
                   var fileStream = File.OpenRead(b);
                   psarc.AddEntry(a, fileStream);
               });

                psarc.Write(psarcStream, !platform.IsConsole);
                psarcStream.Flush();
                psarcStream.Seek(0, SeekOrigin.Begin);

                if (Path.GetExtension(saveFileName) != ".psarc")
                    saveFileName += ".psarc";

                using (var outputFileStream = File.Create(saveFileName))
                    psarcStream.CopyTo(outputFileStream);
            }
        }
        public void Write(Stream str, bool encrypt)
        {
            if (encrypt)
                this.header.archiveFlags = 4;
            this.header.TOCEntrySize = 30;
            this.UpdateManifest();
            Dictionary<Entry, byte[]> dictionary;
            List<uint> list;
            this.deflateEntries(out dictionary, out list, this.header.blockSize);
            byte b = 1;
            uint num = 256;
            do
            {
                num *= 256;
                b += 1;
            }
            while (num < this.header.blockSize);
            BigEndianBinaryWriter bigEndianBinaryWriter = new BigEndianBinaryWriter(str);
            this.header.TotalTOCSize = (uint)(32 + this.header.TOCEntrySize * (this.Entries.Count) + ((int)b * list.Count));
            this.Entries[0].Offset = (ulong)this.header.TotalTOCSize;
            for (int i = 1; i < this.Entries.Count; i++)
            {
                this.Entries[i].Offset = this.Entries[i - 1].Offset + (ulong)(dictionary[this.Entries[i - 1]].Length);
            }
            bigEndianBinaryWriter.Write(this.header.MagicNumber);
            bigEndianBinaryWriter.Write(this.header.VersionNumber);
            bigEndianBinaryWriter.Write(this.header.CompressionMethod);
            bigEndianBinaryWriter.Write(this.header.TotalTOCSize);
            bigEndianBinaryWriter.Write(this.header.TOCEntrySize);
            bigEndianBinaryWriter.Write(this.Entries.Count);
            bigEndianBinaryWriter.Write(this.header.blockSize);
            bigEndianBinaryWriter.Write(this.header.archiveFlags);
            foreach (Entry current in this.Entries)
            {
                current.UpdateNameMD5();
                bigEndianBinaryWriter.Write((current.id == 0) ? new byte[16] : current.MD5);
                bigEndianBinaryWriter.Write(current.zIndex);
                bigEndianBinaryWriter.WriteUInt40((ulong)current.Data.Length);
                bigEndianBinaryWriter.WriteUInt40(current.Offset);
            }
            foreach (uint current2 in list)
            {
                switch (b)
                {
                    case 2:
                        bigEndianBinaryWriter.Write((ushort)current2);
                        break;
                    case 3:
                        bigEndianBinaryWriter.WriteUInt24(current2);
                        break;
                    case 4:
                        bigEndianBinaryWriter.Write(current2);
                        break;
                }
            }
            foreach (Entry current in this.Entries)
            {
                bigEndianBinaryWriter.Write(dictionary[current]);
            }

            if (encrypt)
            {
                var encStream = new MemoryStreamExtension();
                using (var outputStream = new MemoryStreamExtension())
                {
                    str.Seek(32, SeekOrigin.Begin);
                    RijndaelEncryptor.EncryptPSARC(str, outputStream, this.header.TotalTOCSize);

                    int bytesRead;
                    byte[] buffer = new byte[30000];

                    str.Seek(0, SeekOrigin.Begin);
                    while ((bytesRead = str.Read(buffer, 0, buffer.Length)) > 0)
                        encStream.Write(buffer, 0, bytesRead);
                    int decMax = (int)this.header.TotalTOCSize - 32;
                    int decSize = 0;
                    outputStream.Seek(0, SeekOrigin.Begin);
                    encStream.Seek(32, SeekOrigin.Begin);
                    while ((bytesRead = outputStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        decSize += bytesRead;
                        if (decSize > decMax) bytesRead = decMax - (decSize - bytesRead);
                        encStream.Write(buffer, 0, bytesRead);
                    }
                }

                str.Seek(0, SeekOrigin.Begin);
                encStream.Seek(0, SeekOrigin.Begin);
                encStream.CopyTo(str);
            }

            str.Flush();
        }