Template
*
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace FireTools.Phyre {
|
||||
public class Archive {
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BaseHeader {
|
||||
public FourCC magic;
|
||||
public uint size;
|
||||
public uint objectsTableSize;
|
||||
public FourCC platformId;
|
||||
public uint instanceListCount;
|
||||
public uint arrayFixupSize;
|
||||
public uint arrayFixupCount;
|
||||
public uint pointerFixupSize;
|
||||
public uint pointerFixupCount;
|
||||
public uint pointerArrayFixupSize;
|
||||
public uint pointerArrayFixupCount;
|
||||
public uint pointersInArraysCount;
|
||||
public uint userFixupCount;
|
||||
public uint userFixupDataSize;
|
||||
public uint totalDataSize;
|
||||
public uint headerClassInstanceCount;
|
||||
public uint headerClassChildCount;
|
||||
public uint physicsEngineID;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct DX11Header {
|
||||
public BaseHeader baseHeader;
|
||||
public uint indexBufferSize;
|
||||
public uint vertexBufferSize;
|
||||
public uint maxTextureMipBufferSize;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct PInstanceListHeader
|
||||
{
|
||||
public uint m_classID; // The ID of the class stored in this instance list.
|
||||
public uint m_count; // The number of instances of the class stored in this instance list.
|
||||
public uint m_size; // The size of the data for this instance list in bytes. This should be equal to m_objectsSize + m_arraysSize;
|
||||
public uint m_objectsSize; // The size of the data for the objects in this instance list in bytes. Also includes the padding to make sure that the array data is correctly aligned.
|
||||
public uint m_arraysSize; // The size of the non-object array data in this instance list in bytes
|
||||
public uint m_pointersInArraysCount; // The number of pointers in pointer arrays.
|
||||
public uint m_arrayFixupCount; // The count of array fixups required.
|
||||
public uint m_pointerFixupCount; // The count of pointer fixups required.
|
||||
public uint m_pointerArrayFixupCount; // The count of pointer array fixups required.
|
||||
};
|
||||
|
||||
|
||||
public static PInstanceListHeader ReadInstanceListHeader(Stream data)
|
||||
{
|
||||
return data.ReadStruct<PInstanceListHeader>();
|
||||
}
|
||||
|
||||
public static object ReadHeader(Stream data)
|
||||
{
|
||||
var baseHeader = data.ReadStruct<BaseHeader>();
|
||||
var baseSize = Marshal.SizeOf<BaseHeader>();
|
||||
if (baseHeader.size < baseSize)
|
||||
{
|
||||
throw new Exception("Unexpected header size");
|
||||
}
|
||||
|
||||
if (baseHeader.size == baseSize)
|
||||
{
|
||||
return baseHeader;
|
||||
}
|
||||
|
||||
if (baseHeader.platformId.Value == 0x44583131)
|
||||
{
|
||||
//dx11 platform
|
||||
var dx11Size = Marshal.SizeOf<DX11Header>();
|
||||
var extraBytesCount = dx11Size - baseSize;
|
||||
var extraBytes = data.ReadBytes(extraBytesCount);
|
||||
var baseBytes = MemoryUtils.StructToBytes(baseHeader);
|
||||
List<byte> dx11Bytes = new List<byte>();
|
||||
dx11Bytes.AddRange(baseBytes);
|
||||
dx11Bytes.AddRange(extraBytes);
|
||||
return MemoryUtils.BytesToStruct<DX11Header>(dx11Bytes.ToArray());
|
||||
|
||||
}
|
||||
throw new Exception("Unknown platform");
|
||||
}
|
||||
|
||||
public static ObjectsTable ReadObjectsTable( Stream data)
|
||||
{
|
||||
/*var baseArcHeader = archiveHeader is BaseHeader
|
||||
? (BaseHeader) archiveHeader
|
||||
: ((DX11Header) archiveHeader).baseHeader;*/
|
||||
ObjectsTable result = new ObjectsTable();
|
||||
result.header = data.ReadStruct<ObjectsTable.Header>();
|
||||
result.typeDescriptors = data.ReadStructArray<ObjectsTable.TypeDescriptor>(result.header.typeCount).ToArray();
|
||||
result.classDescriptors = data.ReadStructArray<ObjectsTable.ClassDescriptor>(result.header.classCount).ToArray();
|
||||
result.classMemberDescriptors = data.ReadStructArray<ObjectsTable.ClassMemberDescriptor>(result.header.classMemberCount).ToArray();
|
||||
result.stringTable = data.ReadBytes((int)result.header.stringTableSize);
|
||||
|
||||
var s0 = Marshal.SizeOf<ObjectsTable.Header>();
|
||||
var s1 = Marshal.SizeOf<ObjectsTable.TypeDescriptor>() * result.header.typeCount;
|
||||
var s2 = Marshal.SizeOf<ObjectsTable.ClassDescriptor>() * result.header.classCount;
|
||||
var s3 = Marshal.SizeOf<ObjectsTable.ClassMemberDescriptor>() * result.header.classMemberCount;
|
||||
var s4 = result.header.stringTableSize;
|
||||
|
||||
var paddingSize = result.header.size - (s0 + s1 + s2 + s3 + s4);
|
||||
if (paddingSize != 0)
|
||||
{
|
||||
data.ReadBytes((int)paddingSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*SetBackColor(0x0000ff);
|
||||
Header header;
|
||||
SetBackColor(0x00ff00);
|
||||
PackedNamespaceHeader namespaceHeader;
|
||||
SetBackColor(0xff0000);
|
||||
|
||||
PPackedType namespaceTypes[namespaceHeader.m_typeCount];
|
||||
PPackedClassDescriptor namespaceClassDescriptors[namespaceHeader.m_classCount];
|
||||
PPackedDataMember namespaceDataMembers[namespaceHeader.m_classDataMemberCount];
|
||||
|
||||
CHAR namespaceStringTable[namespaceHeader.m_stringTableSize];*/
|
||||
|
||||
|
||||
//PChar* string table
|
||||
//PUInt8 * default buffers
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FireTools.Phyre {
|
||||
public class FieldInstance
|
||||
{
|
||||
public ObjectsTable.ClassMemberDescriptor descriptor;
|
||||
public object value;
|
||||
}
|
||||
|
||||
public class ClassInstance
|
||||
{
|
||||
public ClassInstance parentInstance;
|
||||
public ObjectsTable.Class thisClass;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace FireTools.Phyre {
|
||||
public class ObjectsTable {
|
||||
public struct Header {
|
||||
public uint magic;
|
||||
public uint size;
|
||||
public uint typeCount;
|
||||
public uint classCount;
|
||||
public uint classMemberCount;
|
||||
public uint stringTableSize;
|
||||
public uint someBufferCount;
|
||||
public uint someBufferSize;
|
||||
}
|
||||
|
||||
public struct TypeDescriptor {
|
||||
public uint nameOffset;
|
||||
}
|
||||
|
||||
public struct ClassDescriptor {
|
||||
public int baseClassID; // 0 implies not set, positive implies local, negative implies global.
|
||||
public uint sizeInBytesAndAlignment; // The size of this class in bytes with the alignment shift in the top 4 bits.
|
||||
public uint nameOffset; // The offset to the name of this class in the string table.
|
||||
public uint classDataMemberCount; // The number of data members in this class.
|
||||
public uint offsetFromParent; // The offset of the start of this class from the start of the parent class.
|
||||
public uint offsetToBase; // The offset of the start of this class from the start of the PBase class.
|
||||
public uint offsetToBaseInAllocatedBlock; // The offset of the start of the PBase class in a block allocated for this class.
|
||||
public uint flags; // The flags for this class.
|
||||
public uint defaultBufferOffset; // 0 implies not saved. Subtract one to get the correct default buffer offset if non-zero.
|
||||
}
|
||||
|
||||
public struct ClassMemberDescriptor {
|
||||
public uint nameOffset; // The offset to the name of this member in the string table.
|
||||
public uint typeID; // The type of this member
|
||||
public uint valueOffset; // The offset to the value of this member in the class.
|
||||
public uint sizeInBytes; // The size of this member in bytes.
|
||||
public uint flags; // The flags for this member.
|
||||
public uint fixedArraySize; // If non zero, this represents the size of a fixed size array.
|
||||
}
|
||||
|
||||
public Header header;
|
||||
public TypeDescriptor[] typeDescriptors;
|
||||
public ClassDescriptor[] classDescriptors;
|
||||
public ClassMemberDescriptor[] classMemberDescriptors;
|
||||
public byte[] stringTable;
|
||||
|
||||
public class ClassMember
|
||||
{
|
||||
public Type fieldType;
|
||||
public string name;
|
||||
public uint offset;
|
||||
public uint size;
|
||||
public uint flags;
|
||||
public uint fixedArraySize;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Type
|
||||
{
|
||||
public string name;
|
||||
public override string ToString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public class Class : Type
|
||||
{
|
||||
public Class baseClass;
|
||||
public List<ClassMember> members = new List<ClassMember>();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var baseStr = baseClass == null ? "" : $" Base: {baseClass.name}";
|
||||
return $"Name: {name} Members: {members.Count} Local members size: {members.Sum(v=>v.size)} {baseStr}";
|
||||
}
|
||||
}
|
||||
|
||||
public class ExternalClass : Class {
|
||||
public ExternalClass()
|
||||
{
|
||||
name = "ExternalClass";
|
||||
}
|
||||
}
|
||||
|
||||
public Type[] Types;
|
||||
public Class[] Classes;
|
||||
|
||||
|
||||
public void ParseTypes()
|
||||
{
|
||||
Types = new Type[typeDescriptors.Length];
|
||||
|
||||
for (uint i = 0; i < Types.Length; ++i) {
|
||||
Types[i] = new Type();
|
||||
Types[i].name = ReadString((int)typeDescriptors[i].nameOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public void ParseClasses() {
|
||||
Classes = new Class[classDescriptors.Length];
|
||||
for (uint m = 0; m < Classes.Length; ++m)
|
||||
{
|
||||
Classes[m] = new Class();
|
||||
}
|
||||
|
||||
|
||||
int memberId = 0;
|
||||
|
||||
for (uint i = 0; i < Classes.Length; ++i)
|
||||
{
|
||||
var c = classDescriptors[i];
|
||||
var cls = Classes[i];
|
||||
|
||||
cls.name = ReadString((int) c.nameOffset);
|
||||
|
||||
|
||||
if (c.baseClassID < 0)
|
||||
{
|
||||
cls.baseClass = new ExternalClass();
|
||||
}else if (c.baseClassID > 0)
|
||||
{
|
||||
cls.baseClass = Classes[c.baseClassID - 1 ];
|
||||
}
|
||||
|
||||
for (uint m = 0; m < c.classDataMemberCount; ++m)
|
||||
{
|
||||
var d = classMemberDescriptors[memberId++];
|
||||
ClassMember mem = new ClassMember();
|
||||
mem.size = d.sizeInBytes;
|
||||
mem.fixedArraySize = d.fixedArraySize;
|
||||
mem.flags = d.flags;
|
||||
mem.offset = d.valueOffset;
|
||||
mem.name = ReadString((int)d.nameOffset);
|
||||
|
||||
Console.WriteLine("Member type ID: " + d.typeID);
|
||||
|
||||
if (d.typeID >= Types.Length) {
|
||||
mem.fieldType = Classes[(int)d.typeID - Types.Length - 1];
|
||||
} else {
|
||||
mem.fieldType = Types[(int)d.typeID];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cls.members.Add(mem);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void Unpack()
|
||||
{
|
||||
ParseTypes();
|
||||
ParseClasses();
|
||||
}
|
||||
|
||||
public string ReadString(int offset)
|
||||
{
|
||||
var handle = GCHandle.Alloc(stringTable, GCHandleType.Pinned);
|
||||
var result = Marshal.PtrToStringAnsi(handle.AddrOfPinnedObject() + offset);
|
||||
handle.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user