public void SetProperties(RobloxDocument document, Instance instance, PropertyCollection propertyCollection)
        {
            var instanceType = instance.GetType();

            foreach (var property in propertyCollection)
            {
                if (ReflectionMappingManager.HasMappedClrProperty(instanceType, property.Name))
                {
                    var mappedPropertyTuple = ReflectionMappingManager.GetMappedClrProperty(instanceType, property.Name);
                    if (mappedPropertyTuple.Item2 != PropertyType.Referent)
                    {
                        mappedPropertyTuple.Item1.SetValue(instance, property.Get());
                    }
                    else
                    {
                        var referent = (int)property.Get();
                        if (referent != 0)
                        // It seems like in many cases 0 means no referent? For example, gui object's next selection property. TODO look into this.
                        {
                            var inst = (referent != -1) ? document.ReferentProvider.GetCached(referent) : null;
                            mappedPropertyTuple.Item1.SetValue(instance, inst);
                        }
                    }
                }
                else
                {
                    instance.UnmanagedProperties.Add(property.Name, property);
                }
            }
        }
Beispiel #2
0
        public static RobloxDocument FromStream(Stream stream)
        {
            try
            {
                var reader = new EndianAwareBinaryReader(stream);

                int          typeCount;
                int          objectCount;
                TypeHeader[] typeHeaders;
                Dictionary <int, List <PropertyBlock> > propertyData;
                Tuple <int, int>[] childParentPairs;
                ReadRaw(reader, out typeCount, out objectCount, out typeHeaders, out propertyData, out childParentPairs);

                // Ignore the ...</roblox>

                // Create RobloxDocument object
                var document = new RobloxDocument();
                FillRobloxDocument(document, objectCount, typeHeaders, propertyData, childParentPairs);
                return(document);
            }
            catch (Exception ex)
            {
                throw new InvalidRobloxFileException("The specified Roblox file is corrupt or invalid.", ex);
            }
        }
Beispiel #3
0
        internal static void FillRobloxDocument(RobloxDocument document, int objectCount, TypeHeader[] typeHeaders, Dictionary <int, List <PropertyBlock> > propertyData, Tuple <int, int>[] childParentPairs, Dictionary <Instance, PropertyCollection> propertyDict = null)
        {
            var serializer          = new RobloxSerializer(document);
            var instances           = new List <Instance>(objectCount);
            var propertyCollections = new List <PropertyCollection>();

            // Create instances for described objects
            foreach (var type in typeHeaders)
            {
                for (var i = 0; i < type.InstanceCount; i++)
                {
                    var instance = InstanceFactory.Create(type.Name, type.AdditionalData != null);
                    var referent = type.Referents[i];
                    document.ReferentProvider.Add(instance, referent);
                    instances.Add(instance);

                    var propertyCollection    = new PropertyCollection();
                    var propertyDataBlockList = propertyData[type.TypeId];
                    foreach (var propertyBlock in propertyDataBlockList)
                    {
                        propertyCollection.Add(propertyBlock.GetProperty(i));
                    }
                    propertyCollections.Add(propertyCollection);
                }
            }

            // Set properties
            for (var i = 0; i < instances.Count; i++)
            {
                var instance = instances[i];
                serializer.SetProperties(document, instance, propertyCollections[i]);
                propertyDict?.Add(instance, propertyCollections[i]);
            }

            // Set parents
            foreach (var pair in childParentPairs)
            {
                var child = document.ReferentProvider.GetCached(pair.Item1);
                if (pair.Item2 == -1) // No parent
                {
                    document.Children.Add(child);
                }
                else
                {
                    var parent = document.ReferentProvider.GetCached(pair.Item2);
                    child.Parent = parent;
                }
            }
        }
 public RobloxSerializer(RobloxDocument document)
 {
     _document = document;
 }