/// <summary> /// Saves properties to the HSDWriter /// </summary> /// <param name="Writer"></param> public virtual void Save(HSDWriter Writer) { // Write child node data first foreach (var prop in GetType().GetProperties().Reverse()) { var type = prop.PropertyType; var inLine = false; var ignore = false; foreach (var attr in prop.GetCustomAttributes(false)) { if (attr is FieldData data) { type = data.Type; } if (attr is HSDParseIgnoreAttribute) { ignore = true; } if (attr is HSDInLineAttribute) { inLine = true; } } if (ignore) { continue; } if (type.IsSubclassOf(typeof(IHSDNode))) { if ((!inLine) && prop.GetValue(this) != null) { Writer.WriteObject(((IHSDNode)prop.GetValue(this))); } } } // Write this objects attributes Writer.AddObject(this); foreach (var prop in GetType().GetProperties()) { var type = prop.PropertyType; var inLine = false; var ignore = false; foreach (var attr in prop.GetCustomAttributes(false)) { if (attr is FieldData data) { type = data.Type; } if (attr is HSDParseIgnoreAttribute) { ignore = true; } if (attr is HSDInLineAttribute) { inLine = true; } } if (ignore) { continue; } if (type.IsSubclassOf(typeof(IHSDNode))) { if (inLine) { Writer.WriteObject(((IHSDNode)prop.GetValue(this))); } else { Writer.WritePointer(prop.GetValue(this)); } /*uint temp = Reader.Position() + 4; * IHSDNode field = (IHSDNode)Activator.CreateInstance(attr.Type); * dynamic changedObj = field; * uint Offset = Reader.Position(); * if (!attr.InLine) Offset = Reader.ReadUInt32(); * //Console.WriteLine(attr.Type + " " + Offset.ToString("X")); * prop.SetValue(this, Reader.ReadObject(Offset, changedObj)); * if (!attr.InLine) Reader.Seek(temp);*/ } else if (type == typeof(uint)) { Writer.Write((uint)prop.GetValue(this)); } else if (type == typeof(int)) { Writer.Write((int)prop.GetValue(this)); } else if (type == typeof(float)) { Writer.Write((float)prop.GetValue(this)); } else if (type == typeof(ushort)) { Writer.Write((ushort)prop.GetValue(this)); } else if (type == typeof(short)) { Writer.Write((short)prop.GetValue(this)); } else if (type == typeof(bool)) { Writer.Write((bool)prop.GetValue(this)); } else if (type == typeof(string)) { if ((string)prop.GetValue(this) != "") { Writer.WritePointer(prop.GetValue(this)); } else { Writer.Write(0); } } else if (type == typeof(byte)) { if (prop.PropertyType.IsEnum) { Writer.Write((byte)(int)prop.GetValue(this)); } else { Writer.Write((byte)prop.GetValue(this)); } } else if (type.IsEnum) { Writer.Write((int)prop.GetValue(this)); } else { throw new Exception("Failed to write " + type); } } }
/// <summary> /// Saves the HSDFile as a .dat /// </summary> /// <param name="FileName"></param> public void Save(string FileName) { HSDWriter Writer = new HSDWriter(new FileStream(FileName, FileMode.Create)); Writer.Write(0); Writer.Write(0); Writer.Write(0); Writer.Write(Roots.Count); Writer.Write(Resources.Count); Writer.Write(0); Writer.Write(0); Writer.Write(0); // Write Data Writer.Mode = WriterWriteMode.STRING; foreach (HSDRoot r in Roots) { r.Save(Writer); } foreach (HSDRoot r in Resources) { r.Save(Writer); } Writer.Mode = WriterWriteMode.BUFFER; foreach (HSDRoot r in Roots) { r.Save(Writer); } foreach (HSDRoot r in Resources) { r.Save(Writer); } Writer.Mode = WriterWriteMode.NORMAL; foreach (HSDRoot r in Roots) { r.Save(Writer); } foreach (HSDRoot r in Resources) { r.Save(Writer); } Writer.Mode = WriterWriteMode.TEXTURE; foreach (HSDRoot r in Roots) { r.Save(Writer); } foreach (HSDRoot r in Resources) { r.Save(Writer); } Writer.Mode = WriterWriteMode.NORMAL; //write relocation table uint RelocOffset = (uint)Writer.BaseStream.Position; uint RelocCount = (uint)Writer.WriteRelocationTable(); // Write Strings int stringoff = 0; foreach (HSDRoot r in Roots) { Writer.WritePointer(r.Node); Writer.Write((uint)stringoff); stringoff += r.Name.Length + 1; } foreach (HSDRoot r in Resources) { Writer.WritePointer(r.Node); Writer.Write((uint)stringoff); stringoff += r.Name.Length + 1; } foreach (HSDRoot r in Roots) { Writer.WriteNullString(r.Name); } foreach (HSDRoot r in Resources) { Writer.WriteNullString(r.Name); } //write root offsets and strings Writer.WriteAt(4, RelocOffset - 0x20); Writer.WriteAt(8, RelocCount); Writer.WriteAt(0, (uint)Writer.BaseStream.Position); Writer.WriteRelocationTable(false); Writer.Close(); }