diff --git a/BinaryFormat/Chunks/PROP.cs b/BinaryFormat/Chunks/PROP.cs index 9bbcde3..0a41f0e 100644 --- a/BinaryFormat/Chunks/PROP.cs +++ b/BinaryFormat/Chunks/PROP.cs @@ -414,9 +414,13 @@ namespace RobloxFiles.BinaryFormat.Chunks for (int i = 0; i < instCount; i++) { - var cf = CFrames[i]; - bool active = reader.ReadBoolean(); - CFrames[i] = active ? cf : null; + CFrame cf = CFrames[i]; + bool archivable = reader.ReadBoolean(); + + if (!archivable) + cf = null; + + CFrames[i] = new Optional(cf); } } @@ -984,7 +988,14 @@ namespace RobloxFiles.BinaryFormat.Chunks return; } - writer.Write(true); + if (prop.Value is Optional optional) + { + writer.Write(optional.HasValue); + return; + } + + var cf = prop.Value as CFrame; + writer.Write(cf != null); }); } diff --git a/DataTypes/Optional.cs b/DataTypes/Optional.cs new file mode 100644 index 0000000..6476afa --- /dev/null +++ b/DataTypes/Optional.cs @@ -0,0 +1,35 @@ +namespace RobloxFiles.DataTypes +{ + // Optional represents a value that can be explicitly + // marked as an optional variant to a specified type. + // In practice this is used for OptionalCFrame. + + public struct Optional + { + public T Value; + public bool HasValue => (Value != null); + + public Optional(T value) + { + Value = value; + } + + public override string ToString() + { + return Value?.ToString() ?? "null"; + } + + public static implicit operator T(Optional optional) + { + if (optional.HasValue) + return optional.Value; + + return default(T); + } + + public static implicit operator Optional(T value) + { + return new Optional(value); + } + } +} diff --git a/Generated/Classes.cs b/Generated/Classes.cs index 8e86e9c..29e25c7 100644 --- a/Generated/Classes.cs +++ b/Generated/Classes.cs @@ -2408,7 +2408,7 @@ namespace RobloxFiles public Vector3 ModelMeshSize = new Vector3(); public bool NeedsPivotMigration; public BasePart PrimaryPart; - public CFrame WorldPivotData; + public Optional WorldPivotData; } public class Actor : Model diff --git a/Plugins/GenerateApiDump.rbxm b/Plugins/GenerateApiDump.rbxm index 2f2b34a..4afa18f 100644 Binary files a/Plugins/GenerateApiDump.rbxm and b/Plugins/GenerateApiDump.rbxm differ diff --git a/Plugins/GenerateApiDump/PropertyPatches.lua b/Plugins/GenerateApiDump/PropertyPatches.lua index 5bc8823..a82f466 100644 --- a/Plugins/GenerateApiDump/PropertyPatches.lua +++ b/Plugins/GenerateApiDump/PropertyPatches.lua @@ -378,7 +378,7 @@ return ModelMeshData = "SharedString"; ModelMeshSize = "Vector3"; NeedsPivotMigration = "bool"; - WorldPivotData = "OptionalCFrame"; + WorldPivotData = "Optional"; }; }; diff --git a/Plugins/GenerateApiDump/init.server.lua b/Plugins/GenerateApiDump/init.server.lua index 7faab5c..55f7110 100644 --- a/Plugins/GenerateApiDump/init.server.lua +++ b/Plugins/GenerateApiDump/init.server.lua @@ -640,10 +640,6 @@ local function generateClasses() writeLine("[Obsolete]") end - - if valueType == "OptionalCFrame" then - valueType = "CFrame" - end writeLine("public %s %s%s;", valueType, name, default) diff --git a/RobloxFileFormat.csproj b/RobloxFileFormat.csproj index e6de790..177bc3f 100644 --- a/RobloxFileFormat.csproj +++ b/RobloxFileFormat.csproj @@ -89,6 +89,7 @@ + diff --git a/RobloxFileFormat.dll b/RobloxFileFormat.dll index 4a60753..b218631 100644 Binary files a/RobloxFileFormat.dll and b/RobloxFileFormat.dll differ diff --git a/Tree/Instance.cs b/Tree/Instance.cs index 23bfa8d..6dbca3f 100644 --- a/Tree/Instance.cs +++ b/Tree/Instance.cs @@ -599,7 +599,7 @@ namespace RobloxFiles propType = Property.Types[fieldType]; else if (fieldType.IsEnum) propType = PropertyType.Enum; - + if (propType != PropertyType.Unknown) { if (fieldName.EndsWith("_")) @@ -615,24 +615,35 @@ namespace RobloxFiles case "String": case "Double": case "Int64": + { xmlToken = xmlToken.ToLowerInvariant(); break; + } case "Boolean": + { xmlToken = "bool"; break; + } case "Single": + { xmlToken = "float"; break; + } case "Int32": + { xmlToken = "int"; break; + } case "Rect": + { xmlToken = "Rect2D"; break; + } case "CFrame": + { xmlToken = "CoordinateFrame"; break; - default: break; + } } if (!props.ContainsKey(fieldName)) diff --git a/Tree/Property.cs b/Tree/Property.cs index be46578..3fb2027 100644 --- a/Tree/Property.cs +++ b/Tree/Property.cs @@ -88,8 +88,9 @@ namespace RobloxFiles { typeof(SharedString), PropertyType.SharedString }, { typeof(Vector3int16), PropertyType.Vector3int16 }, - { typeof(ColorSequence), PropertyType.ColorSequence }, - { typeof(NumberSequence), PropertyType.NumberSequence }, + { typeof(ColorSequence), PropertyType.ColorSequence }, + { typeof(NumberSequence), PropertyType.NumberSequence }, + { typeof(Optional), PropertyType.OptionalCFrame }, { typeof(ProtectedString), PropertyType.String }, { typeof(PhysicalProperties), PropertyType.PhysicalProperties },