Add support for XML files.
XML support is now implemented and should generally be working! This library should be useable now, but I still need to set it up to work as a NuGet package. If there are any bugs, let me know!
This commit is contained in:
31
XmlFormat/PropertyTokens/Axes.cs
Normal file
31
XmlFormat/PropertyTokens/Axes.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class AxesToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Axes";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
bool success = XmlPropertyTokens.ReadTokenGeneric<uint>(prop, PropertyType.Axes, token);
|
||||
|
||||
if (success)
|
||||
{
|
||||
uint value = (uint)prop.Value;
|
||||
try
|
||||
{
|
||||
Axes axes = (Axes)value;
|
||||
prop.Value = axes;
|
||||
}
|
||||
catch
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
23
XmlFormat/PropertyTokens/BinaryString.cs
Normal file
23
XmlFormat/PropertyTokens/BinaryString.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class BinaryStringToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "BinaryString";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
// BinaryStrings are encoded in base64
|
||||
string base64 = token.InnerText;
|
||||
prop.Type = PropertyType.String;
|
||||
prop.Value = base64;
|
||||
|
||||
byte[] buffer = Convert.FromBase64String(base64);
|
||||
prop.SetRawBuffer(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
14
XmlFormat/PropertyTokens/Boolean.cs
Normal file
14
XmlFormat/PropertyTokens/Boolean.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class BoolToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "bool";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
return XmlPropertyTokens.ReadTokenGeneric<bool>(prop, PropertyType.Bool, token);
|
||||
}
|
||||
}
|
||||
}
|
35
XmlFormat/PropertyTokens/BrickColor.cs
Normal file
35
XmlFormat/PropertyTokens/BrickColor.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class BrickColorToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "BrickColor";
|
||||
// ^ This is a lie: The token is actually int, but that would cause a name collision.
|
||||
// Since BrickColors are written as ints, the IntToken class will try to redirect
|
||||
// to this handler if it believes that its representing a BrickColor.
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
bool success = XmlPropertyTokens.ReadTokenGeneric<int>(prop, PropertyType.BrickColor, token);
|
||||
|
||||
if (success)
|
||||
{
|
||||
int value = (int)prop.Value;
|
||||
try
|
||||
{
|
||||
BrickColor brickColor = BrickColor.FromNumber(value);
|
||||
prop.Value = brickColor;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Invalid BrickColor Id?
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
47
XmlFormat/PropertyTokens/CFrame.cs
Normal file
47
XmlFormat/PropertyTokens/CFrame.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class CFrameToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "CoordinateFrame; CFrame";
|
||||
private static string[] Coords = new string[12] { "X", "Y", "Z", "R00", "R01", "R02", "R10", "R11", "R12", "R20", "R21", "R22"};
|
||||
|
||||
public static CFrame ReadCFrame(XmlNode token)
|
||||
{
|
||||
float[] components = new float[12];
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
string key = Coords[i];
|
||||
|
||||
try
|
||||
{
|
||||
var coord = token[key];
|
||||
components[i] = float.Parse(coord.InnerText);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new CFrame(components);
|
||||
}
|
||||
|
||||
public bool ReadToken(Property property, XmlNode token)
|
||||
{
|
||||
CFrame result = ReadCFrame(token);
|
||||
bool success = (result != null);
|
||||
|
||||
if (success)
|
||||
{
|
||||
property.Type = PropertyType.CFrame;
|
||||
property.Value = result;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
50
XmlFormat/PropertyTokens/Color3.cs
Normal file
50
XmlFormat/PropertyTokens/Color3.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class Color3Token : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Color3";
|
||||
private string[] LegacyFields = new string[3] { "R", "G", "B" };
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
var color3uint8 = XmlPropertyTokens.GetHandler<Color3uint8Token>();
|
||||
bool success = color3uint8.ReadToken(prop, token);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// Try the legacy technique.
|
||||
float[] fields = new float[LegacyFields.Length];
|
||||
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
string key = LegacyFields[i];
|
||||
|
||||
try
|
||||
{
|
||||
var coord = token[key];
|
||||
fields[i] = XmlPropertyTokens.ParseFloat(coord.InnerText);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float r = fields[0],
|
||||
g = fields[1],
|
||||
b = fields[2];
|
||||
|
||||
prop.Type = PropertyType.Color3;
|
||||
prop.Value = new Color3(r, g, b);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
29
XmlFormat/PropertyTokens/Color3uint8.cs
Normal file
29
XmlFormat/PropertyTokens/Color3uint8.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class Color3uint8Token : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Color3uint8";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
bool success = XmlPropertyTokens.ReadTokenGeneric<uint>(prop, PropertyType.Color3, token);
|
||||
|
||||
if (success)
|
||||
{
|
||||
uint value = (uint)prop.Value;
|
||||
|
||||
uint r = (value >> 16) & 0xFF;
|
||||
uint g = (value >> 8) & 0xFF;
|
||||
uint b = value & 0xFF;
|
||||
|
||||
prop.Value = Color3.fromRGB(r, g, b);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
48
XmlFormat/PropertyTokens/ColorSequence.cs
Normal file
48
XmlFormat/PropertyTokens/ColorSequence.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class ColorSequenceToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "ColorSequence";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
string contents = token.InnerText.Trim();
|
||||
string[] buffer = contents.Split(' ');
|
||||
|
||||
int length = buffer.Length;
|
||||
bool valid = (length % 5 == 0);
|
||||
|
||||
if (valid)
|
||||
{
|
||||
try
|
||||
{
|
||||
ColorSequenceKeypoint[] keypoints = new ColorSequenceKeypoint[length / 5];
|
||||
|
||||
for (int i = 0; i < length; i += 5)
|
||||
{
|
||||
float Time = float.Parse(buffer[i]);
|
||||
|
||||
float R = float.Parse(buffer[i + 1]);
|
||||
float G = float.Parse(buffer[i + 2]);
|
||||
float B = float.Parse(buffer[i + 3]);
|
||||
|
||||
Color3 Value = new Color3(R, G, B);
|
||||
keypoints[i / 5] = new ColorSequenceKeypoint(Time, Value);
|
||||
}
|
||||
|
||||
prop.Type = PropertyType.ColorSequence;
|
||||
prop.Value = new ColorSequence(keypoints);
|
||||
}
|
||||
catch
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
}
|
32
XmlFormat/PropertyTokens/Content.cs
Normal file
32
XmlFormat/PropertyTokens/Content.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class ContentToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Content";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
string content = token.InnerText;
|
||||
prop.Type = PropertyType.String;
|
||||
prop.Value = content;
|
||||
|
||||
if (token.HasChildNodes)
|
||||
{
|
||||
XmlNode childNode = token.FirstChild;
|
||||
string contentType = childNode.Name;
|
||||
|
||||
if (contentType.StartsWith("binary") || contentType == "hash")
|
||||
{
|
||||
// Roblox technically doesn't support this anymore, but load it anyway :P
|
||||
byte[] buffer = Convert.FromBase64String(content);
|
||||
prop.SetRawBuffer(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
14
XmlFormat/PropertyTokens/Double.cs
Normal file
14
XmlFormat/PropertyTokens/Double.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class DoubleToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "double";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
return XmlPropertyTokens.ReadTokenGeneric<double>(prop, PropertyType.Double, token);
|
||||
}
|
||||
}
|
||||
}
|
14
XmlFormat/PropertyTokens/Enum.cs
Normal file
14
XmlFormat/PropertyTokens/Enum.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class EnumToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "token";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
return XmlPropertyTokens.ReadTokenGeneric<uint>(prop, PropertyType.Enum, token);
|
||||
}
|
||||
}
|
||||
}
|
31
XmlFormat/PropertyTokens/Faces.cs
Normal file
31
XmlFormat/PropertyTokens/Faces.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class FacesToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Faces";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
bool success = XmlPropertyTokens.ReadTokenGeneric<uint>(prop, PropertyType.Faces, token);
|
||||
|
||||
if (success)
|
||||
{
|
||||
uint value = (uint)prop.Value;
|
||||
try
|
||||
{
|
||||
Faces faces = (Faces)value;
|
||||
prop.Value = faces;
|
||||
}
|
||||
catch
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
24
XmlFormat/PropertyTokens/Float.cs
Normal file
24
XmlFormat/PropertyTokens/Float.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class FloatToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "float";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
try
|
||||
{
|
||||
float value = XmlPropertyTokens.ParseFloat(token.InnerText);
|
||||
prop.Type = PropertyType.Float;
|
||||
prop.Value = value;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
XmlFormat/PropertyTokens/Int.cs
Normal file
25
XmlFormat/PropertyTokens/Int.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class IntToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "int";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
// BrickColors are represented by ints, see if
|
||||
// we can infer when they should be a BrickColor.
|
||||
|
||||
if (prop.Name.Contains("Color") || prop.Instance.ClassName.Contains("Color"))
|
||||
{
|
||||
var brickColorToken = XmlPropertyTokens.GetHandler<BrickColorToken>();
|
||||
return brickColorToken.ReadToken(prop, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
return XmlPropertyTokens.ReadTokenGeneric<int>(prop, PropertyType.Int, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
XmlFormat/PropertyTokens/Int64.cs
Normal file
14
XmlFormat/PropertyTokens/Int64.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class Int64Token : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "int64";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
return XmlPropertyTokens.ReadTokenGeneric<long>(prop, PropertyType.Int64, token);
|
||||
}
|
||||
}
|
||||
}
|
35
XmlFormat/PropertyTokens/NumberRange.cs
Normal file
35
XmlFormat/PropertyTokens/NumberRange.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class NumberRangeToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "NumberRange";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
string contents = token.InnerText.Trim();
|
||||
string[] buffer = contents.Split(' ');
|
||||
bool valid = (buffer.Length == 2);
|
||||
|
||||
if (valid)
|
||||
{
|
||||
try
|
||||
{
|
||||
float min = float.Parse(buffer[0]);
|
||||
float max = float.Parse(buffer[1]);
|
||||
|
||||
prop.Type = PropertyType.NumberRange;
|
||||
prop.Value = new NumberRange(min, max);
|
||||
}
|
||||
catch
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
}
|
45
XmlFormat/PropertyTokens/NumberSequence.cs
Normal file
45
XmlFormat/PropertyTokens/NumberSequence.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class NumberSequenceToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "NumberSequence";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
string contents = token.InnerText.Trim();
|
||||
string[] buffer = contents.Split(' ');
|
||||
|
||||
int length = buffer.Length;
|
||||
bool valid = (length % 3 == 0);
|
||||
|
||||
if (valid)
|
||||
{
|
||||
try
|
||||
{
|
||||
NumberSequenceKeypoint[] keypoints = new NumberSequenceKeypoint[length / 3];
|
||||
|
||||
for (int i = 0; i < length; i += 3)
|
||||
{
|
||||
float Time = float.Parse(buffer[ i ]);
|
||||
float Value = float.Parse(buffer[i + 1]);
|
||||
float Envelope = float.Parse(buffer[i + 2]);
|
||||
|
||||
keypoints[i / 3] = new NumberSequenceKeypoint(Time, Value, Envelope);
|
||||
}
|
||||
|
||||
prop.Type = PropertyType.NumberSequence;
|
||||
prop.Value = new NumberSequence(keypoints);
|
||||
}
|
||||
catch
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
}
|
50
XmlFormat/PropertyTokens/PhysicalProperties.cs
Normal file
50
XmlFormat/PropertyTokens/PhysicalProperties.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class PhysicalPropertiesToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "PhysicalProperties";
|
||||
|
||||
private Func<string, T> createReader<T>(Func<string, T> parse, XmlNode token) where T : struct
|
||||
{
|
||||
return new Func<string, T>(key =>
|
||||
{
|
||||
XmlElement node = token[key];
|
||||
return parse(node.InnerText);
|
||||
});
|
||||
}
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
var readBool = createReader(bool.Parse, token);
|
||||
var readFloat = createReader(XmlPropertyTokens.ParseFloat, token);
|
||||
|
||||
try
|
||||
{
|
||||
bool custom = readBool("CustomPhysics");
|
||||
if (custom)
|
||||
{
|
||||
prop.Value = new PhysicalProperties
|
||||
(
|
||||
readFloat("Density"),
|
||||
readFloat("Friction"),
|
||||
readFloat("Elasticity"),
|
||||
readFloat("FrictionWeight"),
|
||||
readFloat("ElasticityWeight")
|
||||
);
|
||||
|
||||
prop.Type = PropertyType.PhysicalProperties;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
XmlFormat/PropertyTokens/Ray.cs
Normal file
40
XmlFormat/PropertyTokens/Ray.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class RayToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Ray";
|
||||
private static string[] Fields = new string[2] { "origin", "direction" };
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
Vector3[] read = new Vector3[Fields.Length];
|
||||
|
||||
for (int i = 0; i < read.Length; i++)
|
||||
{
|
||||
string field = Fields[i];
|
||||
try
|
||||
{
|
||||
var fieldToken = token[field];
|
||||
Vector3? vector3 = Vector3Token.ReadVector3(fieldToken);
|
||||
read[i] = vector3.Value;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 origin = read[0],
|
||||
direction = read[1];
|
||||
|
||||
Ray ray = new Ray(origin, direction);
|
||||
prop.Type = PropertyType.Ray;
|
||||
prop.Value = ray;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
40
XmlFormat/PropertyTokens/Rect.cs
Normal file
40
XmlFormat/PropertyTokens/Rect.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class RectToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Rect2D";
|
||||
private static string[] Fields = new string[2] { "min", "max" };
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
Vector2[] read = new Vector2[Fields.Length];
|
||||
|
||||
for (int i = 0; i < read.Length; i++)
|
||||
{
|
||||
string field = Fields[i];
|
||||
try
|
||||
{
|
||||
var fieldToken = token[field];
|
||||
Vector2? vector2 = Vector2Token.ReadVector2(fieldToken);
|
||||
read[i] = vector2.Value;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 min = read[0],
|
||||
max = read[1];
|
||||
|
||||
Rect rect = new Rect(min, max);
|
||||
prop.Type = PropertyType.Rect;
|
||||
prop.Value = rect;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
18
XmlFormat/PropertyTokens/Ref.cs
Normal file
18
XmlFormat/PropertyTokens/Ref.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class RefToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Ref";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
string refId = token.InnerText;
|
||||
prop.Type = PropertyType.Ref;
|
||||
prop.Value = refId;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
22
XmlFormat/PropertyTokens/String.cs
Normal file
22
XmlFormat/PropertyTokens/String.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class StringToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "string; ProtectedString";
|
||||
|
||||
public bool ReadToken(Property prop, XmlNode token)
|
||||
{
|
||||
string contents = token.InnerText;
|
||||
prop.Type = PropertyType.String;
|
||||
prop.Value = contents;
|
||||
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(contents);
|
||||
prop.SetRawBuffer(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
42
XmlFormat/PropertyTokens/UDim.cs
Normal file
42
XmlFormat/PropertyTokens/UDim.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class UDimToken : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "UDim";
|
||||
|
||||
public static UDim? ReadUDim(XmlNode token, string prefix = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlElement scaleToken = token[prefix + 'S'];
|
||||
float scale = XmlPropertyTokens.ParseFloat(scaleToken.InnerText);
|
||||
|
||||
XmlElement offsetToken = token[prefix + 'O'];
|
||||
int offset = int.Parse(offsetToken.InnerText);
|
||||
|
||||
return new UDim(scale, offset);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ReadToken(Property property, XmlNode token)
|
||||
{
|
||||
UDim? result = ReadUDim(token);
|
||||
bool success = (result != null);
|
||||
|
||||
if (success)
|
||||
{
|
||||
property.Type = PropertyType.UDim;
|
||||
property.Value = result;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
26
XmlFormat/PropertyTokens/UDim2.cs
Normal file
26
XmlFormat/PropertyTokens/UDim2.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class UDim2Token : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "UDim2";
|
||||
|
||||
public bool ReadToken(Property property, XmlNode token)
|
||||
{
|
||||
UDim? xDim = UDimToken.ReadUDim(token, "X");
|
||||
UDim? yDim = UDimToken.ReadUDim(token, "Y");
|
||||
|
||||
if (xDim != null && yDim != null)
|
||||
{
|
||||
property.Type = PropertyType.UDim2;
|
||||
property.Value = new UDim2(xDim.Value, yDim.Value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
48
XmlFormat/PropertyTokens/Vector2.cs
Normal file
48
XmlFormat/PropertyTokens/Vector2.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class Vector2Token : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Vector2";
|
||||
private static string[] Coords = new string[2] { "X", "Y" };
|
||||
|
||||
public static Vector2? ReadVector2(XmlNode token)
|
||||
{
|
||||
float[] xy = new float[2];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
string key = Coords[i];
|
||||
|
||||
try
|
||||
{
|
||||
var coord = token[key];
|
||||
string text = coord.InnerText;
|
||||
xy[i] = XmlPropertyTokens.ParseFloat(text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector2(xy);
|
||||
}
|
||||
|
||||
public bool ReadToken(Property property, XmlNode token)
|
||||
{
|
||||
Vector2? result = ReadVector2(token);
|
||||
bool success = (result != null);
|
||||
|
||||
if (success)
|
||||
{
|
||||
property.Type = PropertyType.Vector2;
|
||||
property.Value = result;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
47
XmlFormat/PropertyTokens/Vector3.cs
Normal file
47
XmlFormat/PropertyTokens/Vector3.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System.Xml;
|
||||
using Roblox.DataTypes;
|
||||
|
||||
namespace Roblox.XmlFormat.PropertyTokens
|
||||
{
|
||||
public class Vector3Token : IXmlPropertyToken
|
||||
{
|
||||
public string Token => "Vector3";
|
||||
private static string[] Coords = new string[3] { "X", "Y", "Z" };
|
||||
|
||||
public static Vector3? ReadVector3(XmlNode token)
|
||||
{
|
||||
float[] xyz = new float[3];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
string key = Coords[i];
|
||||
|
||||
try
|
||||
{
|
||||
var coord = token[key];
|
||||
xyz[i] = XmlPropertyTokens.ParseFloat(coord.InnerText);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector3(xyz);
|
||||
}
|
||||
|
||||
public bool ReadToken(Property property, XmlNode token)
|
||||
{
|
||||
Vector3? result = ReadVector3(token);
|
||||
bool success = (result != null);
|
||||
|
||||
if (success)
|
||||
{
|
||||
property.Type = PropertyType.Vector3;
|
||||
property.Value = result;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user