diff --git a/pom.xml b/pom.xml
index a91c636..2eb87ad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
qowyn.ark
ark-savegame-toolkit
- 0.8.0
+ 0.8.1
jar
ARK Savegame Toolkit
diff --git a/src/main/java/qowyn/ark/ArkCloudInventory.java b/src/main/java/qowyn/ark/ArkCloudInventory.java
index 8b1d60e..ae5ae4c 100644
--- a/src/main/java/qowyn/ark/ArkCloudInventory.java
+++ b/src/main/java/qowyn/ark/ArkCloudInventory.java
@@ -7,19 +7,24 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import qowyn.ark.properties.Property;
+import qowyn.ark.types.ArkName;
-public class ArkCloudInventory extends FileFormatBase implements PropertyContainer, GameObjectContainer {
+public class ArkCloudInventory extends FileFormatBase implements PropertyContainer, GameObjectContainerMixin {
private int inventoryVersion;
private final ArrayList objects = new ArrayList<>();
+ private final Map, GameObject>> objectMap = new HashMap<>();
+
private GameObject inventoryData;
public ArkCloudInventory() {}
@@ -50,8 +55,10 @@ public void readBinary(ArkArchive archive, ReadingOptions options) {
int objectCount = archive.getInt();
+ objects.clear();
+ objectMap.clear();
for (int i = 0; i < objectCount; i++) {
- objects.add(new GameObject(archive));
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
for (int i = 0; i < objectCount; i++) {
@@ -112,15 +119,17 @@ public void writeBinary(Path filePath, WritingOptions options) throws FileNotFou
@Override
public void readJson(JsonNode node, ReadingOptions options) {
inventoryVersion = node.path("inventoryVersion").asInt();
- objects.clear();
+ objects.clear();
+ objectMap.clear();
if (node.hasNonNull("inventoryData")) {
- setInventoryData(new GameObject(node.get("inventoryData")));
+ addObject(new GameObject(node.get("inventoryData")), options.getBuildComponentTree());
+ inventoryData = objects.get(0);
}
if (node.hasNonNull("objects")) {
- for (JsonNode profileObject : node.get("objects")) {
- objects.add(new GameObject(profileObject));
+ for (JsonNode objectNode : node.get("objects")) {
+ addObject(new GameObject(objectNode), options.getBuildComponentTree());
}
}
}
@@ -162,10 +171,16 @@ public void setInventoryVersion(int inventoryVersion) {
this.inventoryVersion = inventoryVersion;
}
+ @Override
public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
public GameObject getInventoryData() {
return inventoryData;
}
diff --git a/src/main/java/qowyn/ark/ArkContainer.java b/src/main/java/qowyn/ark/ArkContainer.java
index ed085f3..46ba40e 100644
--- a/src/main/java/qowyn/ark/ArkContainer.java
+++ b/src/main/java/qowyn/ark/ArkContainer.java
@@ -7,17 +7,23 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import qowyn.ark.arrays.ArkArrayInt8;
import qowyn.ark.arrays.ArkArrayUInt8;
+import qowyn.ark.types.ArkName;
-public class ArkContainer extends FileFormatBase implements GameObjectContainer {
+public class ArkContainer extends FileFormatBase implements GameObjectContainerMixin {
private final ArrayList objects = new ArrayList<>();
+ private final Map, GameObject>> objectMap = new HashMap<>();
+
public ArkContainer() {}
public ArkContainer(Path filePath) throws IOException {
@@ -62,8 +68,10 @@ public ArkContainer(ArkArrayInt8 source) {
public void readBinary(ArkArchive archive, ReadingOptions options) {
int objectCount = archive.getInt();
+ objects.clear();
+ objectMap.clear();
for (int i = 0; i < objectCount; i++) {
- objects.add(new GameObject(archive));
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
for (int i = 0; i < objectCount; i++) {
@@ -118,20 +126,17 @@ public void writeBinary(Path filePath, WritingOptions options) throws FileNotFou
@Override
public void readJson(JsonNode node, ReadingOptions options) {
- objects.clear();
+ objects.clear();
+ objectMap.clear();
if (node.isArray()) {
- int id = 0;
for (JsonNode jsonObject : node) {
- objects.add(new GameObject(jsonObject));
- objects.get(id).setId(id++); // Set id and increase afterwards
+ addObject(new GameObject(jsonObject), options.getBuildComponentTree());
}
} else {
if (node.hasNonNull("objects")) {
- int id = 0;
for (JsonNode jsonObject : node.get("objects")) {
- objects.add(new GameObject(jsonObject));
- objects.get(id).setId(id++); // Set id and increase afterwards
+ addObject(new GameObject(jsonObject), options.getBuildComponentTree());
}
}
}
@@ -148,10 +153,16 @@ public void writeJson(JsonGenerator generator, WritingOptions options) throws IO
generator.writeEndArray();
}
+ @Override
public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
private ByteBuffer toBuffer() {
int size = Integer.BYTES;
diff --git a/src/main/java/qowyn/ark/ArkLocalProfile.java b/src/main/java/qowyn/ark/ArkLocalProfile.java
index bc472d0..01ed57b 100644
--- a/src/main/java/qowyn/ark/ArkLocalProfile.java
+++ b/src/main/java/qowyn/ark/ArkLocalProfile.java
@@ -7,14 +7,17 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import qowyn.ark.properties.Property;
+import qowyn.ark.types.ArkName;
-public class ArkLocalProfile extends FileFormatBase implements PropertyContainer, GameObjectContainer {
+public class ArkLocalProfile extends FileFormatBase implements PropertyContainer, GameObjectContainerMixin {
private static final int UNKNOWN_DATA_2_SIZE = 0xc;
@@ -26,6 +29,8 @@ public class ArkLocalProfile extends FileFormatBase implements PropertyContainer
private final ArrayList objects = new ArrayList<>();
+ private final Map, GameObject>> objectMap = new HashMap<>();
+
private GameObject localProfile;
public ArkLocalProfile() {}
@@ -66,8 +71,10 @@ public void readBinary(ArkArchive archive, ReadingOptions options) {
int objectCount = archive.getInt();
+ objects.clear();
+ objectMap.clear();
for (int i = 0; i < objectCount; i++) {
- objects.add(new GameObject(archive));
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
for (int i = 0; i < objectCount; i++) {
@@ -160,15 +167,17 @@ public void writeBinary(Path filePath, WritingOptions options) throws FileNotFou
@Override
public void readJson(JsonNode node, ReadingOptions options) {
localProfileVersion = node.path("localProfileVersion").asInt();
- objects.clear();
+ objects.clear();
+ objectMap.clear();
if (node.hasNonNull("localProfile")) {
- setLocalProfile(new GameObject(node.get("localProfile")));
+ addObject(new GameObject(node.get("localProfile")), options.getBuildComponentTree());
+ localProfile = objects.get(0);
}
if (node.hasNonNull("objects")) {
- for (JsonNode profileObject : node.get("objects")) {
- objects.add(new GameObject(profileObject));
+ for (JsonNode objectNode : node.get("objects")) {
+ addObject(new GameObject(objectNode), options.getBuildComponentTree());
}
}
@@ -233,10 +242,16 @@ public void setLocalProfileVersion(int localProfileVersion) {
this.localProfileVersion = localProfileVersion;
}
+ @Override
public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
public GameObject getLocalProfile() {
return localProfile;
}
diff --git a/src/main/java/qowyn/ark/ArkProfile.java b/src/main/java/qowyn/ark/ArkProfile.java
index 954767b..a840769 100644
--- a/src/main/java/qowyn/ark/ArkProfile.java
+++ b/src/main/java/qowyn/ark/ArkProfile.java
@@ -7,19 +7,24 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import qowyn.ark.properties.Property;
+import qowyn.ark.types.ArkName;
-public class ArkProfile extends FileFormatBase implements PropertyContainer, GameObjectContainer {
+public class ArkProfile extends FileFormatBase implements PropertyContainer, GameObjectContainerMixin {
private int profileVersion;
private final ArrayList objects = new ArrayList<>();
+ private final Map, GameObject>> objectMap = new HashMap<>();
+
private GameObject profile;
public ArkProfile() {}
@@ -50,8 +55,10 @@ public void readBinary(ArkArchive archive, ReadingOptions options) {
int profilesCount = archive.getInt();
+ objects.clear();
+ objectMap.clear();
for (int i = 0; i < profilesCount; i++) {
- objects.add(new GameObject(archive));
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
for (int i = 0; i < profilesCount; i++) {
@@ -112,15 +119,17 @@ public void writeBinary(Path filePath, WritingOptions options) throws FileNotFou
@Override
public void readJson(JsonNode node, ReadingOptions options) {
profileVersion = node.path("profileVersion").asInt();
- objects.clear();
+ objects.clear();
+ objectMap.clear();
if (node.hasNonNull("profile")) {
- setProfile(new GameObject(node.get("profile")));
+ addObject(new GameObject(node.get("profile")), options.getBuildComponentTree());
+ profile = objects.get(0);
}
if (node.hasNonNull("objects")) {
- for (JsonNode tribeObject : node.get("objects")) {
- objects.add(new GameObject(tribeObject));
+ for (JsonNode objectNode : node.get("objects")) {
+ addObject(new GameObject(objectNode), options.getBuildComponentTree());
}
}
}
@@ -160,10 +169,16 @@ public void setProfileVersion(int profileVersion) {
this.profileVersion = profileVersion;
}
+ @Override
public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
public GameObject getProfile() {
return profile;
}
diff --git a/src/main/java/qowyn/ark/ArkSavegame.java b/src/main/java/qowyn/ark/ArkSavegame.java
index 3734ab1..980fa93 100644
--- a/src/main/java/qowyn/ark/ArkSavegame.java
+++ b/src/main/java/qowyn/ark/ArkSavegame.java
@@ -7,6 +7,7 @@
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -19,11 +20,12 @@
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
+import qowyn.ark.types.ArkName;
import qowyn.ark.types.EmbeddedData;
import qowyn.ark.types.ListAppendingSet;
import qowyn.ark.types.ObjectReference;
-public class ArkSavegame extends FileFormatBase implements GameObjectContainer {
+public class ArkSavegame extends FileFormatBase implements GameObjectContainerMixin {
protected short saveVersion;
@@ -51,6 +53,8 @@ public class ArkSavegame extends FileFormatBase implements GameObjectContainer {
protected final ArrayList objects = new ArrayList<>();
+ protected final Map, GameObject>> objectMap = new HashMap<>();
+
protected int hibernationV8Unknown1;
protected int hibernationV8Unknown2;
@@ -120,6 +124,11 @@ public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
public boolean hasUnknownNames() {
return oldNameList != null;
}
@@ -128,6 +137,22 @@ public boolean hasUnknownData() {
return hasUnknownData;
}
+ public Map> getDataFilesObjectMap() {
+ return dataFilesObjectMap;
+ }
+
+ public ArrayList getHibernationClasses() {
+ return hibernationClasses;
+ }
+
+ public ArrayList getHibernationIndices() {
+ return hibernationIndices;
+ }
+
+ public ArrayList getHibernationEntries() {
+ return hibernationEntries;
+ }
+
@Override
public void readBinary(ArkArchive archive, ReadingOptions options) {
readBinaryHeader(archive);
@@ -265,10 +290,9 @@ protected void readBinaryObjects(ArkArchive archive, ReadingOptions options) {
int count = archive.getInt();
objects.clear();
+ objectMap.clear();
for (int n = 0; n < count; n++) {
- GameObject gameObject = new GameObject(archive);
- gameObject.setId(n);
- objects.add(gameObject);
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
} else {
archive.unknownData();
@@ -374,7 +398,7 @@ protected void readBinaryHibernation(ArkArchive archive, ReadingOptions options)
hibernationEntries.clear();
hibernationEntries.ensureCapacity(hibernatedObjectsCount);
for (int index = 0; index < hibernatedObjectsCount; index++) {
- hibernationEntries.add(new HibernationEntry(archive, options.getHibernationObjectProperties()));
+ hibernationEntries.add(new HibernationEntry(archive, options));
}
}
@@ -714,13 +738,13 @@ protected void readJsonDataFilesObjectMap(JsonNode node, ReadingOptions options)
protected void readJsonObjects(JsonNode node, ReadingOptions options) {
objects.clear();
+ objectMap.clear();
if (options.getGameObjects()) {
JsonNode objectsArray = node.path("objects");
if (!objectsArray.isNull()) {
objects.ensureCapacity(objectsArray.size());
for (int i = 0; i < objectsArray.size(); i++) {
- objects.add(new GameObject(objectsArray.get(i), options.getGameObjectProperties()));
- objects.get(i).setId(i);
+ addObject(new GameObject(objectsArray.get(i), options.getGameObjectProperties()), options.getBuildComponentTree());
}
}
}
@@ -757,7 +781,7 @@ protected void readJsonHibernatedObjects(JsonNode node, ReadingOptions options)
JsonNode entriesArray = hibernation.path("entries");
if (!entriesArray.isNull()) {
for (JsonNode hibernatedObject: entriesArray) {
- hibernationEntries.add(new HibernationEntry(hibernatedObject, options.getHibernationObjectProperties()));
+ hibernationEntries.add(new HibernationEntry(hibernatedObject, options));
}
}
} else {
diff --git a/src/main/java/qowyn/ark/ArkTribe.java b/src/main/java/qowyn/ark/ArkTribe.java
index bbfb458..1906674 100644
--- a/src/main/java/qowyn/ark/ArkTribe.java
+++ b/src/main/java/qowyn/ark/ArkTribe.java
@@ -7,19 +7,24 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import qowyn.ark.properties.Property;
+import qowyn.ark.types.ArkName;
-public class ArkTribe extends FileFormatBase implements PropertyContainer, GameObjectContainer {
+public class ArkTribe extends FileFormatBase implements PropertyContainer, GameObjectContainerMixin {
private int tribeVersion;
private final ArrayList objects = new ArrayList<>();
+ private final Map, GameObject>> objectMap = new HashMap<>();
+
private GameObject tribe;
public ArkTribe() {}
@@ -50,8 +55,10 @@ public void readBinary(ArkArchive archive, ReadingOptions options) {
int tribesCount = archive.getInt();
+ objects.clear();
+ objectMap.clear();
for (int i = 0; i < tribesCount; i++) {
- objects.add(new GameObject(archive));
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
for (int i = 0; i < tribesCount; i++) {
@@ -112,15 +119,17 @@ public void writeBinary(Path filePath, WritingOptions options) throws FileNotFou
@Override
public void readJson(JsonNode node, ReadingOptions options) {
tribeVersion = node.path("tribeVersion").asInt();
- objects.clear();
+ objects.clear();
+ objectMap.clear();
if (node.hasNonNull("tribe")) {
- setTribe(new GameObject(node.get("tribe")));
+ addObject(new GameObject(node.get("tribe")), options.getBuildComponentTree());
+ tribe = objects.get(0);
}
if (node.hasNonNull("objects")) {
- for (JsonNode tribeObject : node.get("objects")) {
- objects.add(new GameObject(tribeObject));
+ for (JsonNode objectNode : node.get("objects")) {
+ addObject(new GameObject(objectNode), options.getBuildComponentTree());
}
}
}
@@ -160,10 +169,16 @@ public void setTribeVersion(int tribeVersion) {
this.tribeVersion = tribeVersion;
}
+ @Override
public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
public GameObject getTribe() {
return tribe;
}
diff --git a/src/main/java/qowyn/ark/GameObject.java b/src/main/java/qowyn/ark/GameObject.java
index ab8a763..82cc5e6 100644
--- a/src/main/java/qowyn/ark/GameObject.java
+++ b/src/main/java/qowyn/ark/GameObject.java
@@ -2,6 +2,7 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -25,7 +26,7 @@ public class GameObject implements PropertyContainer, NameContainer {
private static final UUID NULL_UUID = UUID.fromString(NULL_UUID_STRING);
- private static final Map UUID_CACHE = new ConcurrentHashMap<>();
+ private static final Map uuidCache = new ConcurrentHashMap<>();
private int id;
@@ -54,6 +55,10 @@ public class GameObject implements PropertyContainer, NameContainer {
protected ExtraData extraData;
+ protected GameObject parent;
+
+ protected Map components = new LinkedHashMap<>();
+
public GameObject() {}
public GameObject(ArkArchive archive) {
@@ -174,7 +179,8 @@ public void writeProperties(ArkArchive archive, int propertiesBlockOffset) {
}
public void readJson(JsonNode node, boolean loadProperties) {
- uuid = UUID.fromString(node.path("uuid").asText(NULL_UUID_STRING));
+
+ uuid = uuidCache.computeIfAbsent(UUID.fromString(node.path("uuid").asText(NULL_UUID_STRING)), uuid -> uuid);
className = ArkName.from(node.path("class").asText());
item = node.path("item").asBoolean();
@@ -314,10 +320,14 @@ public int getPropertiesSize(NameSizeCalculator nameSizer) {
}
public void readBinary(ArkArchive archive) {
- long uuidMostSig = archive.getLong();
- long uuidLeastSig = archive.getLong();
+ long highOfHigh = archive.getInt();
+ long lowOfHigh = archive.getInt();
+ long high = (highOfHigh << 32) + lowOfHigh;
+ long highOfLow = archive.getInt();
+ long lowOfLow = archive.getInt();
+ long low = (highOfLow << 32) + lowOfLow;
- uuid = UUID_CACHE.computeIfAbsent(new LongLong(uuidMostSig, uuidLeastSig), ll -> new UUID(ll.getHigh(), ll.getLow()));
+ uuid = uuidCache.computeIfAbsent(new UUID(high, low), uuid -> uuid);
className = archive.getName();
@@ -455,4 +465,36 @@ public void collectPropertyNames(NameCollector collector) {
}
}
+ public GameObject getParent() {
+ return parent;
+ }
+
+ public void setParent(GameObject parent) {
+ this.parent = parent;
+ }
+
+ public Map getComponents() {
+ return components;
+ }
+
+ public void setComponents(Map components) {
+ this.components = components;
+ }
+
+ public void addComponent(GameObject component) {
+ this.components.put(component.getNames().get(0), component);
+ }
+
+ public boolean hasParentNames() {
+ return names.size() > 1;
+ }
+
+ public List getParentNames() {
+ return names.subList(1, names.size());
+ }
+
+ public static void clearUUIDCache() {
+ uuidCache.clear();
+ }
+
}
diff --git a/src/main/java/qowyn/ark/GameObjectContainer.java b/src/main/java/qowyn/ark/GameObjectContainer.java
index 983a42f..a22d54d 100644
--- a/src/main/java/qowyn/ark/GameObjectContainer.java
+++ b/src/main/java/qowyn/ark/GameObjectContainer.java
@@ -1,5 +1,6 @@
package qowyn.ark;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -26,4 +27,6 @@ public default Iterator iterator() {
return getObjects().iterator();
}
+ public static final GameObjectContainer EMPTY_CONTAINER = () -> Collections.emptyList();
+
}
diff --git a/src/main/java/qowyn/ark/GameObjectContainerMixin.java b/src/main/java/qowyn/ark/GameObjectContainerMixin.java
new file mode 100644
index 0000000..b0d7b7b
--- /dev/null
+++ b/src/main/java/qowyn/ark/GameObjectContainerMixin.java
@@ -0,0 +1,42 @@
+package qowyn.ark;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import qowyn.ark.types.ArkName;
+
+interface GameObjectContainerMixin extends GameObjectContainer {
+
+ public Map, GameObject>> getObjectMap();
+
+ public default void addObject(GameObject object, boolean processNames) {
+ List objects = getObjects();
+
+ if (processNames) {
+ Map, GameObject> map = getObjectMap().get(object.isFromDataFile() ? object.getDataFileIndex() : null);
+
+ if (map != null) {
+ if (object.hasParentNames()) {
+ List targetName = object.getParentNames();
+
+ GameObject parent = map.get(targetName);
+ if (parent != null) {
+ parent.addComponent(object);
+ object.setParent(parent);
+ }
+ }
+
+ map.putIfAbsent(object.getNames(), object);
+ } else {
+ map = new HashMap<>();
+ map.put(object.getNames(), object);
+ getObjectMap().put(object.isFromDataFile() ? object.getDataFileIndex() : null, map);
+ };
+ }
+
+ object.setId(objects.size());
+ objects.add(object);
+ }
+
+}
diff --git a/src/main/java/qowyn/ark/HibernationEntry.java b/src/main/java/qowyn/ark/HibernationEntry.java
index d29611c..68c38c2 100644
--- a/src/main/java/qowyn/ark/HibernationEntry.java
+++ b/src/main/java/qowyn/ark/HibernationEntry.java
@@ -2,8 +2,10 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import com.fasterxml.jackson.core.JsonGenerator;
@@ -11,7 +13,7 @@
import qowyn.ark.types.ArkName;
-public class HibernationEntry {
+public class HibernationEntry implements GameObjectContainerMixin {
private float x;
@@ -27,6 +29,8 @@ public class HibernationEntry {
private final ArrayList objects = new ArrayList<>();
+ private final Map, GameObject>> objectMap = new HashMap<>();
+
private int unkInt1;
private int classIndex;
@@ -42,22 +46,22 @@ public class HibernationEntry {
public HibernationEntry() {
}
- public HibernationEntry(ArkArchive archive, boolean loadProperties) {
- readBinary(archive, loadProperties);
+ public HibernationEntry(ArkArchive archive, ReadingOptions options) {
+ readBinary(archive, options);
}
- public HibernationEntry(JsonNode node, boolean loadProperties) {
- readJson(node, loadProperties);
+ public HibernationEntry(JsonNode node, ReadingOptions options) {
+ readJson(node, options);
}
- public void readBinary(ArkArchive archive, boolean loadProperties) {
+ public void readBinary(ArkArchive archive, ReadingOptions options) {
x = archive.getFloat();
y = archive.getFloat();
z = archive.getFloat();
unkByte = archive.getByte();
unkFloat = archive.getFloat();
- if (loadProperties) {
+ if (options.getHibernationObjectProperties()) {
ArkArchive nameArchive = archive.slice(archive.getInt());
readBinaryNameTable(nameArchive);
} else {
@@ -69,7 +73,7 @@ public void readBinary(ArkArchive archive, boolean loadProperties) {
}
ArkArchive objectArchive = archive.slice(archive.getInt());
- readBinaryObjects(objectArchive);
+ readBinaryObjects(objectArchive, options);
unkInt1 = archive.getInt();
classIndex = archive.getInt();
@@ -96,13 +100,14 @@ protected void readBinaryNameTable(ArkArchive archive) {
}
}
- protected void readBinaryObjects(ArkArchive archive) {
+ protected void readBinaryObjects(ArkArchive archive, ReadingOptions options) {
int count = archive.getInt();
objects.clear();
objects.ensureCapacity(count);
+ objectMap.clear();
for (int index = 0; index < count; index++) {
- objects.add(new GameObject(archive));
+ addObject(new GameObject(archive), options.getBuildComponentTree());
}
if (nameTable != null) {
@@ -178,7 +183,7 @@ public int getSizeAndCollectNames() {
return size + nameTableSize + objectsSize;
}
- public void readJson(JsonNode node, boolean loadProperties) {
+ public void readJson(JsonNode node, ReadingOptions options) {
x = (float) node.path("x").asDouble();
y = (float) node.path("y").asDouble();
z = (float) node.path("z").asDouble();
@@ -193,9 +198,10 @@ public void readJson(JsonNode node, boolean loadProperties) {
}
objects.clear();
+ objectMap.clear();
if (node.hasNonNull("objects")) {
for (JsonNode object: node.path("objects")) {
- objects.add(new GameObject(object, loadProperties));
+ addObject(new GameObject(object, options.getHibernationObjectProperties()), options.getBuildComponentTree());
}
}
@@ -290,8 +296,14 @@ public ArrayList getZoneVolumes() {
return zoneVolumes;
}
+ @Override
public ArrayList getObjects() {
return objects;
}
+ @Override
+ public Map, GameObject>> getObjectMap() {
+ return objectMap;
+ }
+
}
diff --git a/src/main/java/qowyn/ark/LongLong.java b/src/main/java/qowyn/ark/LongLong.java
deleted file mode 100644
index f4017c5..0000000
--- a/src/main/java/qowyn/ark/LongLong.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package qowyn.ark;
-
-class LongLong {
-
- private final long high;
-
- private final long low;
-
- public LongLong(long high, long low) {
- this.high = high;
- this.low = low;
- }
-
- public long getHigh() {
- return high;
- }
-
- public long getLow() {
- return low;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (int) (high ^ (high >>> 32));
- result = prime * result + (int) (low ^ (low >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- LongLong other = (LongLong) obj;
- if (high != other.high)
- return false;
- if (low != other.low)
- return false;
- return true;
- }
-
-}
diff --git a/src/main/java/qowyn/ark/ReadingOptions.java b/src/main/java/qowyn/ark/ReadingOptions.java
index 04bc3aa..9cdaf82 100644
--- a/src/main/java/qowyn/ark/ReadingOptions.java
+++ b/src/main/java/qowyn/ark/ReadingOptions.java
@@ -25,6 +25,8 @@ public class ReadingOptions extends BaseOptions {
private boolean hibernationObjectProperties = true;
+ private boolean buildComponentTree = false;
+
public static ReadingOptions create() {
return new ReadingOptions();
}
@@ -186,6 +188,15 @@ public ReadingOptions withHibernationObjectProperties(boolean hibernationObjectP
return this;
}
+ public boolean getBuildComponentTree() {
+ return buildComponentTree;
+ }
+
+ public ReadingOptions buildComponentTree(boolean buildComponentTree) {
+ this.buildComponentTree = buildComponentTree;
+ return this;
+ }
+
@Override
public ReadingOptions parallel(boolean parallel) {
super.parallel(parallel);
diff --git a/src/main/java/qowyn/ark/arrays/ArkArrayByteHandler.java b/src/main/java/qowyn/ark/arrays/ArkArrayByteHandler.java
index b33eb3a..b22d40c 100644
--- a/src/main/java/qowyn/ark/arrays/ArkArrayByteHandler.java
+++ b/src/main/java/qowyn/ark/arrays/ArkArrayByteHandler.java
@@ -23,7 +23,7 @@ public static ArkArray> create(ArkArchive archive, PropertyArray property) {
if (property.getDataSize() > size + 4) {
return new ArkArrayByteValue(archive, property);
} else {
- return new ArkArrayInt8(archive, property);
+ return new ArkArrayUInt8(archive, property);
}
}
@@ -32,7 +32,7 @@ public static ArkArray> create(JsonNode node, PropertyArray property) {
if (node.size() > 0 && node.get(0).isNull()) {
return new ArkArrayByteValue(node, property);
} else {
- return new ArkArrayInt8(node, property);
+ return new ArkArrayUInt8(node, property);
}
}
diff --git a/src/main/java/qowyn/ark/arrays/ArkArrayString.java b/src/main/java/qowyn/ark/arrays/ArkArrayString.java
index 92d4b87..0ef4816 100644
--- a/src/main/java/qowyn/ark/arrays/ArkArrayString.java
+++ b/src/main/java/qowyn/ark/arrays/ArkArrayString.java
@@ -29,7 +29,7 @@ public ArkArrayString(ArkArchive archive, PropertyArray property) {
}
public ArkArrayString(JsonNode node, PropertyArray property) {
- node.forEach(n -> this.add(n.asText()));
+ node.forEach(n -> this.add(n.textValue()));
}
@Override
diff --git a/src/main/java/qowyn/ark/properties/PropertyStr.java b/src/main/java/qowyn/ark/properties/PropertyStr.java
index e1631a3..60dd516 100644
--- a/src/main/java/qowyn/ark/properties/PropertyStr.java
+++ b/src/main/java/qowyn/ark/properties/PropertyStr.java
@@ -28,7 +28,7 @@ public PropertyStr(ArkArchive archive, ArkName name) {
public PropertyStr(JsonNode node) {
super(node);
- value = node.path("value").asText();
+ value = node.path("value").textValue();
}
@Override
diff --git a/src/main/java/qowyn/ark/types/ObjectReference.java b/src/main/java/qowyn/ark/types/ObjectReference.java
index 1e8bb1b..dba42e0 100644
--- a/src/main/java/qowyn/ark/types/ObjectReference.java
+++ b/src/main/java/qowyn/ark/types/ObjectReference.java
@@ -103,7 +103,7 @@ public void readJson(JsonNode node) {
objectId = node.asInt();
objectType = TYPE_ID;
} else if (node.isTextual()) {
- objectString = ArkName.from(node.asText());
+ objectString = ArkName.from(node.textValue());
objectType = TYPE_PATH;
} else {
objectString = ArkName.from(node.path("value").asText());
@@ -176,4 +176,12 @@ public void collectNames(NameCollector collector) {
}
}
+ public boolean isId() {
+ return objectType == TYPE_ID;
+ }
+
+ public boolean isPath() {
+ return objectType != TYPE_ID;
+ }
+
}