Attribute -> RbxAttribute

This commit is contained in:
Max 2021-06-05 17:21:12 -05:00
parent 71cd85513e
commit 5dc65e2184
23 changed files with 76 additions and 133 deletions

View File

@ -18,13 +18,6 @@
Envelope = envelope;
}
internal NumberSequenceKeypoint(Attribute attr)
{
Envelope = attr.ReadFloat();
Time = attr.ReadFloat();
Value = attr.ReadFloat();
}
public override int GetHashCode()
{
int hash = Time.GetHashCode()

View File

@ -37,16 +37,6 @@ namespace RobloxFiles.DataTypes
ElasticityWeight = elasticityWeight;
}
internal PhysicalProperties(Attribute attr)
{
Density = attr.ReadFloat();
Friction = attr.ReadFloat();
Elasticity = attr.ReadFloat();
FrictionWeight = attr.ReadFloat();
ElasticityWeight = attr.ReadFloat();
}
public override int GetHashCode()
{
int hash = Density.GetHashCode()

View File

@ -11,12 +11,6 @@
Max = max ?? new Vector3int16();
}
internal Region3int16(Attribute attr)
{
Min = new Vector3int16(attr);
Max = new Vector3int16(attr);
}
public override int GetHashCode()
{
int hash = Min.GetHashCode()

View File

@ -19,12 +19,6 @@ namespace RobloxFiles.DataTypes
Y = (short)y;
}
internal Vector2int16(Attribute attr)
{
X = attr.ReadShort();
Y = attr.ReadShort();
}
private delegate Vector2int16 Operator(Vector2int16 a, Vector2int16 b);
private static Vector2int16 upcastShortOp(Vector2int16 vec, short num, Operator upcast)

View File

@ -25,13 +25,6 @@ namespace RobloxFiles.DataTypes
Z = (short)z;
}
internal Vector3int16(Attribute attr)
{
X = attr.ReadShort();
Y = attr.ReadShort();
Z = attr.ReadShort();
}
private delegate Vector3int16 Operator(Vector3int16 a, Vector3int16 b);
private static Vector3int16 upcastShortOp(Vector3int16 vec, short num, Operator upcast)

View File

@ -4,7 +4,7 @@
{
AttributeType AttributeType { get; }
T ReadAttribute(Attribute attribute);
void WriteAttribute(Attribute attribute, T value);
T ReadAttribute(RbxAttribute attribute);
void WriteAttribute(RbxAttribute attribute, T value);
}
}

Binary file not shown.

View File

