public void ReadObjects(string fileName)
 {
     MappedObjectData.Clear();
     MappedObjects.Clear();
     for (var i = 0; i < Count; i++)
     {
         var dataBytes    = new byte[DataLength];
         var objectOffset = Offset + (i * Size);
         using (var fs = File.OpenRead(fileName))
         {
             fs.Seek(objectOffset, SeekOrigin.Begin);
             fs.Read(dataBytes, 0, DataLength);
         }
         Type type         = typeof(T);
         var  ctor         = type.GetConstructor(new[] { typeof(byte[]), typeof(long) });
         var  mappedObject = (T)ctor.Invoke(new object[] { dataBytes, objectOffset });
         if (mappedObject.Id == -1)
         {
             mappedObject.Id = i;
         }
         if (MappedObjectData.ContainsKey(mappedObject.Id))
         {
             MappedObjectData[mappedObject.Id].AddOffset(objectOffset, dataBytes);
         }
         else
         {
             MappedObjectData.Add(mappedObject.Id, mappedObject);
             MappedObjects.Add(mappedObject);
         }
     }
 }
        public ObjectCollector(GameObjectContainer container, GameObject gameObject, bool followReferences, bool withComponents)
        {
            Stack <IPropertyContainer> toVisit = new Stack <IPropertyContainer>();

            startIndex = 0;

            MappedObjects[gameObject.Id] = gameObject;
            toVisit.Push(gameObject);

            visit(toVisit, container, followReferences, withComponents);

            insertIndex = MappedObjects.Any() ? MappedObjects.Keys.Max() : 0;
        }
        public ObjectCollector(GameObjectContainer container, ArkName className, bool followReferences, bool withComponents)
        {
            Stack <IPropertyContainer> toVisit = new Stack <IPropertyContainer>();

            startIndex = 0;

            foreach (GameObject gameObject in container)
            {
                if (gameObject.ClassName == className)
                {
                    MappedObjects[gameObject.Id] = gameObject;
                    toVisit.Push(gameObject);
                }
            }

            visit(toVisit, container, followReferences, withComponents);

            insertIndex = MappedObjects.Any() ? MappedObjects.Keys.Max() : 0;
        }
        private void visit(Stack <IPropertyContainer> toVisit, GameObjectContainer container, bool followReferences, bool withComponents)
        {
            while (toVisit.Any())
            {
                IPropertyContainer currentInstance = toVisit.Pop();

                if (followReferences)
                {
                    foreach (IProperty property in currentInstance.Properties)
                    {
                        if (property is PropertyObject po)
                        {
                            ObjectReference reference  = po.Value;
                            GameObject      referenced = reference.GetObject(container);
                            if (referenced != null && !MappedObjects.ContainsKey(referenced.Id))
                            {
                                MappedObjects[referenced.Id] = referenced;
                                toVisit.Push(referenced);
                            }
                        }
                        else if (property is PropertyArray pa)
                        {
                            IArkArray <IStruct>         structList          = pa.GetTypedValue <IStruct>();
                            IArkArray <ObjectReference> objectReferenceList = pa.GetTypedValue <ObjectReference>();
                            if (structList != null)
                            {
                                foreach (IStruct aStruct in structList)
                                {
                                    if (aStruct is IPropertyContainer propertyContainer)
                                    {
                                        toVisit.Push(propertyContainer);
                                    }
                                }
                            }
                            else if (objectReferenceList != null)
                            {
                                foreach (ObjectReference reference in objectReferenceList)
                                {
                                    GameObject referenced = reference.GetObject(container);
                                    if (referenced != null && !MappedObjects.ContainsKey(referenced.Id))
                                    {
                                        MappedObjects[referenced.Id] = referenced;
                                        toVisit.Push(referenced);
                                    }
                                }
                            }
                        }
                        else if (property is PropertyStruct ps)
                        {
                            IStruct aStruct = ps.Value;
                            if (aStruct is IPropertyContainer propertyContainer)
                            {
                                toVisit.Push(propertyContainer);
                            }
                        }
                    }
                }

                if (withComponents && currentInstance is GameObject)
                {
                    GameObject gameObject = (GameObject)currentInstance;

                    foreach (GameObject component in gameObject.Components.Values)
                    {
                        if (!MappedObjects.ContainsKey(component.Id))
                        {
                            MappedObjects[component.Id] = component;
                            toVisit.Push(component);
                        }
                    }
                }
            }
        }