Code Analysis feedback tweaks.

This commit is contained in:
CloneTrooper1019 2020-09-14 11:20:34 -05:00
parent 4240337863
commit 2a114e70b0
25 changed files with 100 additions and 104 deletions

View File

@ -43,9 +43,9 @@ namespace RobloxFiles
public BinaryRobloxFile() public BinaryRobloxFile()
{ {
Name = "BinaryRobloxFile"; Name = "Bin:";
ParentLocked = true;
Referent = "-1"; Referent = "-1";
ParentLocked = true;
} }
protected override void ReadFile(byte[] contents) protected override void ReadFile(byte[] contents)

View File

@ -47,10 +47,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
INST inst = file.Classes[ClassIndex]; INST inst = file.Classes[ClassIndex];
ClassName = inst.ClassName; ClassName = inst.ClassName;
Property[] props = new Property[inst.NumInstances];
var ids = inst.InstanceIds; var ids = inst.InstanceIds;
int instCount = inst.NumInstances; int instCount = inst.NumInstances;
var props = new Property[inst.NumInstances];
for (int i = 0; i < instCount; i++) for (int i = 0; i < instCount; i++)
{ {
@ -71,8 +70,8 @@ namespace RobloxFiles.BinaryFormat.Chunks
{ {
for (int i = 0; i < instCount; i++) for (int i = 0; i < instCount; i++)
{ {
object result = read(i); var prop = props[i];
props[i].Value = result; prop.Value = read(i);
} }
}); });

View File

@ -18,10 +18,10 @@ namespace RobloxFiles.DataTypes
public override string ToString() => Name; public override string ToString() => Name;
private static List<BrickColor> ByPalette; private static readonly List<BrickColor> ByPalette;
private static Dictionary<int, BrickColor> ByNumber; private static readonly Dictionary<int, BrickColor> ByNumber;
private static Random RNG = new Random(); private static readonly Random RNG = new Random();
private const string DefaultName = "Medium stone grey"; private const string DefaultName = "Medium stone grey";
private const int DefaultNumber = 194; private const int DefaultNumber = 194;

View File

@ -161,7 +161,7 @@ namespace RobloxFiles.DataTypes
m31 = comp[9]; m32 = comp[10]; m33 = comp[11]; m31 = comp[9]; m32 = comp[10]; m33 = comp[11];
} }
private void initFromMatrix(Vector3 pos, Vector3 vX, Vector3 vY, Vector3 vZ = null) private void InitFromMatrix(Vector3 pos, Vector3 vX, Vector3 vY, Vector3 vZ = null)
{ {
if (vZ == null) if (vZ == null)
vZ = vX.Cross(vY); vZ = vX.Cross(vY);
@ -175,7 +175,7 @@ namespace RobloxFiles.DataTypes
public CFrame(Vector3 pos, Vector3 vX, Vector3 vY, Vector3 vZ = null) public CFrame(Vector3 pos, Vector3 vX, Vector3 vY, Vector3 vZ = null)
{ {
Contract.Requires(pos != null && vX != null && vY != null); Contract.Requires(pos != null && vX != null && vY != null);
initFromMatrix(pos, vX, vY, vZ); InitFromMatrix(pos, vX, vY, vZ);
} }
internal CFrame(Attribute attr) internal CFrame(Attribute attr)
@ -194,7 +194,7 @@ namespace RobloxFiles.DataTypes
NormalId yColumn = (NormalId)(orientId % 6); NormalId yColumn = (NormalId)(orientId % 6);
Vector3 vY = Vector3.FromNormalId(yColumn); Vector3 vY = Vector3.FromNormalId(yColumn);
initFromMatrix(pos, vX, vY); InitFromMatrix(pos, vX, vY);
} }
else else
{ {
@ -202,7 +202,7 @@ namespace RobloxFiles.DataTypes
vY = new Vector3(attr), vY = new Vector3(attr),
vZ = new Vector3(attr); vZ = new Vector3(attr);
initFromMatrix(pos, vX, vY, vZ); InitFromMatrix(pos, vX, vY, vZ);
} }
} }

View File

