diff --git a/BinaryFormat/Chunks/INST.cs b/BinaryFormat/Chunks/INST.cs
index 5b53b03..b4a208b 100644
--- a/BinaryFormat/Chunks/INST.cs
+++ b/BinaryFormat/Chunks/INST.cs
@@ -33,9 +33,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
if (instType == null)
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine($"INST - Unknown class: {ClassName} while reading INST chunk.");
-
+ RobloxFile.LogError($"INST - Unknown class: {ClassName} while reading INST chunk.");
return;
}
diff --git a/BinaryFormat/Chunks/PRNT.cs b/BinaryFormat/Chunks/PRNT.cs
index ce2e244..2f862c4 100644
--- a/BinaryFormat/Chunks/PRNT.cs
+++ b/BinaryFormat/Chunks/PRNT.cs
@@ -33,17 +33,13 @@ namespace RobloxFiles.BinaryFormat.Chunks
if (child == null)
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine($"PRNT: could not parent {childId} to {parentId} because child {childId} was null.");
-
+ RobloxFile.LogError($"PRNT: could not parent {childId} to {parentId} because child {childId} was null.");
continue;
}
if (parentId >= 0 && parent == null)
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine($"PRNT: could not parent {childId} to {parentId} because parent {parentId} was null.");
-
+ RobloxFile.LogError($"PRNT: could not parent {childId} to {parentId} because parent {parentId} was null.");
continue;
}
diff --git a/BinaryFormat/Chunks/PROP.cs b/BinaryFormat/Chunks/PROP.cs
index e7d5e13..6f255a4 100644
--- a/BinaryFormat/Chunks/PROP.cs
+++ b/BinaryFormat/Chunks/PROP.cs
@@ -58,9 +58,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
if (instance == null)
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine($"PROP: No instance @{id} for property {ClassName}.{Name}");
-
+ RobloxFile.LogError($"PROP: No instance @{id} for property {ClassName}.{Name}");
continue;
}
@@ -368,9 +366,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
if (info == null)
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine($"Enum cast failed for {inst.ClassName}.{Name} using value {value}!");
-
+ RobloxFile.LogError($"Enum cast failed for {inst.ClassName}.{Name} using value {value}!");
return value;
}
@@ -378,9 +374,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
}
catch
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine($"Enum cast failed for {inst.ClassName}.{Name} using value {value}!");
-
+ RobloxFile.LogError($"Enum cast failed for {inst.ClassName}.{Name} using value {value}!");
return value;
}
});
@@ -545,9 +539,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
break;
default:
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine("Unhandled property type: {0}!", Type);
-
+ RobloxFile.LogError($"Unhandled property type: {Type}!");
break;
//
}
diff --git a/DataTypes/CFrame.cs b/DataTypes/CFrame.cs
index 5521edc..e229f88 100644
--- a/DataTypes/CFrame.cs
+++ b/DataTypes/CFrame.cs
@@ -181,7 +181,7 @@ namespace RobloxFiles.DataTypes
internal CFrame(Attribute attr)
{
Vector3 pos = new Vector3(attr);
- byte rawOrientId = attr.readByte();
+ byte rawOrientId = attr.ReadByte();
if (rawOrientId > 0)
{
diff --git a/DataTypes/Vector2int16.cs b/DataTypes/Vector2int16.cs
index 6b91dea..3b25585 100644
--- a/DataTypes/Vector2int16.cs
+++ b/DataTypes/Vector2int16.cs
@@ -21,8 +21,8 @@ namespace RobloxFiles.DataTypes
internal Vector2int16(Attribute attr)
{
- X = attr.readShort();
- Y = attr.readShort();
+ X = attr.ReadShort();
+ Y = attr.ReadShort();
}
private delegate Vector2int16 Operator(Vector2int16 a, Vector2int16 b);
diff --git a/DataTypes/Vector3int16.cs b/DataTypes/Vector3int16.cs
index 6acdb35..7d89efe 100644
--- a/DataTypes/Vector3int16.cs
+++ b/DataTypes/Vector3int16.cs
@@ -27,9 +27,9 @@ namespace RobloxFiles.DataTypes
internal Vector3int16(Attribute attr)
{
- X = attr.readShort();
- Y = attr.readShort();
- Z = attr.readShort();
+ X = attr.ReadShort();
+ Y = attr.ReadShort();
+ Z = attr.ReadShort();
}
private delegate Vector3int16 Operator(Vector3int16 a, Vector3int16 b);
diff --git a/Generated/Classes.cs b/Generated/Classes.cs
index cc96ac4..db77343 100644
--- a/Generated/Classes.cs
+++ b/Generated/Classes.cs
@@ -1,5 +1,5 @@
// Auto-generated list of creatable Roblox classes.
-// Updated as of 0.460.0.416222
+// Updated as of 0.462.0.416719
using System;
@@ -732,6 +732,14 @@ namespace RobloxFiles
public Vector3 Torque_ = new Vector3();
}
+ public class UniversalConstraint : Constraint
+ {
+ public bool LimitsEnabled;
+ public float MaxAngle = 45;
+ public float Radius = 0.2f;
+ public float Restitution;
+ }
+
public class VectorForce : Constraint
{
public bool ApplyAtCenterOfMass;
diff --git a/Generated/Enums.cs b/Generated/Enums.cs
index 968cfc1..3267663 100644
--- a/Generated/Enums.cs
+++ b/Generated/Enums.cs
@@ -1,5 +1,5 @@
// Auto-generated list of Roblox enums.
-// Updated as of 0.460.0.416222
+// Updated as of 0.462.0.416719
namespace RobloxFiles.Enums
{
diff --git a/RobloxFile.cs b/RobloxFile.cs
index aba5b69..9ac246c 100644
--- a/RobloxFile.cs
+++ b/RobloxFile.cs
@@ -137,5 +137,17 @@ namespace RobloxFiles
{
return Task.Run(() => Save(filePath));
}
+
+ ///
+ /// Logs an error that occurred while opening a RobloxFile if logs are enabled.
+ ///
+ ///
+ internal static void LogError(string message)
+ {
+ if (!LogErrors)
+ return;
+
+ Console.Error.WriteLine(message);
+ }
}
}
diff --git a/RobloxFileFormat.dll b/RobloxFileFormat.dll
index dfa80cb..67bf028 100644
Binary files a/RobloxFileFormat.dll and b/RobloxFileFormat.dll differ
diff --git a/Tree/Attributes.cs b/Tree/Attributes.cs
index 6494dcc..6e926ff 100644
--- a/Tree/Attributes.cs
+++ b/Tree/Attributes.cs
@@ -57,9 +57,9 @@ namespace RobloxFiles
// internal BinaryWriter writer;
internal int ReadInt() => reader.ReadInt32();
- internal byte readByte() => reader.ReadByte();
- internal bool readBool() => reader.ReadBoolean();
- internal short readShort() => reader.ReadInt16();
+ internal byte ReadByte() => reader.ReadByte();
+ internal bool ReadBool() => reader.ReadBoolean();
+ internal short ReadShort() => reader.ReadInt16();
internal float ReadFloat() => reader.ReadSingle();
internal double ReadDouble() => reader.ReadDouble();
internal string ReadString() => reader.ReadString(true);
@@ -103,14 +103,13 @@ namespace RobloxFiles
switch (DataType)
{
- //////////////////////////
case AttributeType.Null:
break;
case AttributeType.String:
Value = ReadString();
break;
case AttributeType.Bool:
- Value = readBool();
+ Value = ReadBool();
break;
case AttributeType.Int:
Value = ReadInt();
@@ -185,7 +184,7 @@ namespace RobloxFiles
Value = new Rect(this);
break;
case AttributeType.PhysicalProperties:
- bool custom = readBool();
+ bool custom = ReadBool();
if (custom)
Value = new PhysicalProperties(this);
@@ -197,9 +196,7 @@ namespace RobloxFiles
case AttributeType.Region3int16:
Value = new Region3int16(this);
break;
- default:
- throw new InvalidDataException($"Cannot handle AttributeType {DataType}!");
- //////////////////////////
+ default: throw new InvalidDataException($"Cannot handle AttributeType {DataType}!");
}
reader = null;
diff --git a/Tree/Instance.cs b/Tree/Instance.cs
index 65e319f..eff3d12 100644
--- a/Tree/Instance.cs
+++ b/Tree/Instance.cs
@@ -18,6 +18,7 @@ namespace RobloxFiles
public Instance()
{
Name = ClassName;
+ RefreshProperties();
}
/// The ClassName of this Instance.
@@ -506,12 +507,11 @@ namespace RobloxFiles
/// A reference to the property that will be added.
internal void AddProperty(ref Property prop)
{
+ string name = prop.Name;
+ RemoveProperty(name);
+
prop.Instance = this;
-
- if (props.ContainsKey(prop.Name))
- props.Remove(prop.Name);
-
- props.Add(prop.Name, prop);
+ props.Add(name, prop);
}
///
diff --git a/Tree/Property.cs b/Tree/Property.cs
index 6e406fa..7a4f4ab 100644
--- a/Tree/Property.cs
+++ b/Tree/Property.cs
@@ -211,10 +211,7 @@ namespace RobloxFiles
}
else
{
- if (!RobloxFile.LogErrors)
- return false;
-
- Console.Error.WriteLine($"RobloxFiles.Property - Property {Instance.ClassName}.{Name} does not exist!");
+ RobloxFile.LogError($"RobloxFiles.Property - Property {Instance.ClassName}.{Name} does not exist!");
}
}
}
@@ -248,10 +245,7 @@ namespace RobloxFiles
}
catch
{
- if (!RobloxFile.LogErrors)
- return;
-
- Console.Error.WriteLine($"RobloxFiles.Property - Failed to cast value {value} into property {Instance.ClassName}.{Name}");
+ RobloxFile.LogError($"RobloxFiles.Property - Failed to cast value {value} into property {Instance.ClassName}.{Name}");
}
}
else if (valueType != null)
@@ -267,10 +261,7 @@ namespace RobloxFiles
}
catch
{
- if (!RobloxFile.LogErrors)
- return;
-
- Console.Error.WriteLine($"RobloxFiles.Property - Failed to implicitly cast value {value} into property {Instance.ClassName}.{Name}");
+ RobloxFile.LogError($"RobloxFiles.Property - Failed to implicitly cast value {value} into property {Instance.ClassName}.{Name}");
}
}
}
diff --git a/XmlFormat/IO/XmlFileReader.cs b/XmlFormat/IO/XmlFileReader.cs
index 74f8119..1ab4806 100644
--- a/XmlFormat/IO/XmlFileReader.cs
+++ b/XmlFormat/IO/XmlFileReader.cs
@@ -109,7 +109,7 @@ namespace RobloxFiles.XmlFormat
if (!tokenHandler.ReadProperty(prop, propNode) && RobloxFile.LogErrors)
{
var readError = error($"Could not read property: {prop.GetFullName()}!");
- Console.Error.WriteLine(readError.Message);
+ RobloxFile.LogError(readError.Message);
}
instance.AddProperty(ref prop);
@@ -117,7 +117,7 @@ namespace RobloxFiles.XmlFormat
else if (RobloxFile.LogErrors)
{
var tokenError = error($"No {nameof(IXmlPropertyToken)} found for property type: {propType}!");
- Console.Error.WriteLine(tokenError.Message);
+ RobloxFile.LogError(tokenError.Message);
}
}
}
@@ -142,7 +142,7 @@ namespace RobloxFiles.XmlFormat
if (RobloxFile.LogErrors)
{
var typeError = error($"Unknown class {className} while reading Item.");
- Console.Error.WriteLine(typeError.Message);
+ RobloxFile.LogError(typeError.Message);
}
return null;
diff --git a/XmlFormat/IO/XmlFileWriter.cs b/XmlFormat/IO/XmlFileWriter.cs
index dffd385..fe7e4f2 100644
--- a/XmlFormat/IO/XmlFileWriter.cs
+++ b/XmlFormat/IO/XmlFileWriter.cs
@@ -94,9 +94,7 @@ namespace RobloxFiles.XmlFormat
if (handler == null)
{
- if (RobloxFile.LogErrors)
- Console.Error.WriteLine("XmlDataWriter.WriteProperty: No token handler found for property type: {0}", propType);
-
+ RobloxFile.LogError($"XmlRobloxFileWriter.WriteProperty: No token handler found for property type: {propType}");
return null;
}
diff --git a/XmlFormat/Tokens/Content.cs b/XmlFormat/Tokens/Content.cs
index e1073bf..df83b82 100644
--- a/XmlFormat/Tokens/Content.cs
+++ b/XmlFormat/Tokens/Content.cs
@@ -30,10 +30,7 @@ namespace RobloxFiles.XmlFormat.PropertyTokens
}
catch
{
- if (!RobloxFile.LogErrors)
- return true;
-
- Console.Error.WriteLine("ContentToken: Got illegal base64 string: {0}", data);
+ RobloxFile.LogError($"ContentToken: Got illegal base64 string: {data}");
}
}
}
diff --git a/XmlFormat/XmlRobloxFile.cs b/XmlFormat/XmlRobloxFile.cs
index ab8ce26..f727cae 100644
--- a/XmlFormat/XmlRobloxFile.cs
+++ b/XmlFormat/XmlRobloxFile.cs
@@ -97,11 +97,7 @@ namespace RobloxFiles
}
else if (refId != "null")
{
- string name = refProp.GetFullName();
-
- if (LogErrors)
- Console.Error.WriteLine("XmlRobloxFile: Could not resolve reference for {0}", name);
-
+ LogError($"XmlRobloxFile: Could not resolve reference for {refProp.GetFullName()}");
refProp.Value = null;
}
}
@@ -112,6 +108,14 @@ namespace RobloxFiles
foreach (Property sharedProp in sharedProps)
{
SharedString shared = sharedProp.CastValue();
+
+ if (shared == null)
+ {
+ var nullBuffer = Array.Empty();
+ shared = SharedString.FromBuffer(nullBuffer);
+ sharedProp.Value = shared;
+ }
+
SharedStrings.Add(shared.Key);
}
}