private void readBinary(ArkArchive archive, ReadingOptions options)
        {
            X        = archive.ReadFloat();
            Y        = archive.ReadFloat();
            Z        = archive.ReadFloat();
            UnkByte  = archive.ReadByte();
            UnkFloat = archive.ReadFloat();

            if (options.HibernationObjectProperties)
            {
                ArkArchive nameArchive = archive.Slice(archive.ReadInt());
                readBinaryNameTable(nameArchive);
            }
            else
            {
                archive.SkipBytes(archive.ReadInt());
                nameTable = null;

                // Unknown data since the missed names are unrelated to the main nameTable
                archive.HasUnknownData = true;
            }

            ArkArchive objectArchive = archive.Slice(archive.ReadInt());

            readBinaryObjects(objectArchive, options);

            UnkInt1    = archive.ReadInt();
            ClassIndex = archive.ReadInt();
        }
        private void readBinaryNameTable(ArkArchive archive)
        {
            int version = archive.ReadInt();

            if (version != 3)
            {
                archive.DebugMessage($"Found unknown Version {version}", -4);
                throw new NotSupportedException();
            }

            int count = archive.ReadInt();

            nameTable = new List <string>(count);

            for (int index = 0; index < count; index++)
            {
                nameTable.Add(archive.ReadString());
            }

            int zoneCount = archive.ReadInt();

            for (int index = 0; index < zoneCount; index++)
            {
                ZoneVolumes.Add(archive.ReadName());
            }
        }
Exemplo n.º 3
0
        public void ReadBinary(ArkArchive archive, ReadingOptions options)
        {
            TribeVersion = archive.ReadInt();

            if (TribeVersion != 1)
            {
                throw new NotSupportedException("Unknown Tribe Version " + TribeVersion);
            }

            int tribesCount = archive.ReadInt();

            Objects.Clear();
            ObjectMap.Clear();
            for (int i = 0; i < tribesCount; i++)
            {
                addObject(new GameObject(archive), options.BuildComponentTree);
            }

            for (int i = 0; i < tribesCount; i++)
            {
                GameObject gameObject = Objects[i];
                if (gameObject.ClassString == "PrimalTribeData")
                {
                    Tribe = gameObject;
                }

                gameObject.LoadProperties(archive, i < tribesCount - 1 ? Objects[i + 1] : null, 0);
            }
        }
Exemplo n.º 4
0
        private void readBinaryDataFilesObjectMap(ArkArchive archive, ReadingOptions options)
        {
            DataFilesObjectMap.Clear();
            if (options.DataFilesObjectMap)
            {
                int dataFilesCount = archive.ReadInt();
                for (int n = 0; n < dataFilesCount; n++)
                {
                    int      level = archive.ReadInt();
                    int      count = archive.ReadInt();
                    string[] names = new string[count];
                    for (int index = 0; index < count; index++)
                    {
                        names[index] = archive.ReadString();
                    }

                    if (!DataFilesObjectMap.ContainsKey(level) || DataFilesObjectMap[level] == null)
                    {
                        DataFilesObjectMap.Add(level, new List <string[]> {
                            names
                        });
                    }
                }
            }
            else
            {
                archive.HasUnknownData = true;
                int count = archive.ReadInt();
                for (int entry = 0; entry < count; entry++)
                {
                    archive.SkipBytes(4);
                    int stringCount = archive.ReadInt();
                    for (int stringIndex = 0; stringIndex < stringCount; stringIndex++)
                    {
                        archive.SkipString();
                    }
                }
            }
        }
Exemplo n.º 5
0
        private void readBinaryHeader(ArkArchive archive)
        {
            SaveVersion = archive.ReadShort();

            if (SaveVersion < 5 || SaveVersion > 9)
            {
                throw new NotSupportedException("Found unknown Version " + SaveVersion);
            }

            if (SaveVersion > 6)
            {
                hibernationOffset = archive.ReadInt();
                int shouldBeZero = archive.ReadInt();
                if (shouldBeZero != 0)
                {
                    throw new NotSupportedException("The stuff at this position should be zero: " + (archive.Position - 4).ToString("X4"));
                }
            }
            else
            {
                hibernationOffset = 0;
            }

            if (SaveVersion > 5)
            {
                nameTableOffset       = archive.ReadInt();
                propertiesBlockOffset = archive.ReadInt();
            }
            else
            {
                nameTableOffset       = 0;
                propertiesBlockOffset = 0;
            }

            GameTime = archive.ReadFloat();

            SaveCount = SaveVersion > 8 ? archive.ReadInt() : 0;
        }
Exemplo n.º 6
0
        public void ReadBinary(ArkArchive archive, ReadingOptions options)
        {
            int objectCount = archive.ReadInt();

            Objects.Clear();
            ObjectMap.Clear();
            for (int i = 0; i < objectCount; i++)
            {
                addObject(new GameObject(archive), options.BuildComponentTree);
            }

            for (int i = 0; i < objectCount; i++)
            {
                Objects[i].LoadProperties(archive, i < objectCount - 1 ? Objects[i + 1] : null, 0);
            }
        }