@ -44,9 +44,9 @@ namespace RobloxFiles.DataTypes
internal Color3(Attribute attr) internal Color3(Attribute attr)
{ {
R = attr.readFloat(); R = attr.ReadFloat();
G = attr.readFloat(); G = attr.ReadFloat();
B = attr.readFloat(); B = attr.ReadFloat();
} }
public static Color3 FromRGB(uint r = 0, uint g = 0, uint b = 0) public static Color3 FromRGB(uint r = 0, uint g = 0, uint b = 0)

View File

@ -90,7 +90,7 @@ namespace RobloxFiles.DataTypes
public ColorSequence(Attribute attr) public ColorSequence(Attribute attr)
{ {
int numKeys = attr.readInt(); int numKeys = attr.ReadInt();
var keypoints = new ColorSequenceKeypoint[numKeys]; var keypoints = new ColorSequenceKeypoint[numKeys];
for (int i = 0; i < numKeys; i++) for (int i = 0; i < numKeys; i++)

View File

@ -21,8 +21,8 @@
internal ColorSequenceKeypoint(Attribute attr) internal ColorSequenceKeypoint(Attribute attr)
{ {
Envelope = attr.readInt(); Envelope = attr.ReadInt();
Time = attr.readFloat(); Time = attr.ReadFloat();
Value = new Color3(attr); Value = new Color3(attr);
} }

View File

@ -16,7 +16,7 @@
public static implicit operator string(Content content) public static implicit operator string(Content content)
{ {
return content.Url; return content?.Url;
} }
public static implicit operator Content(string url) public static implicit operator Content(string url)

View File

@ -25,7 +25,7 @@ namespace RobloxFiles.DataTypes
Max = max; Max = max;
} }
internal NumberRange(Attribute attr) : this(attr.readFloat(), attr.readFloat()) internal NumberRange(Attribute attr) : this(attr.ReadFloat(), attr.ReadFloat())
{ {
} }

View File

