Files
YarikStudio/AssetStudio/Game/Crypto/Mark.cs
2022-09-27 17:40:31 +04:00

67 lines
2.4 KiB
C#

using System;
using System.IO;
namespace AssetStudio
{
public static class Mark
{
private const string Signature = "mark";
private const int BlockSize = 0xA00;
private const int ChunkSize = 0x264;
private const int ChunkPadding = 4;
private static readonly int BlockPadding = ((BlockSize / ChunkSize) + 1) * ChunkPadding;
private static readonly int ChunkSizeWithPadding = ChunkSize + ChunkPadding;
private static readonly int BlockSizeWithPadding = BlockSize + BlockPadding;
public static byte[] Decrypt(FileReader reader)
{
var signature = reader.ReadStringToNull(4);
if (signature != Signature)
{
throw new InvalidOperationException($"Expected signature mark, got {signature} instead !!");
}
byte[] buffer;
var block = new byte[BlockSizeWithPadding];
using (var ms = new MemoryStream())
using (var writer = new BinaryWriter(ms))
{
while (reader.Length != reader.Position)
{
var blockSize = (int)Math.Min(reader.Length - reader.Position, BlockSizeWithPadding);
var readBytes = reader.Read(block, 0, blockSize);
if (readBytes != blockSize)
{
throw new InvalidOperationException($"Expected {blockSize} but got {readBytes} !!");
}
var offset = 0;
while (offset != blockSize)
{
var chunkSize = Math.Min(readBytes, ChunkSizeWithPadding);
if (!(blockSize == BlockSizeWithPadding || chunkSize == ChunkSizeWithPadding))
{
writer.Write(block, offset, chunkSize);
}
else
{
writer.Write(block, offset, chunkSize - ChunkPadding);
}
readBytes -= chunkSize;
offset += chunkSize;
}
}
buffer = ms.ToArray();
}
for (int j = 0; j < buffer.Length; j++)
{
buffer[j] ^= Crypto.MarkKey[j % Crypto.MarkKey.Length];
}
return buffer;
}
}
}