Exemplo n.º 7
0
        private void readBinaryNameTable(ArkArchive archive)
        {
            long position = archive.Position;

            archive.Position = nameTableOffset;

            int           nameCount = archive.ReadInt();
            List <string> nameTable = new List <string>(nameCount);

            for (int n = 0; n < nameCount; n++)
            {
                nameTable.Add(archive.ReadString());
            }

            archive.SetNameTable(nameTable);

            archive.Position = position;
        }
Exemplo n.º 8
0
        private void readBinaryObjects(ArkArchive archive, ReadingOptions options)
        {
            if (options.GameObjects)
            {
                int count = archive.ReadInt();

                Objects.Clear();
                ObjectMap.Clear();
                for (int n = 0; n < count; n++)
                {
                    addObject(new GameObject(archive), options.BuildComponentTree);
                }
            }
            else
            {
                archive.HasUnknownData  = true;
                archive.HasUnknownNames = true;
            }
        }
Exemplo n.º 9
0
        private void readBinaryEmbeddedData(ArkArchive archive, ReadingOptions options)
        {
            int count = archive.ReadInt();

            EmbeddedData.Clear();
            if (options.EmbeddedData)
            {
                for (int n = 0; n < count; n++)
                {
                    EmbeddedData.Add(new EmbeddedData(archive));
                }
            }
            else
            {
                archive.HasUnknownData = true;
                for (int n = 0; n < count; n++)
                {
                    Types.EmbeddedData.Skip(archive);
                }
            }
        }
Exemplo n.º 10
0
        private void readBinaryDataFiles(ArkArchive archive, ReadingOptions options)
        {
            int count = archive.ReadInt();

            DataFiles.Clear();
            if (options.DataFiles)
            {
                for (int n = 0; n < count; n++)
                {
                    DataFiles.Add(archive.ReadString());
                }
            }
            else
            {
                archive.HasUnknownData = true;
                for (int n = 0; n < count; n++)
                {
                    archive.SkipString();
                }
            }
        }
        private void readBinaryObjects(ArkArchive archive, ReadingOptions options)
        {
            int count = archive.ReadInt();

            Objects.Clear();
            Objects.Capacity = count;
            ObjectMap.Clear();
            for (int index = 0; index < count; index++)
            {
                addObject(new GameObject(archive), options.BuildComponentTree);
            }

            if (nameTable == null)
            {
                return;
            }
            archive.SetNameTable(nameTable, 0, true);

            for (int index = 0; index < count; index++)
            {
                Objects[index].LoadProperties(archive, index + 1 < count ? Objects[index + 1] : null, 0);
            }
        }
Exemplo n.º 12
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.º 13
0
        private void readBinaryHibernation(ArkArchive archive, ReadingOptions options)
        {
            if (!options.Hibernation)
            {
                hibernationV8Unknown1 = 0;
                hibernationV8Unknown2 = 0;
                hibernationV8Unknown3 = 0;
                hibernationV8Unknown4 = 0;
                hibernationUnknown1   = 0;
                hibernationUnknown2   = 0;
                hibernationClasses.Clear();
                hibernationIndices.Clear();
                HibernationEntries.Clear();
                archive.HasUnknownData = true;
                return;
            }

            archive.Position = hibernationOffset;

            if (SaveVersion > 7)
            {
                hibernationV8Unknown1 = archive.ReadInt();
                hibernationV8Unknown2 = archive.ReadInt();
                hibernationV8Unknown3 = archive.ReadInt();
                hibernationV8Unknown4 = archive.ReadInt();
            }

            // No hibernate section if we reached the nameTable
            if (archive.Position == nameTableOffset)
            {
                return;
            }

            hibernationUnknown1 = archive.ReadInt();
            hibernationUnknown2 = archive.ReadInt();

            int hibernatedClassesCount = archive.ReadInt();

            hibernationClasses.Clear();
            hibernationClasses.Capacity = hibernatedClassesCount;
            for (int index = 0; index < hibernatedClassesCount; index++)
            {
                hibernationClasses.Add(archive.ReadString());
            }

            int hibernatedIndicesCount = archive.ReadInt();

            if (hibernatedIndicesCount != hibernatedClassesCount)
            {
                archive.DebugMessage("hibernatedClassesCount does not match hibernatedIndicesCount");
                throw new NotSupportedException();
            }

            hibernationIndices.Clear();
            hibernationIndices.Capacity = hibernatedIndicesCount;
            for (int index = 0; index < hibernatedIndicesCount; index++)
            {
                hibernationIndices.Add(archive.ReadInt());
            }

            int hibernatedObjectsCount = archive.ReadInt();

            HibernationEntries.Clear();
            HibernationEntries.Capacity = hibernatedObjectsCount;
            for (int index = 0; index < hibernatedObjectsCount; index++)
            {
                HibernationEntries.Add(new HibernationEntry(archive, options));
            }
        }
Exemplo n.º 14
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;
                        }
                    }
                }
            }
        }