public DotArkFile OpenArkFile(IOMemoryStream ms) { this.ms = ms; //Initialize our variables ark = new DotArkFile(); //Open the header data. ReadHeader(); //Read in the binary data names, such as "Extinction", "C1_Far", "C2_Far" binaryDataNames = ReadStringArray(ms); //Read the embeded binary data. ReadArkEmbededBinaryData(); //Finally, read the mystery flags ReadMysteryFlags(); //Save our position and read the class name block. gameObjectBlockStartOffset = ms.ms.Position; //Save location ms.ms.Position = nameTableOffset; //Jump to the table binaryNameTable = ReadStringArray(ms); //Read in the data ms.ms.Position = gameObjectBlockStartOffset; //Jump back to continue reading the file. //Read the GameObject table. ReadGameObjectTable(); //Get the property data ReadPropertiesForGameObjects(); //Finish by setting values ark.gameObjects = gameObjects; ark.meta = this; return(ark); }
public static void WriteDotArk(IOMemoryStream ms, DotArkFile f) { //Create instance DotArkSerializerInstance inst = new DotArkSerializerInstance(); //Write the game object bodies into their own temporary stream for later IOMemoryStream gameObjectBodyStream = new IOMemoryStream(true); long[] gameObjectPropertyOffsets = GameObjectBodyWriter.WriteGameObjectBodies(gameObjectBodyStream, f, inst); //Now, write the GameObject heads into their own temporary stream for later. IOMemoryStream gameObjectHeadStream = new IOMemoryStream(true); GameObjectHeadWriter.WriteGameObjectHeads(gameObjectHeadStream, f, inst, gameObjectPropertyOffsets); //Create the binary data names, the map parts. IOMemoryStream binaryDataNames = SmallArkDataWriter.WriteBinaryDataNames(f, inst); //Create the embedded binary data IOMemoryStream embeddedBinaryData = SmallArkDataWriter.WriteEmbeddedBinaryDataArray(f, inst); //Create flag data IOMemoryStream unknownFlagData = SmallArkDataWriter.WriteArkUnknownFlags(f, inst); //Finally, generate the name table. THIS STEP MUST COME LAST! IOMemoryStream nameTable = SmallArkDataWriter.WriteNameTable(f, inst); //Build the file BuildArkFile(nameTable, binaryDataNames, embeddedBinaryData, unknownFlagData, gameObjectHeadStream, gameObjectBodyStream, f.meta.unknownData1, f.gameTime, f.meta.saveCount).CopyFromBeginningTo(ms); }
static void WriteHead(IOMemoryStream ms, DotArkFile f, DotArkSerializerInstance si, DotArkGameObject go, long propertyOffset) { //Write data according to https://us-central.assets-static-2.romanport.com/ark/#gameobject+base_header ms.WriteBytes(go.guid.ToByteArray()); //Write the GUID ms.WriteArkClassname(go.classname, si); //Write classname ms.WriteIntBool(go.isItem); //Write classname array ms.WriteInt(go.names.Count); foreach (var n in go.names) { ms.WriteArkClassname(n, si); } //Write unknowns ms.WriteIntBool(go.unknownData1); ms.WriteInt(go.unknownData2); //Write position data if it exists. ms.WriteIntBool(go.locationData != null); if (go.locationData != null) { ms.WriteLocationData(go.locationData); } //Write the offset to the properties data ms.WriteInt((int)propertyOffset); //Write last unknown data ms.WriteInt(go.unknownData3); }
public SoftEditSession(IOMemoryStream ms) { //Load ARK save underlyingFile = new DotArkDeserializer().OpenArkFile(ms); //Copy name table to here nameTable = underlyingFile.meta.binaryNameTable.ToList(); }
public static IOMemoryStream WriteBinaryDataNames(DotArkFile f, DotArkSerializerInstance si) { //Binary data names are showing map parts. Spec is here: https://us-central.assets-static-2.romanport.com/ark/#binary+data+names_header //Create stream IOMemoryStream ms = new IOMemoryStream(true); //Write into it DotArkWriter.WriteStringArray(ms, f.meta.binaryDataNames); return(ms); }
public static IOMemoryStream WriteNameTable(DotArkFile f, DotArkSerializerInstance si) { //name table for props. Spec is here: https://us-central.assets-static-2.romanport.com/ark/#binary+class+name+table_header //Create stream IOMemoryStream ms = new IOMemoryStream(true); //Write into it DotArkWriter.WriteStringArray(ms, si.nameTable.ToArray()); return(ms); }
public static void WriteGameObjectHeads(IOMemoryStream ms, DotArkFile f, DotArkSerializerInstance si, long[] propertyOffsets) { //Write all of the GameObject headers //First, write the number of GameObjects ms.WriteInt(f.gameObjects.Count); //Loop through gameObjects and write their heads for (int i = 0; i < f.gameObjects.Count; i++) { WriteHead(ms, f, si, f.gameObjects[i], propertyOffsets[i]); } }
static void WriteSingleGameObjectBody(IOMemoryStream ms, DotArkFile f, DotArkGameObject o, DotArkSerializerInstance si) { //Just start writing properties foreach (var prop in o.props) { prop.WriteProp(si, o, f, ms); } //Finally, write a None name to tell Ark that this is the end of the list of props. ms.WriteArkClassname(new ArkClassName { classname = "None", index = 0 }, si); }
public static IOMemoryStream WriteEmbeddedBinaryDataArray(DotArkFile f, DotArkSerializerInstance si) { //I'm really not sure what this is. Spec: https://us-central.assets-static-2.romanport.com/ark/#embeded+binary+data_header //Open straem IOMemoryStream ms = new IOMemoryStream(true); //Get source data var s = f.meta.embededBinaryData; //Write number of blobs ms.WriteInt(s.Length); //Write each for (int i = 0; i < s.Length; i++) { var ss = s[i]; //Write path ms.WriteUEString(ss.path); //Write number of parts ms.WriteInt(ss.data.Length); //Write parts for (int j = 0; j < ss.data.Length; j++) { var ssb = ss.data[j]; //Write number of inner blobs ms.WriteInt(ssb.Length); //Write each inner blob for (int n = 0; n < ssb.Length; n++) { var ssbb = ssb[i]; ms.WriteInt(ssbb.Length / 4); ms.WriteBytes(ssbb); } } } //Return stream return(ms); }
public static long[] WriteGameObjectBodies(IOMemoryStream ms, DotArkFile f, DotArkSerializerInstance si) { //Start writing properties at the current location. long startPos = ms.position; //Allocate an array for storing the offsets to each long[] offsets = new long[f.gameObjects.Count]; //Loop through all GameObjects for (int i = 0; i < f.gameObjects.Count; i++) { offsets[i] = ms.position - startPos; WriteSingleGameObjectBody(ms, f, f.gameObjects[i], si); } //Return offsets return(offsets); }
public static IOMemoryStream WriteArkUnknownFlags(DotArkFile f, DotArkSerializerInstance si) { //Create stream and get the data IOMemoryStream ms = new IOMemoryStream(true); var d = f.meta.mysteryFlagData; //Write array ms.WriteInt(d.Length); for (int i = 0; i < d.Length; i++) { var ds = d[i]; ms.WriteInt(ds.flags); ms.WriteInt(ds.objectCount); ms.WriteUEString(ds.nameString); } //Respond with stream return(ms); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Write the struct type ms.WriteArkClassname(structType, s); //Write the struct data. structData.WriteStruct(s, go, f, ms); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); byte value = 0; if ((bool)data) { value = 1; } //Write ms.WriteByte(value); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Get name table entry ms.WriteArkClassname((ArkClassName)data, s); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Write enum name ms.WriteArkClassname(enumName, s); //If this is a normal byte, write the byte value. Else, write the classname if (isNormalByte) { ms.ms.WriteByte(byteValue); } else { ms.WriteArkClassname(enumValue, s); } }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Write the byte ms.ms.WriteByte((byte)data); }
public override void WriteStruct(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { ms.WriteInt(unk); ms.WriteUEString(netId); }
/// <summary> /// When overwritten, this function will write the prop /// </summary> /// <param name="s"></param> /// <param name="go"></param> /// <param name="f"></param> /// <param name="ms"></param> public virtual void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { //Write the header data ms.WriteArkClassname(name, s); ms.WriteArkClassname(type, s); ms.WriteInt(size); ms.WriteInt(index); //Now, the overwritten function will run. }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { //For now, fake this and pretend this is an empty array //TODO: Add ArrayProperty to saveable properties. size = 4; base.WriteProp(s, go, f, ms); ms.WriteArkClassname(arrayType, s); ms.WriteInt(0); }
public override void WriteStruct(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { ms.WriteFloat(r); ms.WriteFloat(g); ms.WriteFloat(b); ms.WriteFloat(a); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //If the length is four, just write the objectID //TODO: Track the referenced GameObject so changing the index doesn't break this. if (size == 4) { ms.WriteInt(objectId); } else if (size >= 8) { //Write the type ms.WriteInt((int)objectRefType); //Depending on the type, write it if (objectRefType == ObjectPropertyType.TypeID) { ms.WriteInt(objectId); } else if (objectRefType == ObjectPropertyType.TypePath) { ms.WriteArkClassname(className, s); } else { throw new Exception("Unknown type of ObjectProperty."); } } else { throw new Exception($"Unknown ObjectProperty length, {size}. Cannot write."); } }
public virtual void WriteStruct(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { throw new Exception("Unknown sturct type; Cannot write."); }
public override void WriteStruct(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { //Write all of the props in the dict foreach (var p in props) { //Write property p.Value.WriteProp(s, go, f, ms); } //Finally, write a None type to stop Ark ms.WriteArkClassname(new ArkClassName { classname = "None", index = 0 }, s); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Write string ms.WriteUEString((string)data); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Convert from Base64 string byte[] buf = Convert.FromBase64String((string)data); //If this does not match the length, die if (size != buf.Length) { throw new Exception("The size of the TextProperty did not match the real size, in bytes."); } //Write ms.ms.Write(buf, 0, size); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Write int ms.WriteInt((int)data); }
public override void WriteProp(DotArkSerializerInstance s, DotArkGameObject go, DotArkFile f, IOMemoryStream ms) { base.WriteProp(s, go, f, ms); //Write the UInt64 ms.WriteULong((ulong)data); }