ArkFile
Cette documentation est destinée à tous ceux qui souhaitent apprendre ou lire directement le fichier de sauvegarde de Ark.
Ce fichier est un fichier binaire généré par la fonction Save World de l'UE4, la première partie est un "Ark File Header" qui contient des informations importantes sur le fichier, après cela, nous devons lire quelque chose appelé la table des noms qui contient une table de base qui sera l'épine dorsale de notre lecture du fichier.
Pour comprendre tout cela, vous avez besoin d'une connaissance de base des fichiers binaires, du C++, et de la représentation numérique sur un fichier (Float, Int32, UInt32, etc)
Nous allons nous concentrer sur la description du fichier de sauvegarde version 9, il y a des fichiers de sauvegarde ark de la version 5 mais ce n'est pas bien documenté.
Le flux de base pour lire les données du fichier de sauvegarde Ark est le suivant:
- Lire l'Objet d'en-tête de fichier Ark
- Lire l'Objet de noms de données binaires
- Lire l'Objet de table de nom
- Lire l'Objet intégré des données binaires
- Lire l'Objet de données inconnu
- Lire le Tableau d'objets de jeu
- Pour chacun des Objets de jeu lire l'Objet Propriétés
Objet d'en-tête de fichier Ark
C'est le début du fichier de sauvegarde .ark, qui est un en-tête contenant des informations importantes.
Nom | Type | Longueur | Description |
---|---|---|---|
⬤ Version de sauvegarde | Int16 | 2 Octets | Le numéro de version du fichier de sauvegarde, sur cette documentation nous décrivons la version 09 |
⬤ Décalage des données binaires | Int32 | 4 Octets | Il s'agit du décalage de fichier dans lequel les données binaires intégrées commencent |
⬤ Inconu | Int32 | 4 Octets | Cela semble être des données inutilisées (tous les tests lisent 0) |
⬤ Décalage de la table de noms | Int32 | 4 Octets | Il s'agit du décalage de fichier dans lequel les données de la table de noms commencent |
⬤ Décalage du bloc de propriétés | Int32 | 4 Octets | Il s'agit du décalage de fichier dans lequel les propriétés sont stockées |
⬤ Temps en jeu | Float | 4 Octets | Cette section stocke le temps en jeu |
⬤ Nombre de sauvegardes | Int32 | 4 Octets | Cette section stocke le nombre de fois où le fichier de sauvegarde a été enregistré |
Objet de noms de données binaires
Pour lire ce tableau, vous devez lire les données String dans l'objet autant de fois qu'elles ont été spécifiées sur la longueur du tableau.
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur du tableau | Int32 | 2 Octets | Cela nous dit combien de Strings sont contenus dans ce tableau |
Données de chaîne | String | Octets inconnus | La taille de ces objets est inconnue car les données sont lues à la volée |
Objet de table de nom
Ce tableau est crucial pour continuer à lire le reste du fichier de sauvegarde car il contient de nombreuses références nécessaires pour pouvoir comprendre le fichier de sauvegarde.
Pour lire ce tableau, vous devez déplacer votre curseur de lecture sur le fichier vers le décalage de la table des noms obtenu à partir de l'Objet d'en-tête de fichier Ark, n'oubliez pas de sauvegarder la position actuelle du curseur car vous devez revenir à cette position une fois que vous avez fini de lire ces données.
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur du tableau | Int32 | 4 Octets | Cela nous dit combien de Strings sont contenus dans ce tableau |
Données de chaîne | String | Octets inconnus | La taille de ces objets est inconnue car les données sont lues à la volée |
Objet intégré des données binaires
L'utilisation de ces données est inconnue, nous allons lire un tableau de tableaux, contenant des nombres Int32. Nous allons d'abord lire la longueur du tableau et faire une boucle plusieurs fois, sur chacune de ces boucles, nous allons:
Lisez les 4 octets suivants comme Int32 et faites une boucle en lisant à chaque fois une autre valeur Int32 dans le sous-tableau.
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur du tableau | Int32 | 4 Octets | Cela nous indique combien de tableaux sont contenus dans ce tableau |
Longueur du sous-tableau | Int32 | 4 Octets | Cela nous dit combien de Strings sont contenus dans ce tableau |
Données Int32 | Int32 | Longueur du sous-tableau * 4 octets | Numéros Int32 sur le tableau |
Objet de données inconnu
Il s'agit d'un objet de données inconnu, nous devons le lire correctement au cas où Ark l'utiliserait à un moment donné
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur du tableau | Int32 | 4 Octets | Cela nous indique combien de tableaux sont contenus dans ce tableau |
Numéro inconnu | Int32 | 4 Octets | Il s'agit d'un nombre inconnu qui semble être une sorte d'indicateur |
Nombre d'objets inconnus | Int32 | 4 Octets | Il s'agit d'un nombre inconnu qui semble nous indiquer un nombre d'objets |
Données de chaîne | String | Octets inconnus | Certaines données de chaîne inconnues |
Tableau d'objets de jeu
C'est l'objet principal qui contient tous les objets du jeu
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur du tableau | Int32 | 4 Octets | Cela nous indique combien d'Objets de jeu sont contenus dans ce tableau |
Objets de jeu | Objets de jeu | Octets inconnus | Il s'agit d'un Objet de jeu qui doit être lu en conséquence. |
Objets de jeu
Nom | Type | Longueur | Description |
---|---|---|---|
GUID | UInt128 | 16 Octets | Le GUID de l'objet, Cela ne semble pas être unique |
Nom de la classe | Objet de classe Ark | 8 Octets | Le nom de classe de l'objet |
Élément | Objet booléen | 4 Octets | Cela définit si l'objet est un élément |
Longueur du tableau Noms de classe | Int32 | 4 Octets | La quantité d'Objets de classe Ark contenue dans ce tableau |
Nom de la classe | Objets de classe Ark | 8 Octets | Ces données se répètent le montant spécifié dans Longueur du tableau Noms de classe |
À partir du fichier de données | Objet booléen | 4 Octets | Un booléen qui indique s'il provient d'un fichier de données (signification inconnue) |
Index des fichiers de données | Int32 | 4 Octets | L'index du fichier de données (signification inconnue) |
Données de localisation disponibles | Objet booléen | 4 Octets | Cela spécifie s'il y a des données de localisation disponibles, seulement si cela est vrai, les 24 octets suivants existent, sinon les informations n'existent pas et doivent être ignorées |
Données de position | Objet de données de localisation | 24 Octets | Ces données ne sont disponibles que si Données de localisation disponibles était vraie, sinon nous devrions sauter la lecture de ces 24 octets. |
Décalage des propriétés | Int32 | 4 Octets | Cela nous indique le décalage des propriétés sur lequel commencer la lecture des propriétés de l'objet. |
Nombre entier inconnu | Int32 | 4 Octets | Entier inconnu qui semble toujours être 0 (il peut s'agir simplement d'un NUL de 4 octets) |
Objet Propriétés
C'est l'une des parties les plus "amusantes" pour lire des données. Pour créer cet objet, nous le remplirons avec un tableau des objets que nous lisons dans le fichier, nous devons d'abord additionner le Décalage du bloc de propriétés de l'objet d'en-tête de fichier Ark avec le Décalage des propriétés de l'objet de jeu et commencez à lire à partir de là, jusqu'à ce que nous atteignions un nom de classe nommé "Aucun"
Nom | Type | Longueur | Description |
---|---|---|---|
Nom de la classe | Objet de classe Ark | 8 Octets | Nom de classe de la propriété si le résultat est "Aucun", nous devons arrêter la lecture à la fin de cette propriété. |
Contenu des propriétés | Objet de propriété | Octets inconnus | Si le nom de la classe précédente n'était pas "Aucun", nous commençons à lire le contenu de la propriété en conséquence |
Nombre entier inconnu | Int32 | 4 Octets | Entier inconnu qui semble toujours être 0 (il peut s'agir simplement d'un NUL de 4 octets) |
Données supplémentaires | Objet de données supplémentaire | Octets inconnus | Parfois, il y a des données supplémentaires à la fin des propriétés, vous devez enregistrer ces données car elles peuvent contenir des informations importantes. |
Objet de propriété
Après avoir lu le nom de classe de la propriété, vous devez lire les données en fonction de sa classification:
Objet de BooleanProperty
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Propriété booléenne | 1 Octet | La valeur booléenne |
Objet ByteProperty
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire, assez drôle cela ne nous indique parfois pas la taille exacte des octets à lire. |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | UInt8 ou Objet de classe Ark ou Octets bruts | 1, 8 ou octets inconnus | Si la longueur est 1, lire comme UInt8, Si la longueur est égale à 8, alors lire comme un Objet de classe Ark suivi d'une valeur d'un autre Objet de classe Ark, Si la longueur est différente, lisez comme octets bruts. |
Objet FloatProperty
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Float | 4 Octets | La valeur du Float |
Objet DoubleProperty
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Double | 8 Octets | La valeur du Double |
Objet IntProperty
Ceci est lu de la même manière que Objet Int32Property
Objet Int8Property
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Int8 | 1 Octet | La valeur Int8 signée |
Objet UInt8Property
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | UInt8 | 1 Octet | La valeur UInt8 non signée |
Objet Int16Property
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Int16 | 2 Octets | La valeur Int16 signée |
Objet UInt16Property
Name | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | UInt16 | 2 Octets | La valeur UInt16 non signée |
Objet Int32Property
Name | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Int32 | 4 Octets | La valeur Int32 signée |
Objet UInt32Property
Name | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | UInt32 | 4 Octets | La valeur UInt32 non signée |
Objet Int64Property
Name | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Int64 | 8 Octets | La valeur Int64 signée |
Objet UInt64Property
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | UInt64 | 8 Octets | La valeur UInt64 non signée |
Objet NameProperty
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
Valeur | Objet de classe Ark | 8 Octets | L'objet de nom de classe Ark |
Objet ObjectProperty
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur | Int32 | 4 Octets | Longueur en octets des données à lire |
Index | Int32 | 4 Octets | Index des données lues (utilisé sur certaines propriétés qui se répètent plusieurs fois) |
ID | Int32 | 4 Octets | Ceci est un identifiant quelconque (utilisation inconnue) |
Valeur | Int32 ou Objet de classe Ark | 4 ou 8 Octets | Si la longueur est de 8, alors lisez la valeur Int32, si elle est de 12, lisez Ark Class Object comme valeur |
Objet StructProperty
Objet ArrayProperty
Objet PropertyText
Objet StrProperty
Objet de classe Ark
Lors de la lecture d'un objet de classe Ark, vous devez toujours lire 8 octets, et lorsqu'un index est défini (plus de 0), vous devez ajouter cet index au nom de la classe, donc si vous avez votre Objet de table de nom et en position #72, vous avez PrimalItem_WeaponEmptyCryopod_C (Remarque: Il n'y a pas de position 0 sur Objet de table de nom) cela signifie que si votre index = 1, vous devez ajouter _0 à la fin, ce qui en fait PrimalItem_WeaponEmptyCryopod_C_0 et si votre index = 135, vous devez ajouter _134.
Nom | Type | Longueur | Description |
---|---|---|---|
ID | Int32 | 4 Octets | L'ID correspondant sur l'Objet de table de nom |
Index | Int32 | 4 Octets | L'index de ce nom, le jeu prend les noms et les représente avec un _INDEX à la fin, si ce nombre est 0 on n'ajoute pas de _0 au nom, on laisse le nom d'origine tel quel, si on trouve un 1 ou plus dans cette valeur, nous devons commencer à compter à partir de 0, ce qui signifie que Index = 1 est Append = _0 |
Types de données
Voici les types de données et comment les lire en conséquence.
String
Nom | Type | Longueur | Description |
---|---|---|---|
Longueur de chaine | Int32 | 4 Octets | Cela nous indique le nombre d'octets à lire |
Données de chaîne | String | Octets de longueur de chaîne | Lisez ces données sous forme de chaîne, gardez à l'esprit que le dernier caractère sera un caractère 0x00 NUL. |
Bool
Lecture de 32 bits (4 octets) dans laquelle le bit le moins significatif indique vrai
Double
Lire un nombre double de 64 bits (8 octets)
Float
Lire un nombre flottant de 32 bits (4 octets)
Int8
Lire un entier signé 8 bits (1 octet)
UInt8
Lire un entier non signé 8 bits (1 octet)
Int16
Lire un entier signé 16 bits (2 octets)
UInt16
Lire un entier non signé 16 bits (2 octets)
Int32
Lire un entier signé 32 bits (4 octets)
UInt32
Lire un entier non signé 32 bits (4 octets)
Int64
Lire un entier signé 64 bits (8 octets)
UInt64
Lire un entier non signé 64 bits (8 octets)
PropertyBoolean
Lire 8 bits (1 octet) dans lequel le bit le moins significatif indique vrai