mirror of
https://github.com/BtbN/ClanServer.git
synced 2026-09-07 07:55:16 -05:00
KBinXML logic fully implemented
This commit is contained in:
@@ -168,10 +168,13 @@ namespace eAmuseCore.KBinXML
|
||||
return input.Select(v => (object)v);
|
||||
}
|
||||
|
||||
public static IEnumerable<byte> TakeByteArrayAligned(ref IEnumerable<byte> input)
|
||||
public static IEnumerable<byte> TakeBytesAligned(ref IEnumerable<byte> input, int size = -1)
|
||||
{
|
||||
int size = input.FirstS32();
|
||||
input = input.Skip(4);
|
||||
if (size < 0)
|
||||
{
|
||||
size = input.FirstS32();
|
||||
input = input.Skip(4);
|
||||
}
|
||||
|
||||
var res = input.Take(size);
|
||||
input = input.Skip(size);
|
||||
@@ -183,9 +186,9 @@ namespace eAmuseCore.KBinXML
|
||||
return res;
|
||||
}
|
||||
|
||||
public static string TakeStringAligned(ref IEnumerable<byte> input, Encoding encoding)
|
||||
public static string TakeStringAligned(ref IEnumerable<byte> input, Encoding encoding, int size = -1)
|
||||
{
|
||||
byte[] data = TakeByteArrayAligned(ref input).ToArray();
|
||||
byte[] data = TakeBytesAligned(ref input, size).ToArray();
|
||||
return encoding.GetString(data, 0, data.Length - 1); // drop final null byte
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,8 +89,6 @@ namespace eAmuseCore.KBinXML
|
||||
}
|
||||
input = input.Skip(1);
|
||||
|
||||
Console.WriteLine("Compressed: " + compressed);
|
||||
|
||||
byte encodingSig = input.FirstU8();
|
||||
input = input.Skip(1);
|
||||
|
||||
@@ -111,6 +109,9 @@ namespace eAmuseCore.KBinXML
|
||||
|
||||
private void ParseNodes(IEnumerable<byte> nodeBuf, IEnumerable<byte> dataBuf, bool compressed)
|
||||
{
|
||||
IEnumerable<byte> dataByteBuf = Enumerable.Empty<byte>();
|
||||
IEnumerable<byte> dataWordBuf = Enumerable.Empty<byte>();
|
||||
|
||||
uint dataSize = dataBuf.FirstU32();
|
||||
dataBuf = dataBuf.Skip(4);
|
||||
|
||||
@@ -147,9 +148,6 @@ namespace eAmuseCore.KBinXML
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Name: " + name);
|
||||
Console.WriteLine("Type: " + nodeType);
|
||||
|
||||
XmlTypes.Entry nodeTypeEntry = null;
|
||||
bool startNode = false;
|
||||
|
||||
@@ -158,7 +156,6 @@ namespace eAmuseCore.KBinXML
|
||||
case XmlTypes.AttrType:
|
||||
string attrVal = EnumHelpers.TakeStringAligned(ref dataBuf, encoding);
|
||||
node.SetAttributeValue(name, attrVal);
|
||||
Console.WriteLine("Attr val: " + attrVal);
|
||||
break;
|
||||
case XmlTypes.NodeEndType:
|
||||
node = node.Parent;
|
||||
@@ -185,9 +182,68 @@ namespace eAmuseCore.KBinXML
|
||||
|
||||
if (startNode)
|
||||
continue;
|
||||
|
||||
node.SetAttributeValue("__type", nodeTypeEntry.names[0]);
|
||||
|
||||
int varCount = nodeTypeEntry.count;
|
||||
int arrCount = 1;
|
||||
if (varCount < 0)
|
||||
{
|
||||
varCount = dataBuf.FirstS32();
|
||||
dataBuf = dataBuf.Skip(4);
|
||||
isArray = true;
|
||||
}
|
||||
else if (isArray)
|
||||
{
|
||||
arrCount = dataBuf.FirstS32() / (nodeTypeEntry.size * nodeTypeEntry.count);
|
||||
dataBuf = dataBuf.Skip(4);
|
||||
node.SetAttributeValue("__count", arrCount);
|
||||
}
|
||||
int totCount = arrCount * varCount;
|
||||
int totSize = totCount * nodeTypeEntry.size;
|
||||
|
||||
IEnumerable<byte> data = null;
|
||||
if (isArray || totSize > 2)
|
||||
{
|
||||
data = EnumHelpers.TakeBytesAligned(ref dataBuf, totCount * nodeTypeEntry.size);
|
||||
}
|
||||
else if (totSize == 1)
|
||||
{
|
||||
if (!dataByteBuf.Any())
|
||||
{
|
||||
dataByteBuf = dataBuf;
|
||||
dataBuf = dataBuf.Skip(4);
|
||||
}
|
||||
data = dataByteBuf.Take(1);
|
||||
dataByteBuf = dataByteBuf.Skip(1);
|
||||
}
|
||||
else if(totSize == 2)
|
||||
{
|
||||
if (!dataWordBuf.Any())
|
||||
{
|
||||
dataWordBuf = dataBuf;
|
||||
dataBuf = dataBuf.Skip(4);
|
||||
}
|
||||
data = dataWordBuf.Take(2);
|
||||
dataWordBuf = dataWordBuf.Skip(2);
|
||||
}
|
||||
|
||||
if (nodeType == XmlTypes.Bin.nodeType)
|
||||
{
|
||||
node.SetAttributeValue("__size", totCount);
|
||||
node.Value = string.Join("", data.Select(b => Convert.ToString(b, 16).PadLeft(2, '0')));
|
||||
}
|
||||
else if (nodeType == XmlTypes.Str.nodeType)
|
||||
{
|
||||
node.Value = encoding.GetString(data.ToArray(), 0, totCount - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.Value = string.Join(" ", XmlTypes.DataToString(data, nodeTypeEntry));
|
||||
}
|
||||
}
|
||||
|
||||
doc = new XDocument(fakeroot.Elements().First());
|
||||
doc = new XDocument(fakeroot.FirstNode);
|
||||
Console.WriteLine(doc.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace eAmuseCore.KBinXML
|
||||
public int size = 0;
|
||||
public int count = 0;
|
||||
public Type type = typeof(object);
|
||||
public Func<IEnumerable<byte>, IEnumerable<object>> read = _ => Enumerable.Empty<object>();
|
||||
public Func<IEnumerable<byte>, string> toString;
|
||||
}
|
||||
|
||||
public static readonly Entry Void = new Entry
|
||||
@@ -36,7 +36,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 1,
|
||||
count = 1,
|
||||
type = typeof(sbyte),
|
||||
read = input => input.TakeS8(1).Box(),
|
||||
toString = input => input.FirstS8().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry U8 = new Entry
|
||||
@@ -46,7 +46,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 1,
|
||||
count = 1,
|
||||
type = typeof(byte),
|
||||
read = input => input.TakeU8(1).Box(),
|
||||
toString = input => input.FirstU8().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry S16 = new Entry
|
||||
@@ -56,7 +56,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 2,
|
||||
count = 1,
|
||||
type = typeof(short),
|
||||
read = input => input.TakeS16(1).Box(),
|
||||
toString = input => input.FirstS16().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry U16 = new Entry
|
||||
@@ -66,7 +66,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 2,
|
||||
count = 1,
|
||||
type = typeof(ushort),
|
||||
read = input => input.TakeU16(1).Box(),
|
||||
toString = input => input.FirstU16().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry S32 = new Entry
|
||||
@@ -76,7 +76,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 4,
|
||||
count = 1,
|
||||
type = typeof(int),
|
||||
read = input => input.TakeS32(1).Box(),
|
||||
toString = input => input.FirstS32().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry U32 = new Entry
|
||||
@@ -86,7 +86,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 4,
|
||||
count = 1,
|
||||
type = typeof(int),
|
||||
read = input => input.TakeU32(1).Box(),
|
||||
toString = input => input.FirstU32().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry S64 = new Entry
|
||||
@@ -96,7 +96,7 @@ namespace eAmuseCore.KBinXML
|
||||
size = 8,
|
||||
count = 1,
|
||||
type = typeof(int),
|
||||
read = input => input.TakeS64(1).Box(),
|
||||
toString = input => input.FirstS64().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry U64 = new Entry
|
||||
@@ -106,27 +106,27 @@ namespace eAmuseCore.KBinXML
|
||||
size = 8,
|
||||
count = 1,
|
||||
type = typeof(int),
|
||||
read = input => input.TakeU64(1).Box(),
|
||||
toString = input => input.FirstU64().ToString(),
|
||||
};
|
||||
|
||||
public static readonly Entry Bin = new Entry
|
||||
{
|
||||
names = new[] { "bin", "binary" },
|
||||
nodeType = 10,
|
||||
size = 4,
|
||||
size = 1,
|
||||
count = -1,
|
||||
type = typeof(byte[]),
|
||||
read = input => input.TakeU64(1).Box(),
|
||||
type = typeof(byte),
|
||||
toString = null, // special case, cannot be handled here
|
||||
};
|
||||
|
||||
public static readonly Entry Str = new Entry
|
||||
{
|
||||
names = new[] { "str", "string" },
|
||||
nodeType = 11,
|
||||
size = 4,
|
||||
size = 1,
|
||||
count = -1,
|
||||
type = typeof(byte[]),
|
||||
read = input => input.TakeU64(1).Box(),
|
||||
type = typeof(byte),
|
||||
toString = null, // special case, cannot be handled here
|
||||
};
|
||||
|
||||
private static Dictionary<string, Entry> nameLookupMap = new Dictionary<string, Entry>();
|
||||
@@ -169,5 +169,14 @@ namespace eAmuseCore.KBinXML
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> DataToString(IEnumerable<byte> dataBuf, Entry entry)
|
||||
{
|
||||
while (dataBuf.Any())
|
||||
{
|
||||
yield return entry.toString(dataBuf);
|
||||
dataBuf = dataBuf.Skip(entry.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace eAmuseTest
|
||||
else if (compress != "none")
|
||||
throw new ArgumentException("Unsupported compression algorithm");
|
||||
|
||||
Console.WriteLine("" + ((3 - 4) % 4));
|
||||
Console.WriteLine(BitConverter.ToString(new byte[] { 1, 2, 3, 4 }));
|
||||
|
||||
KBinXML kbinxml = new KBinXML(rawData);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user