private static void ReplaceEntry(DrpFileEntry entry, byte[] replaceWith) { var before = entry.GetData().Length; var after = replaceWith.Length; entry.SetData(replaceWith); var msg = $"Replaced: {entry.FileName}."; if (before != after) { msg += $" {before}->{after}"; } Console.WriteLine(msg); }
private static void WriteEntry(this BinaryWriter bw, DrpFileEntry entry, bool encrypted, ReadOnlySpan <byte> table) { Debug.WriteLine($"Writing entry at 0x0{bw.BaseStream.Position:X}."); var h = entry.Header; var seed = entry.GetChecksum(); ReadOnlySpan <byte> payload = entry.GetData(); h.CompressedSize = h.DecompressedSize = payload.Length; if (entry.Compressed) { payload = Oodle.Compress(payload, out int size); h.CompressedSize = 4 + size; Debug.Assert((payload.Length & 3) == 0); } var nameSize = (entry.FileName.Length | 3) + 1; // next multiple of 4 var dataSize = (h.CompressedSize + 3) & ~3; // roundup multiple of 4 h.SizeTotal = 0x18 + nameSize + dataSize; bw.Write(seed); if (encrypted) { var rng = XorShiftUtil.GetEncryptionRng(seed, table); bw.Write(rng.GetNext(uint.MaxValue) ^ h.Magic); bw.Write(rng.GetNext(uint.MaxValue) ^ (uint)h.SizeTotal); bw.Write(rng.GetNext(uint.MaxValue) ^ h.Extension); bw.Write(rng.GetNext(uint.MaxValue) ^ (uint)h.CompressedSize); bw.Write(rng.GetNext(uint.MaxValue) ^ (uint)h.DecompressedSize); Span <byte> temp = stackalloc byte[4]; var fn = entry.FileName; int ctr = 0; foreach (var c in fn) { temp[ctr++] = (byte)c; if (ctr != 4) { continue; } bw.Write(rng.GetNext(uint.MaxValue) ^ BitConverter.ToUInt32(temp)); temp.Clear(); ctr = 0; } if (ctr == 0) { bw.Write(rng.GetNext(uint.MaxValue) ^ 0u); } else { bw.Write(rng.GetNext(uint.MaxValue) ^ BitConverter.ToUInt32(temp)); } var asUint = MemoryMarshal.Cast <byte, uint>(payload); if (entry.Compressed) { bw.Write(rng.GetNext(uint.MaxValue) ^ DrpFileHeader.CompressedDataMagic); } foreach (var u32 in asUint) { bw.Write(rng.GetNext(uint.MaxValue) ^ u32); } var slice = payload[(asUint.Length * 4)..];