@ -54,7 +54,7 @@ namespace RobloxFiles.DataTypes
public NumberSequence(Attribute attr) public NumberSequence(Attribute attr)
{ {
int numKeys = attr.readInt(); int numKeys = attr.ReadInt();
var keypoints = new NumberSequenceKeypoint[numKeys]; var keypoints = new NumberSequenceKeypoint[numKeys];
for (int i = 0; i < numKeys; i++) for (int i = 0; i < numKeys; i++)

View File

@ -20,9 +20,9 @@
internal NumberSequenceKeypoint(Attribute attr) internal NumberSequenceKeypoint(Attribute attr)
{ {
Envelope = attr.readFloat(); Envelope = attr.ReadFloat();
Time = attr.readFloat(); Time = attr.ReadFloat();
Value = attr.readFloat(); Value = attr.ReadFloat();
} }
public override int GetHashCode() public override int GetHashCode()

View File

@ -39,12 +39,12 @@ namespace RobloxFiles.DataTypes
internal PhysicalProperties(Attribute attr) internal PhysicalProperties(Attribute attr)
{ {
Density = attr.readFloat(); Density = attr.ReadFloat();
Friction = attr.readFloat(); Friction = attr.ReadFloat();
Elasticity = attr.readFloat(); Elasticity = attr.ReadFloat();
FrictionWeight = attr.readFloat(); FrictionWeight = attr.ReadFloat();
ElasticityWeight = attr.readFloat(); ElasticityWeight = attr.ReadFloat();
} }
public override int GetHashCode() public override int GetHashCode()

View File

@ -16,7 +16,7 @@ namespace RobloxFiles.DataTypes
public class SharedString public class SharedString
{ {
private static ConcurrentDictionary<string, byte[]> Lookup = new ConcurrentDictionary<string, byte[]>(); private static readonly ConcurrentDictionary<string, byte[]> Lookup = new ConcurrentDictionary<string, byte[]>();
public string Key { get; internal set; } public string Key { get; internal set; }
public string ComputedKey { get; internal set; } public string ComputedKey { get; internal set; }

View File

@ -15,8 +15,8 @@
internal UDim(Attribute attr) internal UDim(Attribute attr)
{ {
Scale = attr.readFloat(); Scale = attr.ReadFloat();
Offset = attr.readInt(); Offset = attr.ReadInt();
} }
public static UDim operator+(UDim a, UDim b) public static UDim operator+(UDim a, UDim b)

View File

@ -37,8 +37,8 @@ namespace RobloxFiles.DataTypes
internal Vector2(Attribute attr) internal Vector2(Attribute attr)
{ {
X = attr.readFloat(); X = attr.ReadFloat();
Y = attr.readFloat(); Y = attr.ReadFloat();
} }
private delegate Vector2 Operator(Vector2 a, Vector2 b); private delegate Vector2 Operator(Vector2 a, Vector2 b);
@ -55,10 +55,10 @@ namespace RobloxFiles.DataTypes
return upcast(numVec, vec); return upcast(numVec, vec);
} }
private static Operator add = new Operator((a, b) => new Vector2(a.X + b.X, a.Y + b.Y)); private static readonly Operator add = new Operator((a, b) => new Vector2(a.X + b.X, a.Y + b.Y));
private static Operator sub = new Operator((a, b) => new Vector2(a.X - b.X, a.Y - b.Y)); private static readonly Operator sub = new Operator((a, b) => new Vector2(a.X - b.X, a.Y - b.Y));
private static Operator mul = new Operator((a, b) => new Vector2(a.X * b.X, a.Y * b.Y)); private static readonly Operator mul = new Operator((a, b) => new Vector2(a.X * b.X, a.Y * b.Y));
private static Operator div = new Operator((a, b) => new Vector2(a.X / b.X, a.Y / b.Y)); private static readonly Operator div = new Operator((a, b) => new Vector2(a.X / b.X, a.Y / b.Y));
public static Vector2 operator +(Vector2 a, Vector2 b) => add(a, b); public static Vector2 operator +(Vector2 a, Vector2 b) => add(a, b);
public static Vector2 operator +(Vector2 v, float n) => upcastFloatOp(v, n, add); public static Vector2 operator +(Vector2 v, float n) => upcastFloatOp(v, n, add);

View File

@ -39,10 +39,10 @@ namespace RobloxFiles.DataTypes
return upcast(numVec, vec); return upcast(numVec, vec);
} }
private static Operator add = new Operator((a, b) => new Vector2int16(a.X + b.X, a.Y + b.Y)); private static readonly Operator add = new Operator((a, b) => new Vector2int16(a.X + b.X, a.Y + b.Y));
private static Operator sub = new Operator((a, b) => new Vector2int16(a.X - b.X, a.Y - b.Y)); private static readonly Operator sub = new Operator((a, b) => new Vector2int16(a.X - b.X, a.Y - b.Y));
private static Operator mul = new Operator((a, b) => new Vector2int16(a.X * b.X, a.Y * b.Y)); private static readonly Operator mul = new Operator((a, b) => new Vector2int16(a.X * b.X, a.Y * b.Y));
private static Operator div = new Operator((a, b) => private static readonly Operator div = new Operator((a, b) =>
{ {
if (b.X == 0 || b.Y == 0) if (b.X == 0 || b.Y == 0)
throw new DivideByZeroException(); throw new DivideByZeroException();

View File

@ -41,9 +41,9 @@ namespace RobloxFiles.DataTypes
internal Vector3(Attribute attr) internal Vector3(Attribute attr)
{ {
X = attr.readFloat(); X = attr.ReadFloat();
Y = attr.readFloat(); Y = attr.ReadFloat();
Z = attr.readFloat(); Z = attr.ReadFloat();
} }
public static Vector3 FromAxis(Axis axis) public static Vector3 FromAxis(Axis axis)
@ -80,10 +80,10 @@ namespace RobloxFiles.DataTypes
return upcast(numVec, vec); return upcast(numVec, vec);
} }
private static Operator add = new Operator((a, b) => new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z)); private static readonly Operator add = new Operator((a, b) => new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z));
private static Operator sub = new Operator((a, b) => new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z)); private static readonly Operator sub = new Operator((a, b) => new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z));
private static Operator mul = new Operator((a, b) => new Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z)); private static readonly Operator mul = new Operator((a, b) => new Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z));
private static Operator div = new Operator((a, b) => new Vector3(a.X / b.X, a.Y / b.Y, a.Z / b.Z)); private static readonly Operator div = new Operator((a, b) => new Vector3(a.X / b.X, a.Y / b.Y, a.Z / b.Z));
public static Vector3 operator +(Vector3 a, Vector3 b) => add(a, b); public static Vector3 operator +(Vector3 a, Vector3 b) => add(a, b);
public static Vector3 operator +(Vector3 v, float n) => upcastFloatOp(v, n, add); public static Vector3 operator +(Vector3 v, float n) => upcastFloatOp(v, n, add);

