Skip to content

Instantly share code, notes, and snippets.

@hhrhhr
Last active August 29, 2015 14:21
Show Gist options
  • Save hhrhhr/39396b76943bcb7875ef to your computer and use it in GitHub Desktop.
Save hhrhhr/39396b76943bcb7875ef to your computer and use it in GitHub Desktop.
public void Deserialize(Stream input)
{
this.Version = input.ReadValueU32();
this.EncryptionKey = 0;
if (this.Version >= 114)
{
this.EncryptionKey |= (uint)(input.ReadValueU16() << 16);
}
var keyCount = input.ReadValueEncodedS32();
this.Keys.Clear();
for (int i = 0; i < keyCount; i++)
{
var key = input.ReadEncodedString();
var index = input.ReadValueU32();
this.Keys.Add(key, index);
}
if (this.Version >= 114)
{
this.EncryptionKey |= (uint)(input.ReadValueU16() << 0);
}
var magic = GetRealKey(this.EncryptionKey);
uint stringsHash = 0;
if (this.Version >= 200)
{
stringsHash = input.ReadValueU32();
stringsHash ^= magic;
}
foreach (var key in this.Keys.Keys.ToArray())
{
this.Keys[key] ^= magic;
}
uint computedStringsHash = 0;
var stringCount = input.ReadValueEncodedS32();
for (int i = 0; i < stringCount; i++)
{
var index = input.ReadValueU32();
index ^= magic;
var buffer = input.ReadEncodedStringBuffer();
uint hash = 0;
for (int j = 0; j < buffer.Length; j += 2)
{
hash += BitConverter.ToUInt16(buffer, j);
}
computedStringsHash += hash;
if (magic != 0)
{
var stringKey = (ushort)(magic >> 8);
for (int j = 0; j < buffer.Length; j += 2)
{
if (this.Version >= 200)
{
var charKey = (ushort)(((buffer.Length / 2) + 1) * stringKey);
buffer[j + 0] ^= (byte)((charKey >> 0) & 0xFF);
buffer[j + 1] ^= (byte)((charKey >> 8) & 0xFF);
stringKey = stringKey.RotateLeft(1);
}
else
{
buffer[j + 0] ^= (byte)((stringKey >> 0) & 0xFF);
buffer[j + 1] ^= (byte)((stringKey >> 8) & 0xFF);
stringKey++;
}
}
}
if (index == 65434 &&
hash == 83394453)
{
// hack to fix this dumb corrupted string in en0.w2strings
this.Texts.Add(index, Encoding.Unicode.GetString(buffer, 0, 104));
}
else
{
this.Texts.Add(index, Encoding.Unicode.GetString(buffer));
}
}
if (this.Version >= 114 && this.Version < 200)
{
stringsHash = input.ReadValueU32();
}
/*if (this.Version >= 114 && stringsHash != computedStringsHash)
{
throw new FormatException("hash for strings does not match");
}*/
this.StringsHash = stringsHash;
this.ComputedStringsHash = computedStringsHash;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment