0.604.0.6040508

This commit is contained in:
Max 2023-11-28 21:07:30 -06:00
parent 9f4f3bbf63
commit 4bac4d4f3e
17 changed files with 6548 additions and 5027 deletions

View File

@ -39,7 +39,7 @@ namespace RobloxFiles
public IReadOnlyDictionary<uint, SharedString> SharedStrings => SSTR?.Strings; public IReadOnlyDictionary<uint, SharedString> SharedStrings => SSTR?.Strings;
public bool HasSignatures => (SIGN != null); public bool HasSignatures => (SIGN != null);
public IReadOnlyList<Signature> Signatures => SIGN?.Signatures; public IReadOnlyList<RbxSignature> Signatures => SIGN?.Signatures;
public BinaryRobloxFile() public BinaryRobloxFile()
{ {

View File

@ -74,7 +74,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
var prop = new Property(instance, this); var prop = new Property(instance, this);
props[i] = prop; props[i] = prop;
instance.AddProperty(ref prop); instance.AddProperty(prop);
} }
// Setup some short-hand functions for actions used during the read procedure. // Setup some short-hand functions for actions used during the read procedure.
@ -103,7 +103,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
string value = reader.ReadString(); string value = reader.ReadString();
// Leave an access point for the original byte sequence, in case this is a BinaryString. // Leave an access point for the original byte sequence, in case this is a BinaryString.
// This will allow the developer to read the sequence without any mangling from C# strings. // This will allow the developer to read the sequence without any mangling from UTF-8.
byte[] buffer = reader.GetLastStringBuffer(); byte[] buffer = reader.GetLastStringBuffer();
props[i].RawBuffer = buffer; props[i].RawBuffer = buffer;
@ -132,6 +132,8 @@ namespace RobloxFiles.BinaryFormat.Chunks
if (memberType == typeof(byte[])) if (memberType == typeof(byte[]))
result = buffer; result = buffer;
else if (memberType == typeof(ProtectedString) && File.HasSignatures)
result = new ProtectedString(buffer); // Very likely compiled.
return result; return result;
} }
@ -661,6 +663,12 @@ namespace RobloxFiles.BinaryFormat.Chunks
break; break;
} }
case PropertyType.SecurityCapabilities:
{
var capabilities = reader.ReadInterleaved(instCount, BitConverter.ToUInt64);
readProperties(i => capabilities[i]);
break;
}
default: default:
{ {
RobloxFile.LogError($"Unhandled property type: {Type} in {this}!"); RobloxFile.LogError($"Unhandled property type: {Type} in {this}!");
@ -1301,6 +1309,20 @@ namespace RobloxFiles.BinaryFormat.Chunks
break; break;
} }
case PropertyType.SecurityCapabilities:
{
// FIXME: Verify this is correct once we know what SecurityCapabilities actually does.
var capabilities = new List<ulong>();
props.ForEach(prop =>
{
var value = prop.CastValue<ulong>();
capabilities.Add(value);
});
writer.WriteInterleaved(capabilities);
break;
}
default: default:
{ {
RobloxFile.LogError($"Unhandled property type: {Type} in {this}!"); RobloxFile.LogError($"Unhandled property type: {Type} in {this}!");

View File

@ -3,35 +3,37 @@ using System.Text;
namespace RobloxFiles.BinaryFormat.Chunks namespace RobloxFiles.BinaryFormat.Chunks
{ {
public struct Signature public enum RbxSignatureType
{ {
public int Version; Ed25519
public long Id; }
public int Length; public struct RbxSignature
public byte[] Data; {
public RbxSignatureType SignatureType;
public long PublicKeyId;
public byte[] Value;
} }
public class SIGN : IBinaryFileChunk public class SIGN : IBinaryFileChunk
{ {
public Signature[] Signatures; public RbxSignature[] Signatures;
public void Load(BinaryRobloxFileReader reader) public void Load(BinaryRobloxFileReader reader)
{ {
int numSignatures = reader.ReadInt32(); int numSignatures = reader.ReadInt32();
Signatures = new Signature[numSignatures]; Signatures = new RbxSignature[numSignatures];
for (int i = 0; i < numSignatures; i++) for (int i = 0; i < numSignatures; i++)
{ {
var signature = new Signature var signature = new RbxSignature
{ {
Version = reader.ReadInt32(), SignatureType = (RbxSignatureType)reader.ReadInt32(),
Id = reader.ReadInt64(), PublicKeyId = reader.ReadInt64(),
Length = reader.ReadInt32(),
}; };
signature.Data = reader.ReadBytes(signature.Length); var length = reader.ReadInt32();
signature.Value = reader.ReadBytes(length);
Signatures[i] = signature; Signatures[i] = signature;
} }
@ -46,13 +48,12 @@ namespace RobloxFiles.BinaryFormat.Chunks
for (int i = 0; i < Signatures.Length; i++) for (int i = 0; i < Signatures.Length; i++)
{ {
var signature = Signatures[i]; var signature = Signatures[i];
signature.Length = signature.Data.Length;
writer.Write(signature.Version); writer.Write((int)signature.SignatureType);
writer.Write(signature.Id); writer.Write(signature.PublicKeyId);
writer.Write(signature.Length); writer.Write(signature.Value.Length);
writer.Write(signature.Data); writer.Write(signature.Value);
} }
} }
@ -66,17 +67,14 @@ namespace RobloxFiles.BinaryFormat.Chunks
var signature = Signatures[i]; var signature = Signatures[i];
builder.AppendLine($"## Signature {i}"); builder.AppendLine($"## Signature {i}");
var version = signature.Version; var version = Enum.GetName(typeof(RbxSignatureType), signature.SignatureType);
builder.AppendLine($"- Version: {version}"); builder.AppendLine($"- SignatureType: {version}");
var id = signature.Id; var publicKeyId = signature.PublicKeyId;
builder.AppendLine($"- Id: {id}"); builder.AppendLine($"- PublicKeyId: {publicKeyId}");
var length = signature.Length; var value = Convert.ToBase64String(signature.Value);
builder.AppendLine($"- Length: {length}"); builder.AppendLine($"- Value: {value}");
var data = Convert.ToBase64String(signature.Data);
builder.AppendLine($"- Data: {data}");
} }
} }
} }

View File

@ -28,7 +28,15 @@ namespace RobloxFiles.DataTypes
public ProtectedString(byte[] compiled) public ProtectedString(byte[] compiled)
{ {
// This'll break in the future if Luau ever has more than 32 VM versions.
// Feels pretty unlikely this'll happen anytime soon, if ever.
IsCompiled = true; IsCompiled = true;
if (compiled.Length > 0)
if (compiled[0] >= 32)
IsCompiled = false;
RawBuffer = compiled; RawBuffer = compiled;
} }

View File

@ -1,5 +1,5 @@
// Auto-generated list of creatable Roblox classes. // Auto-generated list of creatable Roblox classes.
// Updated as of 0.600.1.6000716 // Updated as of 0.604.0.6040508
using System; using System;
@ -22,6 +22,14 @@ namespace RobloxFiles
public float Puffiness = 1; public float Puffiness = 1;
} }
public class AccountService : Instance
{
public AccountService()
{
IsService = true;
}
}
public class Accoutrement : Instance public class Accoutrement : Instance
{ {
public CFrame AttachmentPoint = CFrame.identity; public CFrame AttachmentPoint = CFrame.identity;
@ -406,6 +414,18 @@ namespace RobloxFiles
public VirtualCursorMode VirtualCursorMode = VirtualCursorMode.Default; public VirtualCursorMode VirtualCursorMode = VirtualCursorMode.Default;
} }
public abstract class BaseRemoteEvent : Instance
{
}
public class RemoteEvent : BaseRemoteEvent
{
}
public class UnreliableRemoteEvent : BaseRemoteEvent
{
}
public abstract class BaseWrap : Instance public abstract class BaseWrap : Instance
{ {
public Content CageMeshId = ""; public Content CageMeshId = "";
@ -893,7 +913,7 @@ namespace RobloxFiles
public class AlignOrientation : Constraint public class AlignOrientation : Constraint
{ {
public AlignType AlignType = AlignType.Parallel; public AlignType AlignType = AlignType.AllAxes;
public CFrame CFrame = CFrame.identity; public CFrame CFrame = CFrame.identity;
public float MaxAngularVelocity = float.MaxValue; public float MaxAngularVelocity = float.MaxValue;
public float MaxTorque = 10000; public float MaxTorque = 10000;
@ -1360,7 +1380,7 @@ namespace RobloxFiles
{ {
} }
public class DynamicMesh : DataModelMesh public class EditableMesh : DataModelMesh
{ {
public int MeshVersion = 0; public int MeshVersion = 0;
} }
@ -1483,7 +1503,7 @@ namespace RobloxFiles
} }
} }
public class DynamicImage : Instance public class EditableImage : Instance
{ {
public Vector2 Size = new Vector2(512, 512); public Vector2 Size = new Vector2(512, 512);
} }
@ -1917,6 +1937,8 @@ namespace RobloxFiles
} }
public float LineHeight = 1; public float LineHeight = 1;
public string LocalizationMatchIdentifier = "";
public string LocalizationMatchedSourceText = "";
public int MaxVisibleGraphemes = -1; public int MaxVisibleGraphemes = -1;
public bool RichText; public bool RichText;
public string Text = "Button"; public string Text = "Button";
@ -1999,6 +2021,8 @@ namespace RobloxFiles
} }
public float LineHeight = 1; public float LineHeight = 1;
public string LocalizationMatchIdentifier = "";
public string LocalizationMatchedSourceText = "";
public int MaxVisibleGraphemes = -1; public int MaxVisibleGraphemes = -1;
public bool RichText; public bool RichText;
public string Text = "Label"; public string Text = "Label";
@ -2083,6 +2107,8 @@ namespace RobloxFiles
} }
public float LineHeight = 1; public float LineHeight = 1;
public string LocalizationMatchIdentifier = "";
public string LocalizationMatchedSourceText = "";
public int MaxVisibleGraphemes = -1; public int MaxVisibleGraphemes = -1;
public bool MultiLine; public bool MultiLine;
public Color3 PlaceholderColor3 = Color3.FromRGB(178, 178, 178); public Color3 PlaceholderColor3 = Color3.FromRGB(178, 178, 178);
@ -2614,14 +2640,6 @@ namespace RobloxFiles
public bool AllowInsertFreeModels; public bool AllowInsertFreeModels;
} }
public class InternalSyncService : Instance
{
public InternalSyncService()
{
IsService = true;
}
}
public abstract class JointInstance : Instance public abstract class JointInstance : Instance
{ {
public CFrame C0 = CFrame.identity; public CFrame C0 = CFrame.identity;
@ -3084,7 +3102,7 @@ namespace RobloxFiles
} }
} }
public class OperationTree : Instance public class OperationGraph : Instance
{ {
} }
@ -3590,6 +3608,7 @@ namespace RobloxFiles
public MeshPartHeadsAndAccessories MeshPartHeadsAndAccessories = MeshPartHeadsAndAccessories.Default; public MeshPartHeadsAndAccessories MeshPartHeadsAndAccessories = MeshPartHeadsAndAccessories.Default;
public ModelStreamingBehavior ModelStreamingBehavior = ModelStreamingBehavior.Default; public ModelStreamingBehavior ModelStreamingBehavior = ModelStreamingBehavior.Default;
public PhysicsSteppingMethod PhysicsSteppingMethod = PhysicsSteppingMethod.Default; public PhysicsSteppingMethod PhysicsSteppingMethod = PhysicsSteppingMethod.Default;
public PlayerCharacterDestroyBehavior PlayerCharacterDestroyBehavior = PlayerCharacterDestroyBehavior.Default;
public PrimalPhysicsSolver PrimalPhysicsSolver = PrimalPhysicsSolver.Default; public PrimalPhysicsSolver PrimalPhysicsSolver = PrimalPhysicsSolver.Default;
public RejectCharacterDeletions RejectCharacterDeletions = RejectCharacterDeletions.Default; public RejectCharacterDeletions RejectCharacterDeletions = RejectCharacterDeletions.Default;
public ReplicateInstanceDestroySetting ReplicateInstanceDestroySetting = ReplicateInstanceDestroySetting.Default; public ReplicateInstanceDestroySetting ReplicateInstanceDestroySetting = ReplicateInstanceDestroySetting.Default;
@ -3611,8 +3630,10 @@ namespace RobloxFiles
public class PackageLink : Instance public class PackageLink : Instance
{ {
public bool AutoUpdate; public bool AutoUpdate;
public string DefaultName = "";
public int ModifiedState = 0; public int ModifiedState = 0;
public Content PackageIdSerialize = ""; public Content PackageIdSerialize = "";
public byte[] SerializedDefaultAttributes;
public long VersionIdSerialize = 0; public long VersionIdSerialize = 0;
} }
@ -3683,14 +3704,6 @@ namespace RobloxFiles
public float ZOffset = 0; public float ZOffset = 0;
} }
public class PatchBundlerFileWatch : Instance
{
public PatchBundlerFileWatch()
{
IsService = true;
}
}
public class PathfindingLink : Instance public class PathfindingLink : Instance
{ {
public Attachment Attachment0; public Attachment Attachment0;
@ -4061,10 +4074,6 @@ namespace RobloxFiles
} }
} }
public class RemoteEvent : Instance
{
}
public class RemoteFunction : Instance public class RemoteFunction : Instance
{ {
} }
@ -4399,6 +4408,7 @@ namespace RobloxFiles
public NumberRange LoopRegion = new NumberRange(0, 60000); public NumberRange LoopRegion = new NumberRange(0, 60000);
public bool Looped; public bool Looped;
[Obsolete]
public float MinDistance public float MinDistance
{ {
get => EmitterSize; get => EmitterSize;
@ -4422,8 +4432,11 @@ namespace RobloxFiles
public Content SoundId = ""; public Content SoundId = "";
public double TimePosition = 0; public double TimePosition = 0;
public float Volume = 0.5f; public float Volume = 0.5f;
[Obsolete]
public float xmlRead_MaxDistance_3 = 10000; public float xmlRead_MaxDistance_3 = 10000;
[Obsolete]
public float xmlRead_MinDistance_3 public float xmlRead_MinDistance_3
{ {
get => EmitterSize; get => EmitterSize;
@ -4607,6 +4620,7 @@ namespace RobloxFiles
public HumanoidStateMachineMode HumanoidStateMachineMode = HumanoidStateMachineMode.Default; public HumanoidStateMachineMode HumanoidStateMachineMode = HumanoidStateMachineMode.Default;
public bool LoadCharacterAppearance = true; public bool LoadCharacterAppearance = true;
public LoadCharacterLayeredClothing LoadCharacterLayeredClothing = LoadCharacterLayeredClothing.Default; public LoadCharacterLayeredClothing LoadCharacterLayeredClothing = LoadCharacterLayeredClothing.Default;
public CharacterControlMode LuaCharacterController = CharacterControlMode.Default;
public float NameDisplayDistance = 100; public float NameDisplayDistance = 100;
public bool UserEmotesEnabled = true; public bool UserEmotesEnabled = true;
} }
@ -4667,6 +4681,8 @@ namespace RobloxFiles
{ {
IsService = true; IsService = true;
} }
public bool PublishLocked;
} }
public class StudioSdkService : Instance public class StudioSdkService : Instance
@ -4800,6 +4816,14 @@ namespace RobloxFiles
public bool CustomizedTeleportUI; public bool CustomizedTeleportUI;
} }
public class TemporaryCageMeshProvider : Instance
{
public TemporaryCageMeshProvider()
{
IsService = true;
}
}
public class TemporaryScriptService : Instance public class TemporaryScriptService : Instance
{ {
public TemporaryScriptService() public TemporaryScriptService()
@ -4945,6 +4969,14 @@ namespace RobloxFiles
} }
} }
public class TextureGenerationMeshHandler : Instance
{
public TextureGenerationMeshHandler()
{
IsService = true;
}
}
public class TimerService : Instance public class TimerService : Instance
{ {
public TimerService() public TimerService()
@ -5408,6 +5440,14 @@ namespace RobloxFiles
} }
} }
public class VoiceChatInternal : Instance
{
public VoiceChatInternal()
{
IsService = true;
}
}
public class VoiceChatService : Instance public class VoiceChatService : Instance
{ {
public VoiceChatService() public VoiceChatService()
@ -5416,6 +5456,7 @@ namespace RobloxFiles
} }
public bool EnableDefaultVoice = true; public bool EnableDefaultVoice = true;
public AudioApiRollout UseAudioApi = AudioApiRollout.Automatic;
} }
public class WeldConstraint : Instance public class WeldConstraint : Instance

