public override bool ImportModel(string path, ref Model model) { using (FileStream fs = new FileStream(path, FileMode.Open)) { string magicStr = fs.ReadString(); if (magicStr != "DMW") { MessageBox.Show("Error: Model is not of the DMW format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } int version = fs.ReadInt32(); if (version < DMW_LOWEST_SUPPORTED_VERSION || version > DMW_CURRENT_VERSION) { MessageBox.Show("Error: Model is of unsupported version " + version + "\n\nThis version of the DMW Suite only supports DMW models between versions " + DMW_LOWEST_SUPPORTED_VERSION + " and " + DMW_CURRENT_VERSION, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } string readString; while ((readString = fs.ReadString()) != null) { string[] splString = readString.Split(new char[] { ':' }, 2); model.Metadata[splString[0]] = splString[1]; } short encryptionTypeShrt = fs.ReadInt16(); if (!Enum.IsDefined(typeof(DMW_DATAENC), encryptionTypeShrt)) { MessageBox.Show("Error: Model uses unsupported encryption method", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } DMW_DATAENC encryptionType = (DMW_DATAENC)encryptionTypeShrt; MemoryStream modelData = new MemoryStream(); if (encryptionType != DMW_DATAENC.None) { string encryptionKey = Prompt.Show("The model is encrypted. Enter the file's encryption key:"); if (encryptionKey.Trim().Length == 0) { MessageBox.Show("No encryption key entered. Model decryption cancelled.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } MemoryStream encryptedData = new MemoryStream(); fs.CopyTo(encryptedData); MemoryStream decryptedData = new MemoryStream(); if (!Decryptors[encryptionType](encryptedData.ToArray(), encryptionKey, decryptedData)) { MessageBox.Show("Invalid encrypt key. Model decryption cancelled.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } magicStr = decryptedData.ReadString(); if (magicStr != "DMW") { MessageBox.Show("Error: Decrypted data is corrupted. Model cannot be loaded", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } int decVersion = decryptedData.ReadInt32(); if (decVersion != version) { MessageBox.Show("Error: Decrypted data has been modified or is corrupted. Model cannot be loaded.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } while ((readString = decryptedData.ReadString()) != null) { string[] splString = readString.Split(new char[] { ':' }, 2); if (!model.Metadata.ContainsKey(splString[0])) //Hidden metadata { model.Metadata[splString[0]] = splString[1]; } else if (model.Metadata[splString[0]] != splString[1]) { MessageBox.Show("Error: Decrypted data has been modified or is corrupted. Model cannot be loaded.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } } decryptedData.CopyTo(modelData); } else { fs.CopyTo(modelData); } model.Metadata["ComputedHash"] = Hash.Calculate(modelData.ToArray()); modelData.Position = 0; while (modelData.Position < modelData.Length) { byte mode = (byte)modelData.ReadByte(); int dataLen = modelData.ReadInt32(); long end = modelData.Position + dataLen; while (modelData.Position < end) { switch (mode) { default: //Unsupported type. Just burn though it modelData.ReadByte(); break; case MARKER_VERT: model.Vertices.Add(new Vertex(modelData.ReadFloat(), modelData.ReadFloat(), modelData.ReadFloat())); break; case MARKER_INDEX: model.Faces.Add(new Face(modelData.ReadInt32(), modelData.ReadInt32(), modelData.ReadInt32())); break; } } } } return(true); }
public override bool SaveModel(ref string path, ref Model model) { bool encrypted = false; string encryptionKey = ""; if (MessageBox.Show("Encrypt content?", "Encrypt", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1) == DialogResult.Yes) { encrypted = true; encryptionKey = Prompt.Show("Enter an encryption key:"); if (encryptionKey.Trim().Length == 0) { MessageBox.Show("No encryption key entered. Encryption cancelled.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } if (!path.EndsWith(".enc.dmw")) { path = path.Substring(0, path.LastIndexOf('.')) + ".enc" + path.Substring(path.LastIndexOf('.')); } } else { if (path.EndsWith(".enc.dmw")) { path = path.Substring(0, path.LastIndexOf(".enc")) + path.Substring(path.LastIndexOf('.')); } } MemoryStream data = new MemoryStream(), vertStream = new MemoryStream(), indexStream = new MemoryStream(); foreach (Vertex vert in model.Vertices) { vertStream.WriteFloat(vert.Position.X); vertStream.WriteFloat(vert.Position.Y); vertStream.WriteFloat(vert.Position.Z); } for (int i = 0; i < model.Faces.Count; ++i) { indexStream.WriteInt32(model.Faces[i].Vertex1); indexStream.WriteInt32(model.Faces[i].Vertex2); indexStream.WriteInt32(model.Faces[i].Vertex3); } data.WriteByte(MARKER_VERT); data.WriteInt32((int)vertStream.Length); vertStream.Position = 0; vertStream.CopyTo(data); data.WriteByte(MARKER_INDEX); data.WriteInt32((int)indexStream.Length); indexStream.Position = 0; indexStream.CopyTo(data); model.Metadata["DataHash"] = Hash.Calculate(data.ToArray()); MemoryStream metadata = new MemoryStream(); metadata.WriteString("DMW"); metadata.WriteInt32(DMW_CURRENT_VERSION); foreach (KeyValuePair <StringKey, string> kvp in model.Metadata) { if (kvp.Key.Save) { metadata.WriteString(kvp.Key.KeyText + ":" + kvp.Value); } } metadata.WriteInt16(0); //End of metadata notifier MemoryStream finalFile = new MemoryStream(); metadata.Position = 0; metadata.CopyTo(finalFile); if (encrypted) { finalFile.WriteInt16((short)DefaultEncoder); MemoryStream toEncrypt = new MemoryStream(); metadata.Position = 0; metadata.CopyTo(toEncrypt); data.Position = 0; data.CopyTo(toEncrypt); Encryptors[DefaultEncoder](toEncrypt.ToArray(), encryptionKey, finalFile); } else { finalFile.WriteInt16((short)DMW_DATAENC.None); data.Position = 0; data.CopyTo(finalFile); } File.WriteAllBytes(path, finalFile.ToArray()); return(true); }