Fixed XmlMeta and MetaXML flags/hash conversion bugs.

This commit is contained in:
dexyfex 2018-05-01 15:03:35 +10:00
parent 176da9faf1
commit 6ae802a910
2 changed files with 105 additions and 50 deletions

View File

@ -1646,7 +1646,12 @@ namespace CodeWalker.GameFiles
public static string FormatHash(MetaHash h) //for use with WriteItemArray public static string FormatHash(MetaHash h) //for use with WriteItemArray
{ {
return h.ToString(); var str = JenkIndex.TryGetString(h);
if (!string.IsNullOrEmpty(str)) return str;
str = GlobalText.TryGetString(h);
if (!string.IsNullOrEmpty(str)) return str;
return HashString(h);// "hash_" + h.Hex;
//return h.ToString();
} }
public static string FormatVector2(Vector2 v) //for use with WriteItemArray public static string FormatVector2(Vector2 v) //for use with WriteItemArray
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml; using System.Xml;
using SharpDX; using SharpDX;
@ -182,7 +183,7 @@ namespace CodeWalker.GameFiles
mb.AddEnumInfo(_infos.EnumNameHash); mb.AddEnumInfo(_infos.EnumNameHash);
int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText); int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText, entry.DataType);
Write(val, data, entry.DataOffset); Write(val, data, entry.DataOffset);
break; break;
} }
@ -193,7 +194,7 @@ namespace CodeWalker.GameFiles
mb.AddEnumInfo(_infos.EnumNameHash); mb.AddEnumInfo(_infos.EnumNameHash);
int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText); int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText, entry.DataType);
Write((short)val, data, entry.DataOffset); Write((short)val, data, entry.DataOffset);
break; break;
} }
@ -296,11 +297,16 @@ namespace CodeWalker.GameFiles
private static void GetParsedArrayOfBytes(XmlNode node, byte[] data, MetaStructureEntryInfo_s entry, MetaStructureEntryInfo_s arrEntry) private static void GetParsedArrayOfBytes(XmlNode node, byte[] data, MetaStructureEntryInfo_s entry, MetaStructureEntryInfo_s arrEntry)
{ {
int offset = entry.DataOffset; int offset = entry.DataOffset;
string[] split;
var ns = NumberStyles.Any;
var ic = CultureInfo.InvariantCulture;
var sa = new[] { ' ' };
var so = StringSplitOptions.RemoveEmptyEntries;
var split = node.InnerText.Trim().Split(sa, so); //split = Split(node.InnerText, 2); to read as unsplitted HEX
switch (arrEntry.DataType) switch (arrEntry.DataType)
{ {
default: default: //expecting hex string.
split = Split(node.InnerText, 2); split = Split(node.InnerText, 2);
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
@ -309,67 +315,81 @@ namespace CodeWalker.GameFiles
offset += sizeof(byte); offset += sizeof(byte);
} }
break; break;
case MetaStructureEntryDataType.SignedByte: case MetaStructureEntryDataType.SignedByte: //expecting space-separated array.
split = node.InnerText.Split(); //split = Split(node.InnerText, 2); to read as unsplitted HEX
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
sbyte val = Convert.ToSByte(split[j], 10); sbyte val;// = Convert.ToSByte(split[j], 10);
data[offset] = (byte)val; if (sbyte.TryParse(split[j].Trim(), ns, ic, out val))
offset += sizeof(sbyte); {
data[offset] = (byte)val;
offset += sizeof(sbyte);
}
} }
break; break;
case MetaStructureEntryDataType.UnsignedByte: case MetaStructureEntryDataType.UnsignedByte: //expecting space-separated array.
split = node.InnerText.Split();
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
byte val = Convert.ToByte(split[j], 10); byte val;// = Convert.ToByte(split[j], 10);
data[offset] = val; if (byte.TryParse(split[j].Trim(), ns, ic, out val))
offset += sizeof(byte); {
data[offset] = val;
offset += sizeof(byte);
}
} }
break; break;
case MetaStructureEntryDataType.SignedShort: case MetaStructureEntryDataType.SignedShort: //expecting space-separated array.
split = node.InnerText.Split();
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
short val = Convert.ToInt16(split[j], 10); short val;// = Convert.ToInt16(split[j], 10);
Write(val, data, offset); if (short.TryParse(split[j].Trim(), ns, ic, out val))
offset += sizeof(short); {
Write(val, data, offset);
offset += sizeof(short);
}
} }
break; break;
case MetaStructureEntryDataType.UnsignedShort: case MetaStructureEntryDataType.UnsignedShort: //expecting space-separated array.
split = node.InnerText.Split();
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
ushort val = Convert.ToUInt16(split[j], 10); ushort val;// = Convert.ToUInt16(split[j], 10);
Write(val, data, offset); if (ushort.TryParse(split[j].Trim(), ns, ic, out val))
offset += sizeof(ushort); {
Write(val, data, offset);
offset += sizeof(ushort);
}
} }
break; break;
case MetaStructureEntryDataType.SignedInt: case MetaStructureEntryDataType.SignedInt: //expecting space-separated array.
split = node.InnerText.Split();
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
int val = Convert.ToInt32(split[j], 10); int val;// = Convert.ToInt32(split[j], 10);
Write(val, data, offset); if (int.TryParse(split[j].Trim(), ns, ic, out val))
offset += sizeof(int); {
Write(val, data, offset);
offset += sizeof(int);
}
} }
break; break;
case MetaStructureEntryDataType.UnsignedInt: case MetaStructureEntryDataType.UnsignedInt: //expecting space-separated array.
split = node.InnerText.Split();
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
uint val = Convert.ToUInt32(split[j], 10); uint val;// = Convert.ToUInt32(split[j], 10);
Write(val, data, offset); if (uint.TryParse(split[j].Trim(), ns, ic, out val))
offset += sizeof(uint); {
Write(val, data, offset);
offset += sizeof(uint);
}
} }
break; break;
case MetaStructureEntryDataType.Float: case MetaStructureEntryDataType.Float: //expecting space-separated array.
split = node.InnerText.Split();
for (int j = 0; j < split.Length; j++) for (int j = 0; j < split.Length; j++)
{ {
float val = FloatUtil.Parse(split[j]); float val;// = FloatUtil.Parse(split[j]);
Write(val, data, offset); if (FloatUtil.TryParse(split[j].Trim(), out val))
offset += sizeof(float); {
Write(val, data, offset);
offset += sizeof(float);
}
} }
break; break;
} }
@ -685,12 +705,8 @@ namespace CodeWalker.GameFiles
return chunks.ToArray(); return chunks.ToArray();
} }
private static int GetEnumInt(MetaName type, string enumString) private static int GetEnumInt(MetaName type, string enumString, MetaStructureEntryDataType dataType)
{ {
//BUG: needs to handle multiple flags!!!
var enumName = (MetaName)(uint)GetHash(enumString);
var infos = MetaTypes.GetEnumInfo(type); var infos = MetaTypes.GetEnumInfo(type);
if (infos == null) if (infos == null)
@ -698,13 +714,47 @@ namespace CodeWalker.GameFiles
return 0; return 0;
} }
for (int j = 0; j < infos.Entries.Length; j++)
{
var entry = infos.Entries[j];
if (entry.EntryNameHash == enumName) bool isFlags = (dataType == MetaStructureEntryDataType.IntFlags1) ||
(dataType == MetaStructureEntryDataType.IntFlags2);// ||
//(dataType == MetaStructureEntryDataType.ShortFlags);
if (isFlags)
{
//flags enum. (multiple values, comma-separated)
var split = enumString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
int enumVal = 0;
for (int i = 0; i < split.Length; i++)
{ {
return entry.EntryValue; var enumName = (MetaName)(uint)GetHash(split[i].Trim());
for (int j = 0; j < infos.Entries.Length; j++)
{
var entry = infos.Entries[j];
if (entry.EntryNameHash == enumName)
{
enumVal += (1 << entry.EntryValue);
}
}
}
return enumVal;
}
else
{
//single value enum.
var enumName = (MetaName)(uint)GetHash(enumString);
for (int j = 0; j < infos.Entries.Length; j++)
{
var entry = infos.Entries[j];
if (entry.EntryNameHash == enumName)
{
return entry.EntryValue;
}
} }
} }