View File

@ -1,5 +1,5 @@
// Auto-generated list of Roblox enums. // Auto-generated list of Roblox enums.
// Updated as of 0.600.1.6000716 // Updated as of 0.604.0.6040508
namespace RobloxFiles.Enums namespace RobloxFiles.Enums
{ {
@ -61,7 +61,11 @@ namespace RobloxFiles.Enums
public enum AlignType public enum AlignType
{ {
Parallel, Parallel,
Perpendicular Perpendicular,
PrimaryAxisParallel,
PrimaryAxisPerpendicular,
PrimaryAxisLookAt,
AllAxes
} }
public enum AlphaMode public enum AlphaMode
@ -107,6 +111,13 @@ namespace RobloxFiles.Enums
ScaleWithParentSize ScaleWithParentSize
} }
public enum AudioApiRollout
{
Disabled,
Automatic,
Enabled
}
public enum AudioSubType public enum AudioSubType
{ {
Music = 1, Music = 1,
@ -196,6 +207,14 @@ namespace RobloxFiles.Enums
Orbital Orbital
} }
public enum CharacterControlMode
{
Default,
Legacy,
NoCharacterController,
LuaCharacterController
}
public enum ChatVersion public enum ChatVersion
{ {
LegacyChatService, LegacyChatService,
@ -1070,6 +1089,13 @@ namespace RobloxFiles.Enums
Adaptive Adaptive
} }
public enum PlayerCharacterDestroyBehavior
{
Default,
Disabled,
Enabled
}
public enum PoseEasingDirection public enum PoseEasingDirection
{ {
In, In,

View File

@ -24,6 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -32,6 +33,25 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL"> <Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
@ -147,6 +167,7 @@
<Compile Include="Tokens\Ray.cs" /> <Compile Include="Tokens\Ray.cs" />
<Compile Include="Tokens\Rect.cs" /> <Compile Include="Tokens\Rect.cs" />
<Compile Include="Tokens\Ref.cs" /> <Compile Include="Tokens\Ref.cs" />
<Compile Include="Tokens\SecurityCapabilities.cs" />
<Compile Include="Tokens\SharedString.cs" /> <Compile Include="Tokens\SharedString.cs" />
<Compile Include="Tokens\String.cs" /> <Compile Include="Tokens\String.cs" />
<Compile Include="Tokens\UDim.cs" /> <Compile Include="Tokens\UDim.cs" />

Binary file not shown.

View File

@ -1,26 +1,36 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 17
VisualStudioVersion = 16.0.31507.150 VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobloxFileFormat", "RobloxFileFormat.csproj", "{19400E0B-6CA3-4171-9644-657E9858275C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobloxFileFormat", "RobloxFileFormat.csproj", "{CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RobloxFileFormat.UnitTest", "UnitTest\RobloxFileFormat.UnitTest.csproj", "{E9FF1680-6FB9-41CD-9A73-7D072CB91118}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RobloxFileFormat.UnitTest", "UnitTest\RobloxFileFormat.UnitTest.csproj", "{E9FF1680-6FB9-41CD-9A73-7D072CB91118}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{19400E0B-6CA3-4171-9644-657E9858275C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19400E0B-6CA3-4171-9644-657E9858275C}.Debug|Any CPU.Build.0 = Debug|Any CPU {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19400E0B-6CA3-4171-9644-657E9858275C}.Release|Any CPU.ActiveCfg = Release|Any CPU {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Debug|x64.ActiveCfg = Debug|x64
{19400E0B-6CA3-4171-9644-657E9858275C}.Release|Any CPU.Build.0 = Release|Any CPU {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Debug|x64.Build.0 = Debug|x64
{CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Release|Any CPU.Build.0 = Release|Any CPU
{CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Release|x64.ActiveCfg = Release|x64
{CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Release|x64.Build.0 = Release|x64
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Debug|x64.ActiveCfg = Debug|x64
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Debug|x64.Build.0 = Debug|x64
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Release|Any CPU.Build.0 = Release|Any CPU {E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Release|Any CPU.Build.0 = Release|Any CPU
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Release|x64.ActiveCfg = Release|x64
{E9FF1680-6FB9-41CD-9A73-7D072CB91118}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -0,0 +1,26 @@
using System.Xml;
namespace RobloxFiles.Tokens
{
public class SecurityCapabilitiesToken : IXmlPropertyToken
{
public string XmlPropertyToken => "SecurityCapabilities";
public bool ReadProperty(Property prop, XmlNode node)
{
if (ulong.TryParse(node.InnerText, out var value))
{
prop.Value = value;
return true;
}
return false;
}
public void WriteProperty(Property prop, XmlDocument doc, XmlNode node)
{
var value = prop.CastValue<ulong>();
node.InnerText = value.ToString();
}
}
}

View File

@ -45,6 +45,12 @@ namespace RobloxFiles
/// <summary>The source AssetId this instance was created in.</summary> /// <summary>The source AssetId this instance was created in.</summary>
public long SourceAssetId = -1; public long SourceAssetId = -1;
/// <summary>Whether the instance defines security capabilities.</summary>
public bool DefinesCapabilities = false;
/// <summary>The SecurityCapabilities of this instance.</summary>
public ulong Capabilities = 0;
/// <summary>A unique identifier declared for the history of this instance.</summary> /// <summary>A unique identifier declared for the history of this instance.</summary>
public UniqueId HistoryId = new UniqueId(0, 0, 0); public UniqueId HistoryId = new UniqueId(0, 0, 0);
@ -531,7 +537,7 @@ namespace RobloxFiles
if (newProp.Type == PropertyType.Ref) if (newProp.Type == PropertyType.Ref)
refProps.Add(newProp); refProps.Add(newProp);
newInst.AddProperty(ref newProp); newInst.AddProperty(newProp);
} }
var oldParent = oldInst.Parent; var oldParent = oldInst.Parent;
@ -628,7 +634,7 @@ namespace RobloxFiles
/// Adds a property by reference to this Instance's property list. /// Adds a property by reference to this Instance's property list.
/// </summary> /// </summary>
/// <param name="prop">A reference to the property that will be added.</param> /// <param name="prop">A reference to the property that will be added.</param>
internal void AddProperty(ref Property prop) internal void AddProperty(Property prop)
{ {
string name = prop.Name; string name = prop.Name;
RemoveProperty(name); RemoveProperty(name);
@ -755,7 +761,7 @@ namespace RobloxFiles
Instance = this Instance = this
}; };
AddProperty(ref newProp); AddProperty(newProp);
} }
else else
{ {
@ -784,7 +790,7 @@ namespace RobloxFiles
if (GetProperty(name) == null) if (GetProperty(name) == null)
{ {
var prop = new Property(name, propType); var prop = new Property(name, propType);
AddProperty(ref prop); AddProperty(prop);
} }
} }

View File

@ -42,7 +42,8 @@ namespace RobloxFiles
ProtectedString, ProtectedString,
OptionalCFrame, OptionalCFrame,
UniqueId, UniqueId,
FontFace FontFace,
SecurityCapabilities,
} }
public class Property public class Property
@ -58,8 +59,7 @@ namespace RobloxFiles
internal static BindingFlags BindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase; internal static BindingFlags BindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase;
// TODO: Map typeof(ProtectedString) to PropertyType.ProtectedString // FIXME: Add a proper type for SecurityCapabilities once it's purpose is better understood.
// if binary files are ever publicly allowed to read it.
public static readonly IReadOnlyDictionary<Type, PropertyType> Types = new Dictionary<Type, PropertyType>() public static readonly IReadOnlyDictionary<Type, PropertyType> Types = new Dictionary<Type, PropertyType>()
{ {
@ -95,8 +95,9 @@ namespace RobloxFiles
{ typeof(NumberSequence), PropertyType.NumberSequence }, { typeof(NumberSequence), PropertyType.NumberSequence },
{ typeof(Optional<CFrame>), PropertyType.OptionalCFrame }, { typeof(Optional<CFrame>), PropertyType.OptionalCFrame },
{ typeof(ProtectedString), PropertyType.String }, { typeof(ProtectedString), PropertyType.ProtectedString },
{ typeof(PhysicalProperties), PropertyType.PhysicalProperties }, { typeof(PhysicalProperties), PropertyType.PhysicalProperties },
{ typeof(ulong), PropertyType.SecurityCapabilities },
}; };
private void ImproviseRawBuffer() private void ImproviseRawBuffer()

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -113,7 +113,7 @@ namespace RobloxFiles.XmlFormat
RobloxFile.LogError(readError.Message); RobloxFile.LogError(readError.Message);
} }
instance.AddProperty(ref prop); instance.AddProperty(prop);
} }
else if (RobloxFile.LogErrors) else if (RobloxFile.LogErrors)
{ {

View File

@ -99,7 +99,7 @@ namespace RobloxFiles
Instance refInst = Instances[refId]; Instance refInst = Instances[refId];
refProp.Value = refInst; refProp.Value = refInst;
} }
else if (refId != "null") else if (refId != "null" && refId != "Ref")
{ {
LogError($"XmlRobloxFile: Could not resolve reference for {refProp.GetFullName()}"); LogError($"XmlRobloxFile: Could not resolve reference for {refProp.GetFullName()}");
refProp.Value = null; refProp.Value = null;