Exemplo n.º 1
0
        public ArkContainer(ArkArrayUInt8 source)
        {
            MemoryStream buffer = new MemoryStream(source.ToArray());

            ArkArchive archive = new ArkArchive(buffer);

            ReadBinary(archive, new ReadingOptions());
        }
Exemplo n.º 2
0
        public void ReadBinary(ArkArchive archive, ReadingOptions options)
        {
            readBinaryHeader(archive);

            if (SaveVersion > 5)
            {
                // Name table is located after the objects block, but will be needed to read the objects block
                readBinaryNameTable(archive);
            }

            readBinaryDataFiles(archive, options);
            readBinaryEmbeddedData(archive, options);
            readBinaryDataFilesObjectMap(archive, options);
            readBinaryObjects(archive, options);
            readBinaryObjectProperties(archive, options);

            if (SaveVersion > 6)
            {
                readBinaryHibernation(archive, options);
            }

            // Now parse cryo creature data
            foreach (GameObject cryo in Objects.Where(x => x.ClassName.ToString().Contains("Cryop")).ToList())
            {
                StructPropertyList customData      = cryo.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas")?.FirstOrDefault() as StructPropertyList;
                PropertyStruct     customDataBytes = customData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct;
                PropertyArray      byteArrays      = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray;
                ArkArrayStruct     byteArraysValue = byteArrays?.Value as ArkArrayStruct;
                ArkArrayUInt8      creatureBytes   = ((byteArraysValue?[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8;
                if (creatureBytes == null)
                {
                    continue;
                }

                MemoryStream cryoStream = new MemoryStream(creatureBytes.ToArray <byte>());

                using (ArkArchive cryoArchive = new ArkArchive(cryoStream)) {
                    cryoArchive.ReadBytes(4);
                    GameObject dino         = new GameObject(cryoArchive);
                    GameObject statusObject = new GameObject(cryoArchive);
                    dino.LoadProperties(cryoArchive, new GameObject(), 0);
                    statusObject.LoadProperties(cryoArchive, new GameObject(), 0);
                    dino.IsCryo = true;

                    addObject(dino, true);
                    addObject(statusObject, true);

                    //hack the id's so that the dino points to the appropriate dino status component
                    PropertyObject statusComponentRef = dino.GetTypedProperty <PropertyObject>("MyCharacterStatusComponent");
                    statusComponentRef.Value.ObjectId = statusObject.Id;
                }
            }

            OldNameList    = archive.HasUnknownNames ? archive.NameTable : null;
            HasUnknownData = archive.HasUnknownData;
        }
Exemplo n.º 3
0
        public ArkArrayUInt8 ToByteArray()
        {
            MemoryStream buffer = toBuffer();

            ArkArrayUInt8 result = new ArkArrayUInt8();

            buffer.Position = 0;

            result.AddRange(buffer.ToArray());

            return(result);
        }
Exemplo n.º 4
0
        public void ReadBinary(ArkArchive archive, ReadingOptions options)
        {
            readBinaryHeader(archive);

            if (SaveVersion > 5)
            {
                // Name table is located after the objects block, but will be needed to read the objects block
                readBinaryNameTable(archive);
            }

            readBinaryDataFiles(archive, options);
            readBinaryEmbeddedData(archive, options);
            readBinaryDataFilesObjectMap(archive, options);
            readBinaryObjects(archive, options);
            readBinaryObjectProperties(archive, options);

            if (SaveVersion > 6)
            {
                readBinaryHibernation(archive, options);
            }

            // Parse creatures in cryopods and soultraps (from the mod DinoStorageV2)
            foreach (var cryo in this.Objects.Where(x => x.ClassString.Contains("Cryop") || x.ClassString.Contains("SoulTrap_")).ToList())
            {
                ArkArrayStruct     customItemDatas = cryo.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas");
                StructPropertyList customDinoData  = (StructPropertyList)customItemDatas?.FirstOrDefault(cd => ((StructPropertyList)cd).GetTypedProperty <PropertyName>("CustomDataName").Value.Name == "Dino");
                PropertyStruct     customDataBytes = customDinoData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct;
                PropertyArray      byteArrays      = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray;
                ArkArrayStruct     byteArraysValue = byteArrays?.Value as ArkArrayStruct;
                if (!(byteArraysValue?.Any() ?? false))
                {
                    continue;
                }

                ArkArrayUInt8 creatureBytes = ((byteArraysValue?[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8;
                if (creatureBytes == null)
                {
                    continue;
                }

                var cryoStream = new System.IO.MemoryStream(creatureBytes.ToArray <byte>());

                using (ArkArchive cryoArchive = new ArkArchive(cryoStream))
                {
                    // number of serialized objects
                    int objCount = cryoArchive.ReadInt();
                    if (objCount == 0)
                    {
                        continue;
                    }

                    var storedGameObjects = new List <GameObject>(objCount);
                    for (int oi = 0; oi < objCount; oi++)
                    {
                        storedGameObjects.Add(new GameObject(cryoArchive));
                    }
                    foreach (var ob in storedGameObjects)
                    {
                        ob.LoadProperties(cryoArchive, new GameObject(), 0);
                    }

                    // assume the first object is the creature object
                    string creatureActorId = storedGameObjects[0].Names[0].ToString();
                    storedGameObjects[0].IsCryo = true;

                    // the tribe name is stored in `TamerString`, non-cryoed creatures have the property `TribeName` for that.
                    if (!storedGameObjects[0].HasAnyProperty("TribeName") && storedGameObjects[0].HasAnyProperty("TamerString"))
                    {
                        storedGameObjects[0].Properties.Add(new PropertyString("TribeName", storedGameObjects[0].GetPropertyValue <string>("TamerString")));
                    }

                    // add cryopod object as parent to all child objects of the creature object (ActorIDs are not unique across cryopodded and non-cryopodded creatures)
                    // assume that child objects are stored after their parent objects
                    foreach (var ob in storedGameObjects)
                    {
                        int nIndex = ob.Names.FindIndex(n => n.ToString() == creatureActorId);
                        if (nIndex != -1)
                        {
                            ob.Names.Insert(nIndex + 1, cryo.Names[0]);
                            addObject(ob, true);
                        }
                    }

                    // assign the created ID of the dinoStatusComponent to the creature's property.
                    var statusComponentObject = storedGameObjects.FirstOrDefault(ob => ob.ClassString?.StartsWith("DinoCharacterStatusComponent") ?? false);
                    if (statusComponentObject != null)
                    {
                        var statusComponentRef = storedGameObjects[0].GetTypedProperty <PropertyObject>("MyCharacterStatusComponent");
                        statusComponentRef.Value.ObjectId = statusComponentObject.Id;
                    }
                }
            }

            OldNameList    = archive.HasUnknownNames ? archive.NameTable : null;
            HasUnknownData = archive.HasUnknownData;
        }
Exemplo n.º 5
0
        private void extractBinaryObjectCryopods(ReadingOptions options)
        {
            if (!options.CryopodCreatures)
            {
                return;
            }

            // Parse creatures in cryopods and soultraps (from the mod DinoStorageV2)
            var cryopods = Objects.Where(x => x.ClassString.Contains("Cryop") || x.ClassString.Contains("SoulTrap_")).ToArray();

            foreach (var cryo in cryopods)
            {
                ArkArrayStruct     customItemDatas = cryo.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas");
                StructPropertyList customDinoData  = (StructPropertyList)customItemDatas?.FirstOrDefault(cd => ((StructPropertyList)cd).GetTypedProperty <PropertyName>("CustomDataName").Value.Name == "Dino");
                PropertyStruct     customDataBytes = customDinoData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct;
                PropertyArray      byteArrays      = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray;
                ArkArrayStruct     byteArraysValue = byteArrays?.Value as ArkArrayStruct;
                if (!(byteArraysValue?.Any() ?? false))
                {
                    continue;
                }

                ArkArrayUInt8 creatureBytes = ((byteArraysValue[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8;
                if (creatureBytes == null)
                {
                    continue;
                }

                var cryoStream = new System.IO.MemoryStream(creatureBytes.ToArray <byte>());

                using (ArkArchive cryoArchive = new ArkArchive(cryoStream))
                {
                    // number of serialized objects
                    int objCount = cryoArchive.ReadInt();
                    if (objCount == 0)
                    {
                        continue;
                    }

                    var storedGameObjects = new List <GameObject>(objCount);
                    for (int oi = 0; oi < objCount; oi++)
                    {
                        storedGameObjects.Add(new GameObject(cryoArchive));
                    }
                    foreach (var ob in storedGameObjects)
                    {
                        ob.LoadProperties(cryoArchive, new GameObject(), 0);
                    }

                    // assume the first object is the creature object
                    string creatureActorId = storedGameObjects[0].Names[0].ToString();
                    storedGameObjects[0].IsCryo = true;

                    // the tribe name is stored in `TamerString`, non-cryoed creatures have the property `TribeName` for that.
                    if (!storedGameObjects[0].HasAnyProperty("TribeName") && storedGameObjects[0].HasAnyProperty("TamerString"))
                    {
                        storedGameObjects[0].Properties.Add(new PropertyString("TribeName", storedGameObjects[0].GetPropertyValue <string>("TamerString")));
                    }

                    // add cryopod object as parent to all child objects of the creature object (ActorIDs are not unique across cryopodded and non-cryopodded creatures)
                    // assume that child objects are stored after their parent objects
                    for (int i = 0; i < objCount; i++)
                    {
                        var ob     = storedGameObjects[i];
                        int nIndex = ob.Names.FindIndex(n => n.ToString() == creatureActorId);
                        if (nIndex != -1)
                        {
                            ob.Names.Insert(nIndex + 1, cryo.Names[0]);
                            addObject(ob, false); // processing the names can cause conflicts with reused ids
                        }

                        if (i == 0)
                        {
                            for (int ii = 1; ii < objCount; ii++)
                            {
                                ob.AddComponent(storedGameObjects[ii]);
                            }
                        }
                        else
                        {
                            ob.Parent = storedGameObjects[0];
                        }
                    }

                    // assign the created ID of the components to the creature's properties
                    AssignComponentId("DinoCharacterStatusComponent", "MyCharacterStatusComponent");
                    AssignComponentId("DinoTamedInventoryComponent", "MyInventoryComponent");

                    void AssignComponentId(string classStringStartsWith, string propertyName)
                    {
                        var statusComponentObject = storedGameObjects.FirstOrDefault(ob => ob.ClassString?.StartsWith(classStringStartsWith) ?? false);

                        if (statusComponentObject == null)
                        {
                            return;
                        }
                        var statusComponentRef = storedGameObjects[0].GetTypedProperty <PropertyObject>(propertyName);

                        if (statusComponentRef != null)
                        {
                            statusComponentRef.Value.ObjectId = statusComponentObject.Id;
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        protected override void RunCommand(IEnumerable <string> args)
        {
            List <string> argsList = args.ToList();

            if (showCommandHelp(argsList))
            {
                return;
            }

            string clusterDirectory = argsList[0];
            string outputDirectory  = argsList[1];

            ArkDataManager.LoadData(GlobalOptions.Language);

            List <Action> tasks = GlobalOptions.Parallel ? new List <Action>() : null;

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            foreach (string path in Directory.EnumerateFiles(clusterDirectory))
            {
                Action task = () => {
                    try {
                        ArkCloudInventory cloudInventory = new ArkCloudInventory().ReadBinary <ArkCloudInventory>(path, ReadingOptions.Create());

                        CustomDataContext context = new CustomDataContext {
                            ObjectContainer = cloudInventory
                        };

                        IPropertyContainer arkData = cloudInventory.InventoryData.GetPropertyValue <IPropertyContainer>("MyArkData");

                        CommonFunctions.WriteJson(Path.Combine(outputDirectory, path + ".json"), (generator, writingOptions) => {
                            generator.WriteStartObject();

                            ArkArrayStruct tamedDinosData = arkData.GetPropertyValue <ArkArrayStruct>("ArkTamedDinosData");
                            if (tamedDinosData != null && tamedDinosData.Any())
                            {
                                generator.WriteArrayFieldStart("creatures");
                                foreach (IStruct dinoStruct in tamedDinosData)
                                {
                                    IPropertyContainer dino = (IPropertyContainer)dinoStruct;
                                    ArkContainer container  = null;
                                    if (cloudInventory.InventoryVersion == 1)
                                    {
                                        ArkArrayUInt8 byteData = dino.GetPropertyValue <ArkArrayUInt8>("DinoData");

                                        container = new ArkContainer(byteData);
                                    }
                                    else if (cloudInventory.InventoryVersion == 3)
                                    {
                                        ArkArrayInt8 byteData = dino.GetPropertyValue <ArkArrayInt8>("DinoData");

                                        container = new ArkContainer(byteData);
                                    }

                                    ObjectReference dinoClass = dino.GetPropertyValue <ObjectReference>("DinoClass");
                                    // Skip "BlueprintGeneratedClass " = 24 chars
                                    string dinoClassName = dinoClass.ObjectString.ToString().Substring(24);
                                    generator.WriteStartObject();

                                    generator.WriteField("type",
                                                         ArkDataManager.HasCreatureByPath(dinoClassName) ? ArkDataManager.GetCreatureByPath(dinoClassName).Name : dinoClassName);

                                    // NPE for unknown versions
                                    Creature creature = new Creature(container.Objects[0], container);
                                    generator.WriteObjectFieldStart("data");
                                    creature.writeAllProperties(generator, context, writeAllFields);
                                    generator.WriteEndObject();

                                    generator.WriteEndObject();
                                }

                                generator.WriteEndArray();
                            }

                            ArkArrayStruct arkItems = arkData.GetPropertyValue <ArkArrayStruct>("ArkItems");
                            if (arkItems != null)
                            {
                                List <Item> items = new List <Item>();
                                foreach (IStruct itemStruct in arkItems)
                                {
                                    IPropertyContainer item    = (IPropertyContainer)itemStruct;
                                    IPropertyContainer netItem = item.GetPropertyValue <IPropertyContainer>("ArkTributeItem");

                                    items.Add(new Item(netItem));
                                }

                                if (items.Any())
                                {
                                    generator.WritePropertyName("items");
                                    Inventory.writeInventoryLong(generator, context, items, writeAllFields);
                                }
                            }

                            generator.WriteEndObject();
                        }, writingOptions);
                    } catch (Exception ex) {
                        Console.Error.WriteLine("Found potentially corrupt cluster data: " + path);
                        if (GlobalOptions.Verbose)
                        {
                            Console.Error.WriteLine(ex.Message);
                            Console.Error.WriteLine(ex.StackTrace);
                        }
                    }
                };

                if (tasks != null)
                {
                    tasks.Add(task);
                }
                else
                {
                    task();
                }
            }

            if (tasks != null)
            {
                Parallel.ForEach(tasks, task => task());
            }

            stopwatch.Stop("Loading cluster data and writing info");
            stopwatch.Print();
        }