private void CompareSarc(SARCExt.SarcData a, SARCExt.SarcData b) { Assert.AreEqual(a.Files.Count, b.Files.Count); foreach (var f in a.Files) { if (!b.Files.ContainsKey(f.Key)) { throw new Exception($"{f.Key} is missing in B"); } if (!b.Files[f.Key].SequenceEqual(f.Value)) { throw new Exception($"file {f.Key} is different in B"); } } }
public static Tuple <int, byte[]> PackN(SarcData data, int _align = -1) { int align = _align >= 0 ? _align : (int)GuessAlignment(data.Files); MemoryStream o = new MemoryStream(); BinaryDataWriter bw = new BinaryDataWriter(o, false); bw.ByteOrder = data.endianness; bw.Write("SARC", BinaryStringFormat.NoPrefixOrTermination); bw.Write((UInt16)0x14); // Chunk length bw.Write((UInt16)0xFEFF); // BOM bw.Write((UInt32)0x00); //filesize update later bw.Write((UInt32)0x00); //Beginning of data bw.Write((UInt16)0x100); bw.Write((UInt16)0x00); bw.Write("SFAT", BinaryStringFormat.NoPrefixOrTermination); bw.Write((UInt16)0xc); bw.Write((UInt16)data.Files.Keys.Count); bw.Write((UInt32)0x00000065); List <uint> offsetToUpdate = new List <uint>(); //Sort files by hash string[] Keys = data.Files.Keys.OrderBy(x => data.HashOnly ? StringHashToUint(x) : NameHash(x)).ToArray(); foreach (string k in Keys) { if (data.HashOnly) { bw.Write(StringHashToUint(k)); } else { bw.Write(NameHash(k)); } offsetToUpdate.Add((uint)bw.BaseStream.Position); bw.Write((UInt32)0); bw.Write((UInt32)0); bw.Write((UInt32)0); } bw.Write("SFNT", BinaryStringFormat.NoPrefixOrTermination); bw.Write((UInt16)0x8); bw.Write((UInt16)0); List <uint> StringOffsets = new List <uint>(); foreach (string k in Keys) { StringOffsets.Add((uint)bw.BaseStream.Position); bw.Write(k, BinaryStringFormat.ZeroTerminated); bw.Align(4); } bw.Align(0x1000); //TODO: check if works in odyssey List <uint> FileOffsets = new List <uint>(); foreach (string k in Keys) { bw.Align((int)GuessFileAlignment(data.Files[k])); FileOffsets.Add((uint)bw.BaseStream.Position); bw.Write(data.Files[k]); } for (int i = 0; i < offsetToUpdate.Count; i++) { bw.BaseStream.Position = offsetToUpdate[i]; if (!data.HashOnly) { bw.Write(0x01000000 | ((StringOffsets[i] - StringOffsets[0]) / 4)); } else { bw.Write((UInt32)0); } bw.Write((UInt32)(FileOffsets[i] - FileOffsets[0])); bw.Write((UInt32)(FileOffsets[i] + data.Files[Keys[i]].Length - FileOffsets[0])); } bw.BaseStream.Position = 0x08; bw.Write((uint)bw.BaseStream.Length); bw.Write((uint)FileOffsets[0]); return(new Tuple <int, byte[]>(align, o.ToArray())); }