Skip to content

Commit

Permalink
Add support for games that encode CryXmlB in LittleEndian format
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-dolkens committed Apr 8, 2016
1 parent f8f0a94 commit baf190e
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 27 deletions.
160 changes: 135 additions & 25 deletions HoloXPLOR.DataForge/CryXmlB/CryXmlSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,115 @@

namespace HoloXPLOR.DataForge
{
public enum ByteOrderEnum
{
AutoDetect,
BigEndian,
LittleEndian,
}

public static class CryXmlSerializer
{
public static Int64 ReadInt64(this BinaryReader br, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian)
{
var bytes = new Byte[] {
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
};

if (byteOrder == ByteOrderEnum.LittleEndian)
bytes = bytes.Reverse().ToArray();

return BitConverter.ToInt64(bytes, 0);
}

public static XmlDocument ReadFile(String inFile, Boolean writeLog = false)
public static Int32 ReadInt32(this BinaryReader br, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian)
{
return CryXmlSerializer.ReadStream(File.OpenRead(inFile), writeLog);
var bytes = new Byte[] {
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
};

if (byteOrder == ByteOrderEnum.LittleEndian)
bytes = bytes.Reverse().ToArray();

return BitConverter.ToInt32(bytes, 0);
}

public static XmlDocument ReadStream(Stream inStream, Boolean writeLog = false)
public static Int16 ReadInt16(this BinaryReader br, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian)
{
var bytes = new Byte[] {
br.ReadByte(),
br.ReadByte(),
};

if (byteOrder == ByteOrderEnum.LittleEndian)
bytes = bytes.Reverse().ToArray();

return BitConverter.ToInt16(bytes, 0);
}

public static UInt64 ReadUInt64(this BinaryReader br, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian)
{
var bytes = new Byte[] {
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
};

if (byteOrder == ByteOrderEnum.LittleEndian)
bytes = bytes.Reverse().ToArray();

return BitConverter.ToUInt64(bytes, 0);
}

public static UInt32 ReadUInt32(this BinaryReader br, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian)
{
var bytes = new Byte[] {
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
br.ReadByte(),
};

if (byteOrder == ByteOrderEnum.LittleEndian)
bytes = bytes.Reverse().ToArray();

return BitConverter.ToUInt32(bytes, 0);
}

public static UInt16 ReadUInt16(this BinaryReader br, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian)
{
var bytes = new Byte[] {
br.ReadByte(),
br.ReadByte(),
};

if (byteOrder == ByteOrderEnum.LittleEndian)
bytes = bytes.Reverse().ToArray();

return BitConverter.ToUInt16(bytes, 0);
}

public static XmlDocument ReadFile(String inFile, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian, Boolean writeLog = false)
{
return CryXmlSerializer.ReadStream(File.OpenRead(inFile), byteOrder, writeLog);
}

public static XmlDocument ReadStream(Stream inStream, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian, Boolean writeLog = false)
{
using (BinaryReader br = new BinaryReader(inStream))
{
Expand All @@ -43,22 +143,32 @@ public static XmlDocument ReadStream(Stream inStream, Boolean writeLog = false)
}

var headerLength = br.BaseStream.Position;
var fileLength = br.ReadInt32();

var nodeTableOffset = br.ReadInt32();
var nodeTableCount = br.ReadInt32();
byteOrder = ByteOrderEnum.BigEndian;

var fileLength = br.ReadInt32(byteOrder);

if (fileLength != br.BaseStream.Length)
{
br.BaseStream.Seek(headerLength, SeekOrigin.Begin);
byteOrder = ByteOrderEnum.LittleEndian;
fileLength = br.ReadInt32(byteOrder);
}

var nodeTableOffset = br.ReadInt32(byteOrder);
var nodeTableCount = br.ReadInt32(byteOrder);
var nodeTableSize = 28;

var referenceTableOffset = br.ReadInt32();
var referenceTableCount = br.ReadInt32();
var referenceTableOffset = br.ReadInt32(byteOrder);
var referenceTableCount = br.ReadInt32(byteOrder);
var referenceTableSize = 8;

var offset3 = br.ReadInt32();
var count3 = br.ReadInt32();
var offset3 = br.ReadInt32(byteOrder);
var count3 = br.ReadInt32(byteOrder);
var length3 = 4;

var contentOffset = br.ReadInt32();
var contentLength = br.ReadInt32();
var contentOffset = br.ReadInt32(byteOrder);
var contentLength = br.ReadInt32(byteOrder);

if (writeLog)
{
Expand Down Expand Up @@ -87,14 +197,14 @@ public static XmlDocument ReadStream(Stream inStream, Boolean writeLog = false)
var value = new CryXmlNode
{
NodeID = nodeID++,
NodeNameOffset = br.ReadInt32(),
ItemType = br.ReadInt32(),
AttributeCount = br.ReadInt16(),
ChildCount = br.ReadInt16(),
ParentNodeID = br.ReadInt32(),
FirstAttributeIndex = br.ReadInt32(),
FirstChildIndex = br.ReadInt32(),
Reserved = br.ReadInt32(),
NodeNameOffset = br.ReadInt32(byteOrder),
ItemType = br.ReadInt32(byteOrder),
AttributeCount = br.ReadInt16(byteOrder),
ChildCount = br.ReadInt16(byteOrder),
ParentNodeID = br.ReadInt32(byteOrder),
FirstAttributeIndex = br.ReadInt32(byteOrder),
FirstChildIndex = br.ReadInt32(byteOrder),
Reserved = br.ReadInt32(byteOrder),
};

nodeTable.Add(value);
Expand Down Expand Up @@ -127,8 +237,8 @@ public static XmlDocument ReadStream(Stream inStream, Boolean writeLog = false)
var position = br.BaseStream.Position;
var value = new CryXmlReference
{
NameOffset = br.ReadInt32(),
ValueOffset = br.ReadInt32()
NameOffset = br.ReadInt32(byteOrder),
ValueOffset = br.ReadInt32(byteOrder)
};

attributeTable.Add(value);
Expand All @@ -148,7 +258,7 @@ public static XmlDocument ReadStream(Stream inStream, Boolean writeLog = false)
while (br.BaseStream.Position < offset3 + count3 * length3)
{
var position = br.BaseStream.Position;
var value = br.ReadInt32();
var value = br.ReadInt32(byteOrder);

table3.Add(value);
if (writeLog)
Expand Down Expand Up @@ -218,11 +328,11 @@ public static XmlDocument ReadStream(Stream inStream, Boolean writeLog = false)
}
}

public static TObject Deserialize<TObject>(String inFile) where TObject : class
public static TObject Deserialize<TObject>(String inFile, ByteOrderEnum byteOrder = ByteOrderEnum.BigEndian, Boolean writeLog = false) where TObject : class
{
using (MemoryStream ms = new MemoryStream())
{
var xmlDoc = CryXmlSerializer.ReadFile(inFile);
var xmlDoc = CryXmlSerializer.ReadFile(inFile, byteOrder, writeLog);

xmlDoc.Save(ms);

Expand Down
5 changes: 3 additions & 2 deletions HoloXPLOR.DataForge/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public static class Program

public static void Main(params String[] args)
{
args = new String[] { "Game.dcb" };
// args = new String[] { "LevelNames.xml" };
// args = new String[] { "ptv_low_background.mtl" };
// args = new String[] { @"O:\Mods\BuildXPLOR\_manifest\333246" };

if ((args.Length > 0) && Directory.Exists(args[0]))
Expand Down Expand Up @@ -70,7 +71,7 @@ public static void Process(params String[] args)
}
else
{
var xml = CryXmlSerializer.ReadFile(args[0]);
var xml = CryXmlSerializer.ReadFile(args[0], ByteOrderEnum.AutoDetect);

if (xml != null)
{
Expand Down

0 comments on commit baf190e

Please sign in to comment.