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); } } }
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); } }
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; }