Beispiel #1
0
        public void Read_AdditionalData()
        {
            var data = new byte[] { 0x13, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x74, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x06, 0x01, 0x02, 0x03 };

            var parsed = TypeHeader.Deserialize(data);

            Assert.AreEqual("Part", parsed.Name);
            Assert.AreEqual(0x13, parsed.TypeId);
            Assert.AreEqual(3, parsed.InstanceCount);
            Assert.AreEqual(new[] { 2, 3, 6 }, parsed.Referents);
            Assert.AreEqual(new byte[] { 0x1, 0x2, 0x3 }, parsed.AdditionalData);
        }
Beispiel #2
0
        public void Serialziation()
        {
            var rand = new Random(20121230);

            for (int i = 0; i < 1000; i += 1)
            {
                int kind    = rand.Next(0, 3);
                int ordinal = rand.Next(1, 32767);
                int length  = 0;

                if (kind == 3)
                {
                    length = rand.Next(8, 2147483647);
                }

                var head1 = new TypeHeader
                {
                    Kind    = (TypeKind)kind,
                    Size    = length,
                    Ordinal = ordinal,
                };
                var head2 = new TypeHeader {
                };

                Assert.Equal((TypeKind)kind, head1.Kind);
                Assert.Equal(length, head1.Size);
                Assert.Equal(ordinal, head1.Ordinal);

                Assert.NotEqual(head1, head2);

                Assert.Equal((TypeKind)0, head2.Kind);
                Assert.Equal(0, head2.Size);
                Assert.Equal(0, head2.Ordinal);

                Guid buf = Guid.Empty;

                int size = head1.Serialize((byte *)&buf, sizeof(Guid));
                int read = head2.Deserialize((byte *)&buf, sizeof(Guid));

                Assert.Equal(size, read);
                Assert.Equal(head1, head2, new TypeHeaderComparer());
            }
        }
Beispiel #3
0
        internal static void ReadRaw(EndianAwareBinaryReader reader, out int typeCount, out int objectCount, out TypeHeader[] typeHeaders, out Dictionary <int, List <PropertyBlock> > propertyData, out Tuple <int, int>[] childParentPairs)
        {
            // Check file signature
            var signatureBytes = reader.ReadBytes(Signatures.Signature.Length);

            if (!signatureBytes.SequenceEqual(Signatures.Signature))
            {
                throw new InvalidRobloxFileException("The file signature does not match.");
            }

            typeCount   = reader.ReadInt32();
            objectCount = reader.ReadInt32();
            reader.ReadInt32(); // Reserved
            reader.ReadInt32(); // Reserved

            // Deserialize type headers
            typeHeaders = new TypeHeader[typeCount];
            for (var i = 0; i < typeCount; i++)
            {
                var typeHeaderSignature = reader.ReadBytes(Signatures.TypeHeaderSignature.Length);
                if (!typeHeaderSignature.SequenceEqual(Signatures.TypeHeaderSignature))
                {
                    throw new InvalidRobloxFileException("Invalid type header signature.");
                }

                var decompressedBytes = RobloxLZ4.ReadBlock(reader.Stream);
                var typeHeader        = TypeHeader.Deserialize(decompressedBytes);
                typeHeaders[i] = typeHeader;
            }

            // Read property data
            propertyData = new Dictionary <int, List <PropertyBlock> >(); // Key is type id
            byte[] lastPropSignature;

            while (true)
            {
                lastPropSignature = reader.ReadBytes(Signatures.PropBlockSignature.Length);
                if (!lastPropSignature.SequenceEqual(Signatures.PropBlockSignature))
                {
                    break;
                }

                var decompressedBytes = RobloxLZ4.ReadBlock(reader.Stream);
                var propertyBlock     = PropertyBlock.Deserialize(decompressedBytes, typeHeaders);

                if (propertyBlock == null)
                {
                    continue;
                }

                if (!propertyData.ContainsKey(propertyBlock.TypeId))
                {
                    propertyData.Add(propertyBlock.TypeId, new List <PropertyBlock>());
                }
                propertyData[propertyBlock.TypeId].Add(propertyBlock);
            }

            if (!lastPropSignature.SequenceEqual(Signatures.ParentDataSignature))
            {
                throw new InvalidRobloxFileException("Missing parent data section.");
            }
            var parentData = RobloxLZ4.ReadBlock(reader.Stream);

            childParentPairs = Util.ReadParentData(parentData);

            var endSignature = reader.ReadBytes(Signatures.EndSignature.Length);

            if (!endSignature.SequenceEqual(Signatures.EndSignature))
            {
                throw new InvalidRobloxFileException("End signature is missing or invalid.");
            }
        }