View File

@ -46,10 +46,10 @@ namespace RobloxFiles.DataTypes
return upcast(numVec, vec); return upcast(numVec, vec);
} }
private static Operator add = new Operator((a, b) => new Vector3int16(a.X + b.X, a.Y + b.Y, a.Z + b.Z)); private static readonly Operator add = new Operator((a, b) => new Vector3int16(a.X + b.X, a.Y + b.Y, a.Z + b.Z));
private static Operator sub = new Operator((a, b) => new Vector3int16(a.X - b.X, a.Y - b.Y, a.Z - b.Z)); private static readonly Operator sub = new Operator((a, b) => new Vector3int16(a.X - b.X, a.Y - b.Y, a.Z - b.Z));
private static Operator mul = new Operator((a, b) => new Vector3int16(a.X * b.X, a.Y * b.Y, a.Z * b.Z)); private static readonly Operator mul = new Operator((a, b) => new Vector3int16(a.X * b.X, a.Y * b.Y, a.Z * b.Z));
private static Operator div = new Operator((a, b) => private static readonly Operator div = new Operator((a, b) =>
{ {
if (b.X == 0 || b.Y == 0 || b.Z == 0) if (b.X == 0 || b.Y == 0 || b.Z == 0)
throw new DivideByZeroException(); throw new DivideByZeroException();

Binary file not shown.

View File

@ -56,17 +56,17 @@ namespace RobloxFiles
internal BinaryReader reader; internal BinaryReader reader;
// internal BinaryWriter writer; // internal BinaryWriter writer;
internal int readInt() => reader.ReadInt32(); internal int ReadInt() => reader.ReadInt32();
internal byte readByte() => reader.ReadByte(); internal byte readByte() => reader.ReadByte();
internal bool readBool() => reader.ReadBoolean(); internal bool readBool() => reader.ReadBoolean();
internal short readShort() => reader.ReadInt16(); internal short readShort() => reader.ReadInt16();
internal float readFloat() => reader.ReadSingle(); internal float ReadFloat() => reader.ReadSingle();
internal double readDouble() => reader.ReadDouble(); internal double ReadDouble() => reader.ReadDouble();
internal string readString() => reader.ReadString(true); internal string ReadString() => reader.ReadString(true);
internal Attribute[] readArray() internal Attribute[] ReadArray()
{ {
int count = readInt(); int count = ReadInt();
var result = new Attribute[count]; var result = new Attribute[count];
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
@ -77,8 +77,8 @@ namespace RobloxFiles
internal object readEnum() internal object readEnum()
{ {
string name = readString(); string name = ReadString();
int value = readInt(); int value = ReadInt();
try try
{ {
@ -107,22 +107,22 @@ namespace RobloxFiles
case AttributeType.Null: case AttributeType.Null:
break; break;
case AttributeType.String: case AttributeType.String:
Value = readString(); Value = ReadString();
break; break;
case AttributeType.Bool: case AttributeType.Bool:
Value = readBool(); Value = readBool();
break; break;
case AttributeType.Int: case AttributeType.Int:
Value = readInt(); Value = ReadInt();
break; break;
case AttributeType.Float: case AttributeType.Float:
Value = readFloat(); Value = ReadFloat();
break; break;
case AttributeType.Double: case AttributeType.Double:
Value = readDouble(); Value = ReadDouble();
break; break;
case AttributeType.Array: case AttributeType.Array:
Value = readArray(); Value = ReadArray();
break; break;
case AttributeType.Dictionary: case AttributeType.Dictionary:
Value = new Attributes(reader); Value = new Attributes(reader);
@ -137,13 +137,13 @@ namespace RobloxFiles
Value = new Ray(this); Value = new Ray(this);
break; break;
case AttributeType.Faces: case AttributeType.Faces:
Value = (Faces)readInt(); Value = (Faces)ReadInt();
break; break;
case AttributeType.Axes: case AttributeType.Axes:
Value = (Axes)readInt(); Value = (Axes)ReadInt();
break; break;
case AttributeType.BrickColor: case AttributeType.BrickColor:
Value = (BrickColor)readInt(); Value = (BrickColor)ReadInt();
break; break;
case AttributeType.Color3: case AttributeType.Color3:
Value = new Color3(this); Value = new Color3(this);
@ -225,7 +225,7 @@ namespace RobloxFiles
public class Attributes : Dictionary<string, Attribute> public class Attributes : Dictionary<string, Attribute>
{ {
private void initialize(BinaryReader reader) private void Initialize(BinaryReader reader)
{ {
Stream stream = reader.BaseStream; Stream stream = reader.BaseStream;
@ -245,14 +245,14 @@ namespace RobloxFiles
internal Attributes(BinaryReader reader) internal Attributes(BinaryReader reader)
{ {
initialize(reader); Initialize(reader);
} }
internal Attributes(MemoryStream stream) internal Attributes(MemoryStream stream)
{ {
using (BinaryReader reader = new BinaryReader(stream)) using (BinaryReader reader = new BinaryReader(stream))
{ {
initialize(reader); Initialize(reader);
} }
} }

View File

@ -24,7 +24,7 @@ namespace RobloxFiles
public string ClassName => GetType().Name; public string ClassName => GetType().Name;
/// <summary>Internal list of properties that are under this Instance.</summary> /// <summary>Internal list of properties that are under this Instance.</summary>
private Dictionary<string, Property> props = new Dictionary<string, Property>(); private readonly Dictionary<string, Property> props = new Dictionary<string, Property>();
/// <summary>A list of properties that are defined under this Instance.</summary> /// <summary>A list of properties that are defined under this Instance.</summary>
public IReadOnlyDictionary<string, Property> Properties => props; public IReadOnlyDictionary<string, Property> Properties => props;
@ -45,7 +45,7 @@ namespace RobloxFiles
public override string ToString() => Name; public override string ToString() => Name;
/// <summary>A unique identifier for this instance when being serialized.</summary> /// <summary>A unique identifier for this instance when being serialized.</summary>
public string Referent { get; internal set; } public string Referent { get; set; }
/// <summary>Indicates whether the parent of this object is locked.</summary> /// <summary>Indicates whether the parent of this object is locked.</summary>
public bool ParentLocked { get; internal set; } public bool ParentLocked { get; internal set; }
@ -438,7 +438,7 @@ namespace RobloxFiles
/// <summary> /// <summary>
/// Returns a string describing the index traversal of this Instance, starting from its root ancestor. /// Returns a string describing the index traversal of this Instance, starting from its root ancestor.
/// </summary> /// </summary>
public string GetFullName(string separator = ".") public string GetFullName(string separator = "\\")
{ {
string fullName = Name; string fullName = Name;
Instance at = Parent; Instance at = Parent;
@ -512,6 +512,8 @@ namespace RobloxFiles
if (field.GetCustomAttribute<ObsoleteAttribute>() != null) if (field.GetCustomAttribute<ObsoleteAttribute>() != null)
continue; continue;
// A few specific edge case hacks. I wish these didn't need to exist :(
if (fieldName == "Archivable" || fieldName.EndsWith("k__BackingField")) if (fieldName == "Archivable" || fieldName.EndsWith("k__BackingField"))
continue; continue;
else if (fieldName == "Bevel_Roundness") else if (fieldName == "Bevel_Roundness")

View File

@ -126,9 +126,18 @@ namespace RobloxFiles
} }
} }
if (RawValue is long)
Type = PropertyType.Int64;
switch (Type) switch (Type)
{ {
case PropertyType.Int: case PropertyType.Int:
if (Value is long)
{
Type = PropertyType.Int64;
goto case PropertyType.Int64;
}
RawBuffer = BitConverter.GetBytes((int)Value); RawBuffer = BitConverter.GetBytes((int)Value);
break; break;
case PropertyType.Bool: case PropertyType.Bool:
@ -307,7 +316,7 @@ namespace RobloxFiles
string result = Name; string result = Name;
if (Instance != null) if (Instance != null)
result = Instance.GetFullName() + '.' + result; result = Instance.GetFullName() + "->" + result;
return result; return result;
} }
@ -329,8 +338,8 @@ namespace RobloxFiles
if (typeof(T) == typeof(string)) if (typeof(T) == typeof(string))
result = Value?.ToString() ?? ""; result = Value?.ToString() ?? "";
else if (Value is T) else if (Value is T typedValue)
result = (T)Value; result = typedValue;
else else
result = default(T); result = default(T);

View File

@ -7,7 +7,7 @@ namespace RobloxFiles.XmlFormat
{ {
public static class XmlRobloxFileReader public static class XmlRobloxFileReader
{ {
private static Func<string, Exception> createErrorHandler(string label) private static Func<string, Exception> CreateErrorHandler(string label)
{ {
var errorHandler = new Func<string, Exception>((message) => var errorHandler = new Func<string, Exception>((message) =>
{ {
@ -20,7 +20,7 @@ namespace RobloxFiles.XmlFormat
public static void ReadSharedStrings(XmlNode sharedStrings, XmlRobloxFile file) public static void ReadSharedStrings(XmlNode sharedStrings, XmlRobloxFile file)
{ {
var error = createErrorHandler("ReadSharedStrings"); var error = CreateErrorHandler("ReadSharedStrings");
if (sharedStrings.Name != "SharedStrings") if (sharedStrings.Name != "SharedStrings")
throw error("Provided XmlNode's class should be 'SharedStrings'!"); throw error("Provided XmlNode's class should be 'SharedStrings'!");
@ -56,7 +56,7 @@ namespace RobloxFiles.XmlFormat
public static void ReadMetadata(XmlNode meta, XmlRobloxFile file) public static void ReadMetadata(XmlNode meta, XmlRobloxFile file)
{ {
var error = createErrorHandler("ReadMetadata"); var error = CreateErrorHandler("ReadMetadata");
if (meta.Name != "Meta") if (meta.Name != "Meta")
throw error("Provided XmlNode's class should be 'Meta'!"); throw error("Provided XmlNode's class should be 'Meta'!");
@ -74,7 +74,7 @@ namespace RobloxFiles.XmlFormat
public static void ReadProperties(Instance instance, XmlNode propsNode) public static void ReadProperties(Instance instance, XmlNode propsNode)
{ {
var error = createErrorHandler("ReadProperties"); var error = CreateErrorHandler("ReadProperties");
if (propsNode.Name != "Properties") if (propsNode.Name != "Properties")
throw error("Provided XmlNode's class should be 'Properties'!"); throw error("Provided XmlNode's class should be 'Properties'!");
@ -121,7 +121,7 @@ namespace RobloxFiles.XmlFormat
public static Instance ReadInstance(XmlNode instNode, XmlRobloxFile file) public static Instance ReadInstance(XmlNode instNode, XmlRobloxFile file)
{ {
var error = createErrorHandler("ReadInstance"); var error = CreateErrorHandler("ReadInstance");
// Process the instance itself // Process the instance itself
if (instNode.Name != "Item") if (instNode.Name != "Item")

View File

@ -161,28 +161,14 @@ namespace RobloxFiles.XmlFormat
object a = DefaultProperty.Get(instance, prop); object a = DefaultProperty.Get(instance, prop);
object b = prop.Value; object b = prop.Value;
if (a is float) if (a is double d0 && b is double d1)
{
float f0 = (float)a,
f1 = (float)b;
isDefault = f0.FuzzyEquals(f1);
}
else if (a is double)
{
double d0 = (double)a,
d1 = (double)b;
isDefault = d0.FuzzyEquals(d1); isDefault = d0.FuzzyEquals(d1);
} else if (a is float f0 && b is float f1)
isDefault = f0.FuzzyEquals(f1);
else if (b != null) else if (b != null)
{
isDefault = b.Equals(a); isDefault = b.Equals(a);
}
else if (a == b) else if (a == b)
{
isDefault = true; isDefault = true;
}
if (!isDefault) if (!isDefault)
{ {

View File

@ -23,9 +23,9 @@ namespace RobloxFiles
public XmlRobloxFile() public XmlRobloxFile()
{ {
Name = "XmlRobloxFile"; Name = "Xml:";
ParentLocked = true;
Referent = "null"; Referent = "null";
ParentLocked = true;
} }
protected override void ReadFile(byte[] buffer) protected override void ReadFile(byte[] buffer)