Archived
1
1
This repository has been archived on 2026-03-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
RTUnlocker/MetroUnlocker/LibTSForge/PhysicalStore/CRCBlock.cs
Lasse Lauwerys f20cf222a8 Initial commit
2025-02-20 16:33:04 +01:00

112 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MetroUnlocker.LibTSForge.PhysicalStore
{
public enum CRCBlockType : uint
{
UINT = 1 << 0,
STRING = 1 << 1,
BINARY = 1 << 2
}
public class CRCBlock
{
public CRCBlockType DataType;
public byte[] Key;
public string KeyAsStr
{
get
{
return Utils.DecodeString(Key);
}
set
{
Key = Utils.EncodeString(value);
}
}
public byte[] Value;
public string ValueAsStr
{
get
{
return Utils.DecodeString(Value);
}
set
{
Value = Utils.EncodeString(value);
}
}
public uint ValueAsInt
{
get
{
return BitConverter.ToUInt32(Value, 0);
}
set
{
Value = BitConverter.GetBytes(value);
}
}
public void Encode(BinaryWriter writer)
{
uint crc = CRC();
writer.Write(crc);
writer.Write((uint)DataType);
writer.Write(Key.Length);
writer.Write(Value.Length);
writer.Write(Key);
writer.Align(8);
writer.Write(Value);
writer.Align(8);
}
public static CRCBlock Decode(BinaryReader reader)
{
uint crc = reader.ReadUInt32();
uint type = reader.ReadUInt32();
uint lenName = reader.ReadUInt32();
uint lenVal = reader.ReadUInt32();
byte[] key = reader.ReadBytes((int)lenName);
reader.Align(8);
byte[] value = reader.ReadBytes((int)lenVal);
reader.Align(8);
CRCBlock block = new CRCBlock
{
DataType = (CRCBlockType)type,
Key = key,
Value = value,
};
if (block.CRC() != crc)
{
throw new InvalidDataException("Invalid CRC in variable bag.");
}
return block;
}
public uint CRC()
{
BinaryWriter wtemp = new BinaryWriter(new MemoryStream());
wtemp.Write(0);
wtemp.Write((uint)DataType);
wtemp.Write(Key.Length);
wtemp.Write(Value.Length);
wtemp.Write(Key);
wtemp.Write(Value);
return Utils.CRC32(((MemoryStream)wtemp.BaseStream).ToArray());
}
}
}