mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-29 18:32:55 +08:00
XML/RBF conversion
This commit is contained in:
parent
e31e401fa8
commit
e3bbd29b33
@ -99,6 +99,7 @@
|
|||||||
<Compile Include="GameFiles\MetaTypes\Rbf.cs" />
|
<Compile Include="GameFiles\MetaTypes\Rbf.cs" />
|
||||||
<Compile Include="GameFiles\MetaTypes\XmlMeta.cs" />
|
<Compile Include="GameFiles\MetaTypes\XmlMeta.cs" />
|
||||||
<Compile Include="GameFiles\MetaTypes\XmlPso.cs" />
|
<Compile Include="GameFiles\MetaTypes\XmlPso.cs" />
|
||||||
|
<Compile Include="GameFiles\MetaTypes\XmlRbf.cs" />
|
||||||
<Compile Include="GameFiles\Resources\Bounds.cs" />
|
<Compile Include="GameFiles\Resources\Bounds.cs" />
|
||||||
<Compile Include="GameFiles\Resources\Clip.cs" />
|
<Compile Include="GameFiles\Resources\Clip.cs" />
|
||||||
<Compile Include="GameFiles\Resources\Clothes.cs" />
|
<Compile Include="GameFiles\Resources\Clothes.cs" />
|
||||||
|
@ -1517,9 +1517,37 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
private static void WriteNode(StringBuilder sb, int indent, RbfStructure rs)
|
private static void WriteNode(StringBuilder sb, int indent, RbfStructure rs)
|
||||||
{
|
{
|
||||||
|
var attStr = "";
|
||||||
|
if (rs.Attributes.Count > 0)
|
||||||
|
{
|
||||||
|
var asb = new StringBuilder();
|
||||||
|
foreach (var attr in rs.Attributes)
|
||||||
|
{
|
||||||
|
if (attr is RbfString str)
|
||||||
|
{
|
||||||
|
asb.Append($" {attr.Name}=\"{str.Value}\"");
|
||||||
|
}
|
||||||
|
else if (attr is RbfFloat flt)
|
||||||
|
{
|
||||||
|
asb.Append($" {attr.Name}=\"{FloatUtil.ToString(flt.Value)}\"");
|
||||||
|
}
|
||||||
|
else if (attr is RbfUint32 unt)
|
||||||
|
{
|
||||||
|
asb.Append($" {attr.Name}=\"{unt.Value.ToString()}\"");
|
||||||
|
}
|
||||||
|
else if (attr is RbfBoolean bln)
|
||||||
|
{
|
||||||
|
asb.Append($" {attr.Name}=\"{bln.Value.ToString()}\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
attStr = $"{asb.ToString()}";
|
||||||
|
}
|
||||||
|
|
||||||
if (rs.Children.Count == 0)
|
if (rs.Children.Count == 0)
|
||||||
{
|
{
|
||||||
SelfClosingTag(sb, indent, rs.Name);
|
SelfClosingTag(sb, indent, rs.Name + attStr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1527,7 +1555,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
bool oneline = ((rs.Children.Count == 1) && (rs.Children[0].Name == null));
|
bool oneline = ((rs.Children.Count == 1) && (rs.Children[0].Name == null));
|
||||||
|
|
||||||
OpenTag(sb, indent, rs.Name, !oneline);
|
OpenTag(sb, indent, rs.Name + attStr, !oneline);
|
||||||
|
|
||||||
|
|
||||||
foreach (var child in rs.Children)
|
foreach (var child in rs.Children)
|
||||||
|
@ -42,6 +42,7 @@ namespace CodeWalker.GameFiles
|
|||||||
public RbfStructure current { get; set; }
|
public RbfStructure current { get; set; }
|
||||||
public Stack<RbfStructure> stack { get; set; }
|
public Stack<RbfStructure> stack { get; set; }
|
||||||
public List<RbfEntryDescription> descriptors { get; set; }
|
public List<RbfEntryDescription> descriptors { get; set; }
|
||||||
|
public Dictionary<string, int> outDescriptors { get; private set; } = new Dictionary<string, int>();
|
||||||
|
|
||||||
public RbfStructure Load(string fileName)
|
public RbfStructure Load(string fileName)
|
||||||
{
|
{
|
||||||
@ -130,7 +131,7 @@ namespace CodeWalker.GameFiles
|
|||||||
private void ParseElement(DataReader reader, int descriptorIndex, byte dataType)
|
private void ParseElement(DataReader reader, int descriptorIndex, byte dataType)
|
||||||
{
|
{
|
||||||
var descriptor = descriptors[descriptorIndex];
|
var descriptor = descriptors[descriptorIndex];
|
||||||
switch (dataType) //(descriptor.Type)
|
switch (dataType)
|
||||||
{
|
{
|
||||||
case 0: // open element...
|
case 0: // open element...
|
||||||
{
|
{
|
||||||
@ -139,22 +140,15 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
if (current != null)
|
if (current != null)
|
||||||
{
|
{
|
||||||
current.Children.Add(structureValue);
|
current.AddChild(structureValue);
|
||||||
stack.Push(current);
|
stack.Push(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
current = structureValue;
|
current = structureValue;
|
||||||
|
|
||||||
// 6 bytes
|
|
||||||
var x1 = reader.ReadInt16();
|
var x1 = reader.ReadInt16();
|
||||||
var x2 = reader.ReadInt16();
|
var x2 = reader.ReadInt16();
|
||||||
var x3 = reader.ReadInt16();
|
current.PendingAttributes = reader.ReadInt16();
|
||||||
//if (x1 != 0)
|
|
||||||
// throw new Exception("unexpected");
|
|
||||||
//if (x2 != 0)
|
|
||||||
// throw new Exception("unexpected");
|
|
||||||
//if (x3 != 0)
|
|
||||||
// throw new Exception("unexpected");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x10:
|
case 0x10:
|
||||||
@ -162,7 +156,7 @@ namespace CodeWalker.GameFiles
|
|||||||
var intValue = new RbfUint32();
|
var intValue = new RbfUint32();
|
||||||
intValue.Name = descriptor.Name;
|
intValue.Name = descriptor.Name;
|
||||||
intValue.Value = reader.ReadUInt32();
|
intValue.Value = reader.ReadUInt32();
|
||||||
current.Children.Add(intValue);
|
current.AddChild(intValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x20:
|
case 0x20:
|
||||||
@ -170,7 +164,7 @@ namespace CodeWalker.GameFiles
|
|||||||
var booleanValue = new RbfBoolean();
|
var booleanValue = new RbfBoolean();
|
||||||
booleanValue.Name = descriptor.Name;
|
booleanValue.Name = descriptor.Name;
|
||||||
booleanValue.Value = true;
|
booleanValue.Value = true;
|
||||||
current.Children.Add(booleanValue);
|
current.AddChild(booleanValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x30:
|
case 0x30:
|
||||||
@ -178,7 +172,7 @@ namespace CodeWalker.GameFiles
|
|||||||
var booleanValue = new RbfBoolean();
|
var booleanValue = new RbfBoolean();
|
||||||
booleanValue.Name = descriptor.Name;
|
booleanValue.Name = descriptor.Name;
|
||||||
booleanValue.Value = false;
|
booleanValue.Value = false;
|
||||||
current.Children.Add(booleanValue);
|
current.AddChild(booleanValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x40:
|
case 0x40:
|
||||||
@ -186,7 +180,7 @@ namespace CodeWalker.GameFiles
|
|||||||
var floatValue = new RbfFloat();
|
var floatValue = new RbfFloat();
|
||||||
floatValue.Name = descriptor.Name;
|
floatValue.Name = descriptor.Name;
|
||||||
floatValue.Value = reader.ReadSingle();
|
floatValue.Value = reader.ReadSingle();
|
||||||
current.Children.Add(floatValue);
|
current.AddChild(floatValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x50:
|
case 0x50:
|
||||||
@ -196,7 +190,7 @@ namespace CodeWalker.GameFiles
|
|||||||
floatVectorValue.X = reader.ReadSingle();
|
floatVectorValue.X = reader.ReadSingle();
|
||||||
floatVectorValue.Y = reader.ReadSingle();
|
floatVectorValue.Y = reader.ReadSingle();
|
||||||
floatVectorValue.Z = reader.ReadSingle();
|
floatVectorValue.Z = reader.ReadSingle();
|
||||||
current.Children.Add(floatVectorValue);
|
current.AddChild(floatVectorValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x60:
|
case 0x60:
|
||||||
@ -207,7 +201,7 @@ namespace CodeWalker.GameFiles
|
|||||||
var stringValue = new RbfString();
|
var stringValue = new RbfString();
|
||||||
stringValue.Name = descriptor.Name;
|
stringValue.Name = descriptor.Name;
|
||||||
stringValue.Value = value;
|
stringValue.Value = value;
|
||||||
current.Children.Add(stringValue);
|
current.AddChild(stringValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -225,6 +219,66 @@ namespace CodeWalker.GameFiles
|
|||||||
return isrbf;
|
return isrbf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte GetDescriptorIndex(IRbfType t, out bool isNew)
|
||||||
|
{
|
||||||
|
var key = $"{t.Name}_{t.DataType}";
|
||||||
|
isNew = false;
|
||||||
|
|
||||||
|
if (!outDescriptors.TryGetValue(key, out var idx))
|
||||||
|
{
|
||||||
|
idx = outDescriptors.Count;
|
||||||
|
outDescriptors.Add(key, idx);
|
||||||
|
|
||||||
|
isNew = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte)idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte[] Save()
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
Save(ms);
|
||||||
|
|
||||||
|
var buf = new byte[ms.Length];
|
||||||
|
ms.Position = 0;
|
||||||
|
ms.Read(buf, 0, buf.Length);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(string fileName)
|
||||||
|
{
|
||||||
|
using (var fileStream = new FileStream(fileName, FileMode.Create))
|
||||||
|
{
|
||||||
|
Save(fileStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(Stream stream)
|
||||||
|
{
|
||||||
|
outDescriptors = new Dictionary<string, int>();
|
||||||
|
|
||||||
|
var writer = new DataWriter(stream);
|
||||||
|
writer.Write(RBF_IDENT);
|
||||||
|
|
||||||
|
current.Save(this, writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void WriteRecordId(IRbfType type, DataWriter writer)
|
||||||
|
{
|
||||||
|
writer.Write(GetDescriptorIndex(type, out var isNew));
|
||||||
|
writer.Write((byte)type.DataType);
|
||||||
|
|
||||||
|
if (isNew)
|
||||||
|
{
|
||||||
|
writer.Write((ushort)type.Name.Length);
|
||||||
|
writer.Write(Encoding.ASCII.GetBytes(type.Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfEntryDescription
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfEntryDescription
|
||||||
@ -236,23 +290,56 @@ namespace CodeWalker.GameFiles
|
|||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public interface IRbfType
|
[TypeConverter(typeof(ExpandableObjectConverter))] public interface IRbfType
|
||||||
{
|
{
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
}
|
byte DataType { get; }
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfBoolean : IRbfType
|
void Save(RbfFile file, DataWriter writer);
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Value { get; set; }
|
|
||||||
public override string ToString() { return Name + ": " + Value.ToString(); }
|
|
||||||
}
|
}
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfBytes : IRbfType
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfBytes : IRbfType
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public byte[] Value { get; set; }
|
public byte[] Value { get; set; }
|
||||||
|
public byte DataType => 0;
|
||||||
|
public void Save(RbfFile root, DataWriter writer)
|
||||||
|
{
|
||||||
|
writer.Write((byte)0xFD);
|
||||||
|
writer.Write((byte)0xFF);
|
||||||
|
writer.Write(Value.Length);
|
||||||
|
writer.Write(Value);
|
||||||
|
}
|
||||||
|
public override string ToString() { return Name + ": " + Value.ToString(); }
|
||||||
|
}
|
||||||
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfUint32 : IRbfType
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public uint Value { get; set; }
|
||||||
|
public byte DataType => 0x10;
|
||||||
|
public void Save(RbfFile file, DataWriter writer)
|
||||||
|
{
|
||||||
|
file.WriteRecordId(this, writer);
|
||||||
|
writer.Write(Value);
|
||||||
|
}
|
||||||
|
public override string ToString() { return Name + ": " + Value.ToString(); }
|
||||||
|
}
|
||||||
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfBoolean : IRbfType
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool Value { get; set; }
|
||||||
|
public byte DataType => (byte)((Value) ? 0x20 : 0x30);
|
||||||
|
public void Save(RbfFile file, DataWriter writer)
|
||||||
|
{
|
||||||
|
file.WriteRecordId(this, writer);
|
||||||
|
}
|
||||||
public override string ToString() { return Name + ": " + Value.ToString(); }
|
public override string ToString() { return Name + ": " + Value.ToString(); }
|
||||||
}
|
}
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfFloat : IRbfType
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfFloat : IRbfType
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public float Value { get; set; }
|
public float Value { get; set; }
|
||||||
|
public byte DataType => 0x40;
|
||||||
|
public void Save(RbfFile file, DataWriter writer)
|
||||||
|
{
|
||||||
|
file.WriteRecordId(this, writer);
|
||||||
|
writer.Write(Value);
|
||||||
|
}
|
||||||
public override string ToString() { return Name + ": " + Value.ToString(); }
|
public override string ToString() { return Name + ": " + Value.ToString(); }
|
||||||
}
|
}
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfFloat3 : IRbfType
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfFloat3 : IRbfType
|
||||||
@ -261,18 +348,36 @@ namespace CodeWalker.GameFiles
|
|||||||
public float X { get; set; }
|
public float X { get; set; }
|
||||||
public float Y { get; set; }
|
public float Y { get; set; }
|
||||||
public float Z { get; set; }
|
public float Z { get; set; }
|
||||||
|
public byte DataType => 0x50;
|
||||||
|
public void Save(RbfFile file, DataWriter writer)
|
||||||
|
{
|
||||||
|
file.WriteRecordId(this, writer);
|
||||||
|
writer.Write(X);
|
||||||
|
writer.Write(Y);
|
||||||
|
writer.Write(Z);
|
||||||
|
}
|
||||||
public override string ToString() { return string.Format("{0}: X:{1}, Y:{2}, Z:{3}", Name, X, Y, Z); }
|
public override string ToString() { return string.Format("{0}: X:{1}, Y:{2}, Z:{3}", Name, X, Y, Z); }
|
||||||
}
|
}
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfString : IRbfType
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfString : IRbfType
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
|
public byte DataType => 0x60;
|
||||||
|
public void Save(RbfFile file, DataWriter writer)
|
||||||
|
{
|
||||||
|
file.WriteRecordId(this, writer);
|
||||||
|
writer.Write((short)Value.Length);
|
||||||
|
writer.Write(Encoding.ASCII.GetBytes(Value));
|
||||||
|
}
|
||||||
public override string ToString() { return Name + ": " + Value.ToString(); }
|
public override string ToString() { return Name + ": " + Value.ToString(); }
|
||||||
}
|
}
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfStructure : IRbfType
|
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfStructure : IRbfType
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public List<IRbfType> Children { get; set; } = new List<IRbfType>();
|
public List<IRbfType> Children { get; set; } = new List<IRbfType>();
|
||||||
|
public List<IRbfType> Attributes { get; set; } = new List<IRbfType>();
|
||||||
|
internal int PendingAttributes { get; set; }
|
||||||
|
public byte DataType => 0;
|
||||||
public override string ToString() { return Name + ": {" + Children.Count.ToString() + "}"; }
|
public override string ToString() { return Name + ": {" + Children.Count.ToString() + "}"; }
|
||||||
public IRbfType FindChild(string name)
|
public IRbfType FindChild(string name)
|
||||||
{
|
{
|
||||||
@ -283,12 +388,39 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
public void Save(RbfFile root, DataWriter writer)
|
||||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class RbfUint32 : IRbfType
|
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
root.WriteRecordId(this, writer);
|
||||||
public uint Value { get; set; }
|
|
||||||
public override string ToString() { return Name + ": " + Value.ToString(); }
|
writer.Write(new byte[4]); // 00
|
||||||
|
|
||||||
|
// count of non-primitive fields in this (... attributes??)
|
||||||
|
writer.Write((short)Attributes.Count); //writer.Write((short)Children.TakeWhile(a => !(a is RbfBytes || a is RbfStructure)).Count());
|
||||||
|
|
||||||
|
foreach (var attr in Attributes)
|
||||||
|
{
|
||||||
|
attr.Save(root, writer);
|
||||||
|
}
|
||||||
|
foreach (var child in Children)
|
||||||
|
{
|
||||||
|
child.Save(root, writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.Write((byte)0xFF);
|
||||||
|
writer.Write((byte)0xFF);
|
||||||
|
}
|
||||||
|
internal void AddChild(IRbfType value)
|
||||||
|
{
|
||||||
|
if (PendingAttributes > 0)
|
||||||
|
{
|
||||||
|
PendingAttributes--;
|
||||||
|
Attributes.Add(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Children.Add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
142
CodeWalker.Core/GameFiles/MetaTypes/XmlRbf.cs
Normal file
142
CodeWalker.Core/GameFiles/MetaTypes/XmlRbf.cs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
using SharpDX;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace CodeWalker.GameFiles
|
||||||
|
{
|
||||||
|
public class XmlRbf
|
||||||
|
{
|
||||||
|
|
||||||
|
public static RbfFile GetRbf(XmlDocument doc)
|
||||||
|
{
|
||||||
|
var rbf = new RbfFile();
|
||||||
|
|
||||||
|
using (var reader = new XmlNodeReader(doc))
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
rbf.current = (RbfStructure) Traverse(XDocument.Load(reader).Root);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rbf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IRbfType Traverse(XNode node)
|
||||||
|
{
|
||||||
|
if (node is XElement element)
|
||||||
|
{
|
||||||
|
if (element.Attribute("value") != null)
|
||||||
|
{
|
||||||
|
var val = element.Attribute("value").Value;
|
||||||
|
if (!string.IsNullOrEmpty(val))
|
||||||
|
{
|
||||||
|
var rval = CreateValueNode(element.Name.LocalName, val);
|
||||||
|
if (rval != null)
|
||||||
|
{
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((element.Attributes().Count() == 3) && (element.Attribute("x") != null) && (element.Attribute("y") != null) && (element.Attribute("z") != null))
|
||||||
|
{
|
||||||
|
FloatUtil.TryParse(element.Attribute("x").Value, out float x);
|
||||||
|
FloatUtil.TryParse(element.Attribute("y").Value, out float y);
|
||||||
|
FloatUtil.TryParse(element.Attribute("z").Value, out float z);
|
||||||
|
return new RbfFloat3()
|
||||||
|
{
|
||||||
|
Name = element.Name.LocalName,
|
||||||
|
X = x,
|
||||||
|
Y = y,
|
||||||
|
Z = z
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if ((element.Elements().Count() == 0) && (element.Attributes().Count() == 0)) //else if (element.Name == "type" || element.Name == "key" || element.Name == "platform")
|
||||||
|
{
|
||||||
|
return new RbfString()
|
||||||
|
{
|
||||||
|
Name = element.Name.LocalName,
|
||||||
|
Value = element.Value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var n = new RbfStructure();
|
||||||
|
n.Name = element.Name.LocalName;
|
||||||
|
n.Children = element.Nodes().Select(c => Traverse(c)).ToList();
|
||||||
|
|
||||||
|
foreach (var attr in element.Attributes())
|
||||||
|
{
|
||||||
|
var val = attr.Value;
|
||||||
|
var aval = CreateValueNode(attr.Name.LocalName, val);
|
||||||
|
if (aval != null)
|
||||||
|
{
|
||||||
|
n.Attributes.Add(aval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
else if (node is XText text)
|
||||||
|
{
|
||||||
|
return new RbfBytes()
|
||||||
|
{
|
||||||
|
Name = "",
|
||||||
|
Value = Encoding.ASCII.GetBytes(text.Value).Concat(new byte[] { 0x00 }).ToArray()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static IRbfType CreateValueNode(string name, string val)
|
||||||
|
{
|
||||||
|
if (val == "True")
|
||||||
|
{
|
||||||
|
return new RbfBoolean()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Value = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (val == "False")
|
||||||
|
{
|
||||||
|
return new RbfBoolean()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Value = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (val.StartsWith("0x"))
|
||||||
|
{
|
||||||
|
uint.TryParse(val.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint u);
|
||||||
|
return new RbfUint32()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Value = u
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (FloatUtil.TryParse(val, out float f))
|
||||||
|
{
|
||||||
|
return new RbfFloat()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Value = f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new RbfString()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Value = val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2504,7 +2504,13 @@ namespace CodeWalker
|
|||||||
}
|
}
|
||||||
case MetaFormat.RBF:
|
case MetaFormat.RBF:
|
||||||
{
|
{
|
||||||
//todo!
|
var rbf = XmlRbf.GetRbf(doc);
|
||||||
|
if (rbf.current == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(fname + ": Schema not supported.", "Cannot import RBF XML");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
data = rbf.Save();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MetaFormat.AudioRel:
|
case MetaFormat.AudioRel:
|
||||||
|
@ -373,11 +373,14 @@ namespace CodeWalker.Forms
|
|||||||
data = pso.Save();
|
data = pso.Save();
|
||||||
break;
|
break;
|
||||||
case MetaFormat.RBF:
|
case MetaFormat.RBF:
|
||||||
MessageBox.Show("Sorry, RBF import is not supported.", "Cannot import RBF XML");
|
var rbf = XmlRbf.GetRbf(doc);
|
||||||
return false;
|
if (rbf.current == null)
|
||||||
case MetaFormat.CacheFile:
|
{
|
||||||
MessageBox.Show("Sorry, CacheFile import is not supported.", "Cannot import CacheFile XML");
|
MessageBox.Show("Schema not supported.", "Cannot import RBF XML");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
data = rbf.Save();
|
||||||
|
break;
|
||||||
case MetaFormat.Ynd:
|
case MetaFormat.Ynd:
|
||||||
var ynd = XmlYnd.GetYnd(doc);
|
var ynd = XmlYnd.GetYnd(doc);
|
||||||
if (ynd.NodeDictionary == null)
|
if (ynd.NodeDictionary == null)
|
||||||
@ -387,6 +390,9 @@ namespace CodeWalker.Forms
|
|||||||
}
|
}
|
||||||
data = ynd.Save();
|
data = ynd.Save();
|
||||||
break;
|
break;
|
||||||
|
case MetaFormat.CacheFile:
|
||||||
|
MessageBox.Show("Sorry, CacheFile import is not supported.", "Cannot import CacheFile XML");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
|
Loading…
Reference in New Issue
Block a user