public static byte[] ResolveHash(WZProperty prop) { using (WZReader reader = prop.FileContainer.GetContentReader(null, prop)) using (SHA1 sha = SHA1.Create()) { reader.BaseStream.Position = prop.Offset; switch (prop.Type) { case PropertyType.Image: reader.BaseStream.Position = prop.ContainerStartLocation; byte imgType = reader.ReadByte(); if (imgType == 1) { byte unk = reader.ReadByte(); return(reader.GetLuaScriptBytes().ToArray()); } else { return(new byte[0]); } case PropertyType.Directory: return(new byte[0]); case PropertyType.SubProperty: return(new byte[0]); case PropertyType.Convex: return(new byte[0]); case PropertyType.Vector2: return(sha.ComputeHash(reader.GetWZIntBytes().Concat(reader.GetWZIntBytes()).ToArray())); case PropertyType.UOL: return(sha.ComputeHash(reader.GetWZStringBlockBytes(prop.Encrypted | prop.Container.Encrypted))); case PropertyType.Audio: using (Stream sub = new SubStream(reader.BaseStream, (int)reader.BaseStream.Position, prop.Size)) return(sha.ComputeHash(sub)); case PropertyType.Canvas: reader.BaseStream.Seek(1, SeekOrigin.Current); byte[][] childHashes; if (reader.ReadByte() == 1) { reader.BaseStream.Seek(2, SeekOrigin.Current); childHashes = PropertyList(reader, prop).ToArray().Select(c => ResolveHash(c)).ToArray(); } else { childHashes = new byte[0][]; } int width = reader.ReadWZInt(); // width int height = reader.ReadWZInt(); // height int format1 = reader.ReadWZInt(); // format 1 byte format2 = reader.ReadByte(); // format 2 reader.BaseStream.Seek(4, SeekOrigin.Current); uint blockLen = (uint)reader.ReadInt32(); ushort header = reader.PeekFor(() => reader.ReadUInt16()); byte[] imageHash = new byte[0]; using (Stream sub = new SubStream(reader.BaseStream, reader.BaseStream.Position, blockLen - 1)) imageHash = sha.ComputeHash(sub); if (childHashes.Length > 0) { return(calcAggregateHash(sha, childHashes.Prepend(imageHash).ToArray())); } else { return(imageHash); } default: byte[] nameHash = sha.ComputeHash(reader.GetWZStringBlockBytes(prop.Encrypted | prop.Container.Encrypted)); byte type = reader.ReadByte(); switch (type) { case 0: return(nameHash); case 0x10: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.ReadBytes(1)))); case 0x11: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.ReadBytes(1)))); case 0x0B: case 2: case 0x12: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.ReadBytes(2)))); case 3: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.GetWZIntBytes()))); case 19: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.GetWZIntBytes()))); case 4: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.GetWZSingleBytes()))); case 5: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.ReadBytes(8)))); case 8: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.GetWZStringBlockBytes(prop.Container.Encrypted)))); case 9: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.ReadBytes(reader.ReadInt32())))); case 20: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.GetWZLongBytes()))); case 21: return(calcAggregateHash(sha, nameHash, sha.ComputeHash(reader.GetWZLongBytes()))); default: System.Diagnostics.Debugger.Break(); Console.WriteLine("Wow"); if (type > 100) { throw new Exception("Unknown property type at ParsePropertyList"); } else { return(new byte[0]); } } } } }