private void Decompile(Stream stream) { HSDReader Reader = new HSDReader(stream); HSDHeader Header = Reader.ReadType <HSDHeader>(new HSDHeader()); Roots = new List <HSDRoot>(Header.RootCount); Resources = new List <HSDRoot>(Header.ResourceCount); Reader.Seek(Header.RelocationTableOffset + 0x20); Reader.ReadRelocationTable(Header.RelocationTableCount); // Roots for (int i = 0; i < Header.RootCount; i++) { Roots.Add(new HSDRoot()); Roots[i].Offset = Reader.ReadUInt32() + 0x20; Roots[i].NameOffset = Reader.ReadUInt32(); } // Resources for (int i = 0; i < Header.ResourceCount; i++) { Resources.Add(new HSDRoot()); Resources[i].Offset = Reader.ReadUInt32() + 0x20; Resources[i].NameOffset = Reader.ReadUInt32(); } uint StringOffset = Reader.Position(); foreach (HSDRoot r in Roots) { Reader.Seek(StringOffset + r.NameOffset); r.Name = Reader.ReadString(); r.Open(Reader); } foreach (HSDRoot r in Resources) { Reader.Seek(StringOffset + r.NameOffset); r.Name = Reader.ReadString(); r.Open(Reader); } //Reader.PrintOffsets(); //Clean up Reader.Close(); }
/// <summary> /// Reads properties from the HSDReader stream /// </summary> /// <param name="Reader"></param> public virtual void Open(HSDReader Reader) { foreach (var prop in GetType().GetProperties()) { var attrs = (FieldData[])prop.GetCustomAttributes(typeof(FieldData), false); var type = prop.PropertyType; bool inLine = false; bool ignore = false; foreach (var attr in prop.GetCustomAttributes(false)) { if (attr is FieldData field) { type = field.Type; } if (attr is HSDInLineAttribute inline) { inLine = true; } if (attr is HSDParseIgnoreAttribute) { ignore = true; } } if (ignore) { continue; } if (type.IsSubclassOf(typeof(IHSDNode))) { uint temp = Reader.Position() + 4; IHSDNode field = (IHSDNode)Activator.CreateInstance(type); dynamic changedObj = field; uint Offset = Reader.Position(); if (!inLine) { Offset = Reader.ReadUInt32(); } prop.SetValue(this, Reader.ReadObject(Offset, changedObj)); if (!inLine) { Reader.Seek(temp); } } else if (type == typeof(uint)) { prop.SetValue(this, Reader.ReadUInt32()); } else if (type == typeof(int)) { prop.SetValue(this, Reader.ReadInt32()); } else if (type == typeof(float)) { prop.SetValue(this, Reader.ReadSingle()); } else if (type == typeof(ushort)) { prop.SetValue(this, Reader.ReadUInt16()); } else if (type == typeof(short)) { prop.SetValue(this, Reader.ReadInt16()); } else if (type == typeof(bool)) { prop.SetValue(this, Reader.ReadBoolean()); } else if (type == typeof(string)) { prop.SetValue(this, Reader.ReadString(Reader.ReadInt32())); } else if (type == typeof(byte)) { if (type.IsEnum) { prop.SetValue(this, (Enum)Enum.ToObject(prop.PropertyType, Reader.ReadByte())); } else { prop.SetValue(this, Reader.ReadByte()); } } else if (type.IsEnum) { prop.SetValue(this, (Enum)Enum.ToObject(type, Reader.ReadUInt32())); } else { throw new InvalidOperationException("Failed to read " + type); } } }