@ -8,8 +8,8 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "bool";
public AttributeType AttributeType => AttributeType.Bool;
public bool ReadAttribute(Attribute attr) => attr.ReadBool();
public void WriteAttribute(Attribute attr, bool value) => attr.WriteBool(value);
public bool ReadAttribute(RbxAttribute attr) => attr.ReadBool();
public void WriteAttribute(RbxAttribute attr, bool value) => attr.WriteBool(value);
public bool ReadProperty(Property prop, XmlNode token)
{

View File

@ -12,8 +12,8 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "BrickColor";
public AttributeType AttributeType => AttributeType.BrickColor;
public BrickColor ReadAttribute(Attribute attr) => attr.ReadInt();
public void WriteAttribute(Attribute attr, BrickColor value) => attr.WriteInt(value.Number);
public BrickColor ReadAttribute(RbxAttribute attr) => attr.ReadInt();
public void WriteAttribute(RbxAttribute attr, BrickColor value) => attr.WriteInt(value.Number);
public bool ReadProperty(Property prop, XmlNode token)
{

View File

@ -10,10 +10,10 @@ namespace RobloxFiles.Tokens
private readonly string[] XmlFields = new string[3] { "R", "G", "B" };
public AttributeType AttributeType => AttributeType.Color3;
public Color3 ReadAttribute(Attribute attr) => ReadColor3(attr);
public void WriteAttribute(Attribute attr, Color3 value) => WriteColor3(attr, value);
public Color3 ReadAttribute(RbxAttribute attr) => ReadColor3(attr);
public void WriteAttribute(RbxAttribute attr, Color3 value) => WriteColor3(attr, value);
public static Color3 ReadColor3(Attribute attr)
public static Color3 ReadColor3(RbxAttribute attr)
{
float r = attr.ReadFloat(),
g = attr.ReadFloat(),
@ -22,7 +22,7 @@ namespace RobloxFiles.Tokens
return new Color3(r, g, b);
}
public static void WriteColor3(Attribute attr, Color3 value)
public static void WriteColor3(RbxAttribute attr, Color3 value)
{
attr.WriteFloat(value.R);
attr.WriteFloat(value.G);

View File

@ -52,7 +52,7 @@ namespace RobloxFiles.Tokens
node.InnerText = value.ToString() + ' ';
}
public ColorSequence ReadAttribute(Attribute attr)
public ColorSequence ReadAttribute(RbxAttribute attr)
{
int numKeys = attr.ReadInt();
var keypoints = new ColorSequenceKeypoint[numKeys];
@ -69,7 +69,7 @@ namespace RobloxFiles.Tokens
return new ColorSequence(keypoints);
}
public void WriteAttribute(Attribute attr, ColorSequence value)
public void WriteAttribute(RbxAttribute attr, ColorSequence value)
{
attr.WriteInt(value.Keypoints.Length);

View File

@ -8,8 +8,8 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "double";
public AttributeType AttributeType => AttributeType.Double;
public double ReadAttribute(Attribute attr) => attr.ReadDouble();
public void WriteAttribute(Attribute attr, double value) => attr.WriteDouble(value);
public double ReadAttribute(RbxAttribute attr) => attr.ReadDouble();
public void WriteAttribute(RbxAttribute attr, double value) => attr.WriteDouble(value);
public bool ReadProperty(Property prop, XmlNode token)
{

View File

@ -8,8 +8,8 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "float";
public AttributeType AttributeType => AttributeType.Float;
public float ReadAttribute(Attribute attr) => attr.ReadFloat();
public void WriteAttribute(Attribute attr, float value) => attr.WriteFloat(value);
public float ReadAttribute(RbxAttribute attr) => attr.ReadFloat();
public void WriteAttribute(RbxAttribute attr, float value) => attr.WriteFloat(value);
public bool ReadProperty(Property prop, XmlNode token)
{

View File

@ -40,7 +40,7 @@ namespace RobloxFiles.Tokens
node.InnerText = value.ToString() + ' ';
}
public NumberRange ReadAttribute(Attribute attr)
public NumberRange ReadAttribute(RbxAttribute attr)
{
float min = attr.ReadFloat();
float max = attr.ReadFloat();
@ -48,7 +48,7 @@ namespace RobloxFiles.Tokens
return new NumberRange(min, max);
}
public void WriteAttribute(Attribute attr, NumberRange value)
public void WriteAttribute(RbxAttribute attr, NumberRange value)
{
attr.WriteFloat(value.Min);
attr.WriteFloat(value.Max);

View File

@ -49,7 +49,7 @@ namespace RobloxFiles.Tokens
node.InnerText = value.ToString() + ' ';
}
public NumberSequence ReadAttribute(Attribute attr)
public NumberSequence ReadAttribute(RbxAttribute attr)
{
int numKeys = attr.ReadInt();
var keypoints = new NumberSequenceKeypoint[numKeys];
@ -66,7 +66,7 @@ namespace RobloxFiles.Tokens
return new NumberSequence(keypoints);
}
public void WriteAttribute(Attribute attr, NumberSequence value)
public void WriteAttribute(RbxAttribute attr, NumberSequence value)
{
attr.WriteInt(value.Keypoints.Length);

View File

@ -51,7 +51,7 @@ namespace RobloxFiles.Tokens
node.AppendChild(max);
}
public Rect ReadAttribute(Attribute attr)
public Rect ReadAttribute(RbxAttribute attr)
{
Vector2 min = Vector2Token.ReadVector2(attr);
Vector2 max = Vector2Token.ReadVector2(attr);
@ -59,7 +59,7 @@ namespace RobloxFiles.Tokens
return new Rect(min, max);
}
public void WriteAttribute(Attribute attr, Rect value)
public void WriteAttribute(RbxAttribute attr, Rect value)
{
Vector2Token.WriteVector2(attr, value.Min);
Vector2Token.WriteVector2(attr, value.Max);

View File

@ -7,8 +7,8 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "string";
public AttributeType AttributeType => AttributeType.String;
public string ReadAttribute(Attribute attr) => attr.ReadString();
public void WriteAttribute(Attribute attr, string value) => attr.WriteString(value);
public string ReadAttribute(RbxAttribute attr) => attr.ReadString();
public void WriteAttribute(RbxAttribute attr, string value) => attr.WriteString(value);
public bool ReadProperty(Property prop, XmlNode token)
{

View File

@ -9,8 +9,8 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "UDim";
public AttributeType AttributeType => AttributeType.UDim;
public UDim ReadAttribute(Attribute attr) => ReadUDim(attr);
public void WriteAttribute(Attribute attr, UDim value) => WriteUDim(attr, value);
public UDim ReadAttribute(RbxAttribute attr) => ReadUDim(attr);
public void WriteAttribute(RbxAttribute attr, UDim value) => WriteUDim(attr, value);
public static UDim ReadUDim(XmlNode token, string prefix = "")
{
@ -41,7 +41,7 @@ namespace RobloxFiles.Tokens
node.AppendChild(offset);
}
public static UDim ReadUDim(Attribute attr)
public static UDim ReadUDim(RbxAttribute attr)
{
float scale = attr.ReadFloat();
int offset = attr.ReadInt();
@ -49,7 +49,7 @@ namespace RobloxFiles.Tokens
return new UDim(scale, offset);
}
public static void WriteUDim(Attribute attr, UDim value)
public static void WriteUDim(RbxAttribute attr, UDim value)
{
float scale = value.Scale;
attr.WriteFloat(scale);

View File

@ -8,7 +8,7 @@ namespace RobloxFiles.Tokens
public string XmlPropertyToken => "UDim2";
public AttributeType AttributeType => AttributeType.UDim2;
public UDim2 ReadAttribute(Attribute attr)
public UDim2 ReadAttribute(RbxAttribute attr)
{
UDim x = UDimToken.ReadUDim(attr);
UDim y = UDimToken.ReadUDim(attr);
@ -16,7 +16,7 @@ namespace RobloxFiles.Tokens
return new UDim2(x, y);
}
public void WriteAttribute(Attribute attr, UDim2 value)
public void WriteAttribute(RbxAttribute attr, UDim2 value)
{
UDimToken.WriteUDim(attr, value.X);
UDimToken.WriteUDim(attr, value.Y);

View File

@ -9,8 +9,8 @@ namespace RobloxFiles.Tokens
private static readonly string[] XmlCoords = new string[2] { "X", "Y" };
public AttributeType AttributeType => AttributeType.Vector2;
public Vector2 ReadAttribute(Attribute attr) => ReadVector2(attr);
public void WriteAttribute(Attribute attr, Vector2 value) => WriteVector2(attr, value);
public Vector2 ReadAttribute(RbxAttribute attr) => ReadVector2(attr);
public void WriteAttribute(RbxAttribute attr, Vector2 value) => WriteVector2(attr, value);
public static Vector2 ReadVector2(XmlNode token)
{
@ -46,7 +46,7 @@ namespace RobloxFiles.Tokens
node.AppendChild(y);
}
public static Vector2 ReadVector2(Attribute attr)
public static Vector2 ReadVector2(RbxAttribute attr)
{
float x = attr.ReadFloat(),
y = attr.ReadFloat();
@ -54,7 +54,7 @@ namespace RobloxFiles.Tokens
return new Vector2(x, y);
}
public static void WriteVector2(Attribute attr, Vector2 value)
public static void WriteVector2(RbxAttribute attr, Vector2 value)
{
attr.WriteFloat(value.X);
attr.WriteFloat(value.Y);

View File

@ -9,8 +9,8 @@ namespace RobloxFiles.Tokens
private static readonly string[] XmlCoords = new string[3] { "X", "Y", "Z" };
public AttributeType AttributeType => AttributeType.Vector3;
public Vector3 ReadAttribute(Attribute attr) => ReadVector3(attr);
public void WriteAttribute(Attribute attr, Vector3 value) => WriteVector3(attr, value);
public Vector3 ReadAttribute(RbxAttribute attr) => ReadVector3(attr);
public void WriteAttribute(RbxAttribute attr, Vector3 value) => WriteVector3(attr, value);
public static Vector3 ReadVector3(XmlNode token)
{
@ -49,7 +49,7 @@ namespace RobloxFiles.Tokens
node.AppendChild(z);
}
public static Vector3 ReadVector3(Attribute attr)
public static Vector3 ReadVector3(RbxAttribute attr)
{
float x = attr.ReadFloat(),
y = attr.ReadFloat(),
@ -58,7 +58,7 @@ namespace RobloxFiles.Tokens
return new Vector3(x, y, z);
}
public static void WriteVector3(Attribute attr, Vector3 value)
public static void WriteVector3(RbxAttribute attr, Vector3 value)
{
attr.WriteFloat(value.X);
attr.WriteFloat(value.Y);

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
namespace RobloxFiles
@ -45,7 +46,7 @@ namespace RobloxFiles
// Region3int16 = 32
}
public class Attribute : IDisposable
public class RbxAttribute : IDisposable
{
private static readonly IReadOnlyDictionary<AttributeType, Tokenizer> AttributeSupport;
private static readonly IReadOnlyDictionary<Type, AttributeType> SupportedTypes;
@ -70,20 +71,20 @@ namespace RobloxFiles
Writer = support.GetMethod("WriteAttribute");
}
public object ReadAttribute(Attribute attr)
public object ReadAttribute(RbxAttribute attr)
{
var args = new object[1] { attr };
return Reader.Invoke(Token, args);
}
public void WriteAttribute(Attribute attr, object value)
public void WriteAttribute(RbxAttribute attr, object value)
{
var args = new object[2] { attr, value };
Writer.Invoke(Token, args);
}
}
static Attribute()
static RbxAttribute()
{
var attributeSupport = new Dictionary<AttributeType, Tokenizer>();
var supportedTypes = new Dictionary<Type, AttributeType>();
@ -193,19 +194,19 @@ namespace RobloxFiles
Writer = null;
}
internal Attribute(BinaryReader reader)
internal RbxAttribute(BinaryReader reader)
{
Reader = reader;
Read();
}
internal Attribute(MemoryStream stream)
internal RbxAttribute(MemoryStream stream)
{
Reader = new BinaryReader(stream);
Read();
}
internal Attribute(object value)
internal RbxAttribute(object value)
{
Type type = value.GetType();
@ -217,44 +218,31 @@ namespace RobloxFiles
}
}
public class Attributes : SortedDictionary<string, Attribute>
public class RbxAttributes : SortedDictionary<string, RbxAttribute>
{
private void Initialize(BinaryReader reader)
internal void Load(byte[] buffer)
{
Stream stream = reader.BaseStream;
Clear();
if (stream.Length - stream.Position < 4)
if (buffer == null || buffer.Length < 4)
// Not enough room to read the entry count, possibly empty?
return;
using (var input = new MemoryStream(buffer))
using (var reader = new BinaryReader(input))
{
int numEntries = reader.ReadInt32();
for (int i = 0; i < numEntries; i++)
{
string key = reader.ReadString(true);
var attribute = new Attribute(reader);
var attribute = new RbxAttribute(reader);
Add(key, attribute);
}
}
public Attributes() : base()
{
}
internal Attributes(BinaryReader reader)
{
Initialize(reader);
}
internal Attributes(MemoryStream stream)
{
using (var reader = new BinaryReader(stream))
Initialize(reader);
stream.Dispose();
}
internal byte[] Serialize()
internal byte[] Save()
{
if (Count == 0)
return Array.Empty<byte>();

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
@ -61,26 +59,16 @@ namespace RobloxFiles
public bool Destroyed { get; internal set; }
/// <summary>A hashset of CollectionService tags assigned to this Instance.</summary>
public HashSet<string> Tags { get; } = new HashSet<string>();
/// <summary>The attributes defined for this Instance.</summary>
private Attributes AttributesImpl = new Attributes();
public readonly HashSet<string> Tags = new HashSet<string>();
/// <summary>The public readonly access point of the attributes on this Instance.</summary>
public IReadOnlyDictionary<string, Attribute> Attributes => AttributesImpl;
public readonly RbxAttributes Attributes = new RbxAttributes();
/// <summary>The internal serialized data of this Instance's attributes</summary>
internal byte[] AttributesSerialize
{
get
{
return AttributesImpl?.Serialize() ?? Array.Empty<byte>();
}
set
{
var data = new MemoryStream(value);
AttributesImpl = new Attributes(data);
}
get => Attributes.Save();
set => Attributes.Load(value);
}
/// <summary>
@ -134,7 +122,7 @@ namespace RobloxFiles
/// <returns>True if the attribute could be read and the out value was set, false otherwise.</returns>
public bool GetAttribute<T>(string key, out T value)
{
if (AttributesImpl.TryGetValue(key, out Attribute attr))
if (Attributes.TryGetValue(key, out RbxAttribute attr))
{
if (attr.Value is T result)
{
@ -161,13 +149,16 @@ namespace RobloxFiles
if (key.Length > 100)
return false;
Type type = value.GetType();
if (!Attribute.SupportsType(type))
if (key.StartsWith("RBX", StringComparison.InvariantCulture))
return false;
var attr = new Attribute(value);
AttributesImpl[key] = attr;
Type type = value.GetType();
if (!RbxAttribute.SupportsType(type))
return false;
var attr = new RbxAttribute(value);
Attributes[key] = attr;
return true;
}
@ -474,8 +465,8 @@ namespace RobloxFiles
Parent = null;
ParentLocked = true;
Tags?.Clear();
AttributesImpl?.Clear();
Tags.Clear();
Attributes.Clear();
while (Children.Any())
{