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(); }