/// <summary> /// output all the changes made with the editor to a new datadict file /// </summary> private void SaveAs_Execute() { //make sure all the elements that may hold old data before starting the file output process SaveAsOutput.Clear(); SaveAsAttributeDescription.Clear(); SaveAsFinalData.Clear(); //store the header of the currently open file for later use SaveAsOutput = OpenFileBytes.Skip(0).Take(16 + (DDObjects.Count * 8)).ToList(); //for every datadict object in the current file for (int i = 0; i < DDObjects.Count; i++) { ObservableCollection <DataDict_Attribute> SaveAsAttributes = new ObservableCollection <DataDict_Attribute>(DDObjects[i].DataDictObjects); //define the attributes associated to the current data dict object int SaveAsNumAttributes = DDObjects[i].NumOfAttributes; // loop through all atrributes, save to the output attribute description list and final data list for (int a = 0; a < SaveAsNumAttributes; a++) { //add the attributes description the the attribute description array SaveAsAttributeDescription.AddRange(DDObjects[i].DataDictObjects[a].Description.ToList <byte>()); //Set the new offset based on the current length of the final data block and write it to the attribute description array byte[] cbytes = BitConverter.GetBytes(SaveAsFinalData.Count); SaveAsAttributeDescription.AddRange(cbytes.Skip(0).Take(3).ToList()); //write the attribute type to the attribute description array SaveAsAttributeDescription.Add(DDObjects[i].DataDictObjects[a].Type); //based on the attribute type write the appropriate value bytes to the attribute description array if (DDObjects[i].DataDictObjects[a].Type == 13) { SaveAsFinalData.AddRange(ReturnZeroPaddedString(DDObjects[i].DataDictObjects[a].Value)); } else { SaveAsFinalData.AddRange(DDObjects[i].DataDictObjects[a].Value); } } } //add the attribute description array to the final output array SaveAsOutput.AddRange(SaveAsAttributeDescription); //add the final data array to the final output array SaveAsOutput.AddRange(SaveAsFinalData); //update bytes 12-16 to represent the new length of data byte[] newdatalength = BitConverter.GetBytes(SaveAsFinalData.Count); //update the output bytes 4-8 with the new datablock length UpdateDatablockLength(newdatalength); //prepare to write the changes to a file by creating a new savefiledialog SaveFileDialog saveFileDialog1 = new SaveFileDialog(); //Set the window options to default to .datadict file format saveFileDialog1.Filter = "DeathSpank Data Files (*.datadict)| *.datadict"; //set the save as window title saveFileDialog1.Title = "Save a DeathSpank Data File"; //display the save as dialog option saveFileDialog1.ShowDialog(); if (saveFileDialog1.FileName != "") { //Create a new filestream from the open file dialog options using (FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile()) { //create a binary writer to write to the filestream BinaryWriter bw = new BinaryWriter(fs); //Write data to the new file bw.Write(SaveAsOutput.ToArray()); //flush and close the binarywriter bw.Flush(); bw.Close(); } } }
/// <summary> /// Populate an observable collection of DataDict_Objects /// from the bytes in the currently opened files any time the currently /// opened file changes /// </summary> private void OnOpenFileBytesChanged() { //Clear all objects from the observable collection DDObjects.Clear(); //reset the hexidecimal display boolean IsHexadecimalDisplayed = false; //Declare the number of objects //derived by bytes 4-8 of OpenFileBytes array int numobjects = BitConverter.ToInt32(OpenFileBytes.Skip(4).Take(4).ToArray(), 0); //declare the datablock length from bytes 12-16 int datablocklength = BitConverter.ToInt32(OpenFileBytes.Skip(12).Take(4).ToArray(), 0); //declare the attribute description block length by taking bytes 8-12 as an integer and multiplying by 8 //because each attribute description is 8 bytes long int attributedescriptionblocklength = BitConverter.ToInt32(OpenFileBytes.Skip(8).Take(4).ToArray(), 0) * 8; //define the block of data defining the number of attributes per object byte[] objectattributeblock = OpenFileBytes.Skip(16).Take(numobjects * 8).ToArray(); //define the lock of data defining the details of each object attribute byte[] attributedescriptionblock = OpenFileBytes.Skip(16 + objectattributeblock.Length).Take(attributedescriptionblocklength).ToArray(); //define the block of data where all of the attribute values are held byte[] datablock = OpenFileBytes.Skip(OpenFileBytes.Length - datablocklength).Take(datablocklength).ToArray(); //create a loop that repeats for every object in the file for (int i = 0; i < numobjects; i++) { //Get the 8 bits that define the current object and the number of attributes it has byte[] currentobject = objectattributeblock.Skip(i * 8).Take(8).ToArray(); //take the last 4 bits of the current object byte array to define the number of attributes the object has int numattributes = BitConverter.ToInt32(currentobject.Skip(4).Take(4).ToArray(), 0); //define where in the attribute description block this object's attributes start int attrstartOFfset = (BitConverter.ToInt32(currentobject.Skip(0).Take(4).ToArray(), 0) * 8); //create a new datadict_object to represent the file object //populate the number of attributes and give it an object ID DataDict_Object ddobject = new DataDict_Object() { NumOfAttributes = numattributes, ObjectID = i + 1 }; //Loop through the attributes and populate the attributes into to DataDict_Object for (int a = 0; a < numattributes; a++) { //locate and define the current attribute description object (8 bytes) byte[] currentattribute = attributedescriptionblock.Skip((a * 8) + attrstartOFfset).Take(8).ToArray(); //create a new datadict_attribute object and populate the description, offset and type DataDict_Attribute ddattribute = new DataDict_Attribute() { Description = currentattribute.Skip(0).Take(4).ToArray(), Offset = ReturnOffset(currentattribute.Skip(4).Take(3).ToArray()), Type = currentattribute[7] }; //use the get value method to return the value for this attribute based on its type and offset ddattribute.Value = GetValue(ddattribute.Offset, ddattribute.Type, datablock); //add the current attribute to the object's observable collection of attributes ddobject.DataDictObjects.Add(ddattribute); } //Add the current object to the bound observablecollection of datadict objects DDObjects.Add(ddobject); } }