예제 #1
0
        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]);
                            }
                        }
                    }
                }
        }