private void writeBinaryHibernation(ArkArchive archive)
        {
            archive.Position = hibernationOffset;
            if (SaveVersion > 7)
            {
                archive.WriteInt(hibernationV8Unknown1);
                archive.WriteInt(hibernationV8Unknown2);
                archive.WriteInt(hibernationV8Unknown3);
                archive.WriteInt(hibernationV8Unknown4);
            }

            if (!HibernationEntries.Any())
            {
                return;
            }

            archive.WriteInt(hibernationUnknown1);
            archive.WriteInt(hibernationUnknown2);

            archive.WriteInt(hibernationClasses.Count);
            hibernationClasses.ForEach(archive.WriteString);

            archive.WriteInt(hibernationIndices.Count);
            hibernationIndices.ForEach(archive.WriteInt);

            archive.WriteInt(HibernationEntries.Count);
            foreach (HibernationEntry hibernationEntry in HibernationEntries)
            {
                hibernationEntry.WriteBinary(archive);
            }
        }
        private void readJsonHibernatedObjects(JToken node, ReadingOptions options)
        {
            hibernationClasses.Clear();
            hibernationIndices.Clear();
            HibernationEntries.Clear();
            JObject hibernation = node.Value <JObject>("hibernation");

            if (options.Hibernation && hibernation != null && hibernation.Type != JTokenType.Null)
            {
                hibernationV8Unknown1 = hibernation.Value <int>("v8Unknown1");
                hibernationV8Unknown2 = hibernation.Value <int>("v8Unknown2");
                hibernationV8Unknown3 = hibernation.Value <int>("v8Unknown3");
                hibernationV8Unknown4 = hibernation.Value <int>("v8Unknown4");
                hibernationUnknown1   = hibernation.Value <int>("unknown1");
                hibernationUnknown2   = hibernation.Value <int>("unknown2");

                JArray classesArray = hibernation.Value <JArray>("classes");
                if (classesArray != null)
                {
                    foreach (JToken clazz in classesArray)
                    {
                        hibernationClasses.Add(clazz.Value <string>());
                    }
                }

                JArray indicesArray = hibernation.Value <JArray>("indices");
                if (indicesArray != null)
                {
                    foreach (JToken index in indicesArray)
                    {
                        hibernationIndices.Add(index.Value <int>());
                    }
                }

                JArray entriesArray = hibernation.Value <JArray>("entries");
                if (entriesArray != null)
                {
                    foreach (JToken hibernatedObject in entriesArray)
                    {
                        HibernationEntries.Add(new HibernationEntry(hibernatedObject, options));
                    }
                }
            }
            else
            {
                hibernationV8Unknown1 = 0;
                hibernationV8Unknown2 = 0;
                hibernationV8Unknown3 = 0;
                hibernationV8Unknown4 = 0;
                hibernationUnknown1   = 0;
                hibernationUnknown2   = 0;
            }
        }
        private int calculateHibernationSize()
        {
            int size = SaveVersion > 7 ? sizeof(int) * 4 : 0;

            if (HibernationEntries.Count <= 0)
            {
                return(size);
            }

            size += sizeof(int) * (5 + hibernationIndices.Count);
            size += hibernationClasses.Sum(ArkArchive.GetStringLength);
            size += HibernationEntries.Sum(hibernationEntry => hibernationEntry.GetSizeAndCollectNames());
            return(size);
        }
        /// <inheritdoc />
        /// <summary>
        /// Writes this class as json using <code>generator</code>.
        /// This method is valid only in an array context or in no context (see <see cref="M:Newtonsoft.Json.JsonTextWriter.WriteStartObject" />.
        /// Requires the current objects list to be correctly sorted, otherwise the written
        /// <see cref="T:SavegameToolkit.Types.ObjectReference" /> might be broken.
        /// </summary>
        /// <param name="writer"><see cref="T:Newtonsoft.Json.JsonTextWriter" /> to write with</param>
        /// <param name="writingOptions"></param>
        public void WriteJson(JsonTextWriter writer, WritingOptions writingOptions)
        {
            writer.WriteStartObject();

            writer.WriteField("saveVersion", SaveVersion);
            writer.WriteField("gameTime", GameTime);

            writer.WriteField("saveCount", SaveCount);

            if (!writingOptions.Compact && OldNameList != null && OldNameList.Any())
            {
                writer.WriteArrayFieldStart("preservedNames");

                foreach (string oldName in OldNameList)
                {
                    writer.WriteValue(oldName);
                }

                writer.WriteEndArray();
            }

            if (!writingOptions.Compact && DataFiles.Any())
            {
                writer.WriteArrayFieldStart("dataFiles");

                foreach (string dataFile in DataFiles)
                {
                    writer.WriteValue(dataFile);
                }

                writer.WriteEndArray();
            }

            if (!writingOptions.Compact && EmbeddedData.Any())
            {
                writer.WriteArrayFieldStart("embeddedData");

                foreach (EmbeddedData data in EmbeddedData)
                {
                    data.WriteJson(writer);
                }

                writer.WriteEndArray();
            }

            if (DataFilesObjectMap.Any())
            {
                writer.WriteObjectFieldStart("dataFilesObjectMap");

                foreach (KeyValuePair <int, List <string[]> > entry in DataFilesObjectMap)
                {
                    writer.WriteArrayFieldStart(entry.Key.ToString());
                    foreach (string[] namesList in entry.Value)
                    {
                        writer.WriteStartArray();
                        foreach (string name in namesList)
                        {
                            writer.WriteValue(name);
                        }

                        writer.WriteEndArray();
                    }

                    writer.WriteEndArray();
                }

                writer.WriteEndObject();
            }

            if (Objects.Any())
            {
                writer.WriteArrayFieldStart("objects");

                foreach (GameObject gameObject in Objects)
                {
                    gameObject.WriteJson(writer, writingOptions);
                }

                writer.WriteEndArray();
            }

            writer.WriteObjectFieldStart("hibernation");

            if (!writingOptions.Compact)
            {
                writer.WriteField("v8Unknown1", hibernationV8Unknown1);
                writer.WriteField("v8Unknown2", hibernationV8Unknown2);
                writer.WriteField("v8Unknown3", hibernationV8Unknown3);
                writer.WriteField("v8Unknown4", hibernationV8Unknown4);

                writer.WriteField("unknown1", hibernationUnknown1);
                writer.WriteField("unknown2", hibernationUnknown2);
            }

            if (!writingOptions.Compact && hibernationClasses.Any())
            {
                writer.WriteArrayFieldStart("classes");

                foreach (string hibernationClass in hibernationClasses)
                {
                    writer.WriteValue(hibernationClass);
                }

                writer.WriteEndArray();
            }

            if (!writingOptions.Compact && hibernationIndices.Any())
            {
                writer.WriteArrayFieldStart("indices");

                foreach (int hibernationIndex in hibernationIndices)
                {
                    writer.WriteValue(hibernationIndex);
                }

                writer.WriteEndArray();
            }

            if (HibernationEntries.Any())
            {
                writer.WriteArrayFieldStart("entries");

                foreach (HibernationEntry hibernationEntry in HibernationEntries)
                {
                    hibernationEntry.WriteJson(writer, writingOptions);
                }

                writer.WriteEndArray();
            }

            writer.WriteEndObject();

            writer.WriteEndObject();
        }
        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));
            }
        }