0.476.0.421371
This commit is contained in:
parent
31eddea24e
commit
009d84f49f
@ -82,31 +82,46 @@ namespace RobloxFiles
|
|||||||
switch (chunk.ChunkType)
|
switch (chunk.ChunkType)
|
||||||
{
|
{
|
||||||
case "INST":
|
case "INST":
|
||||||
|
{
|
||||||
handler = new INST();
|
handler = new INST();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "PROP":
|
case "PROP":
|
||||||
|
{
|
||||||
handler = new PROP();
|
handler = new PROP();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "PRNT":
|
case "PRNT":
|
||||||
|
{
|
||||||
handler = new PRNT();
|
handler = new PRNT();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "META":
|
case "META":
|
||||||
|
{
|
||||||
handler = new META();
|
handler = new META();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "SSTR":
|
case "SSTR":
|
||||||
|
{
|
||||||
handler = new SSTR();
|
handler = new SSTR();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "SIGN":
|
case "SIGN":
|
||||||
|
{
|
||||||
handler = new SIGN();
|
handler = new SIGN();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "END\0":
|
case "END\0":
|
||||||
|
{
|
||||||
ChunksImpl.Add(chunk);
|
ChunksImpl.Add(chunk);
|
||||||
reading = false;
|
reading = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case string unhandled:
|
case string unhandled:
|
||||||
Console.Error.WriteLine("BinaryRobloxFile - Unhandled chunk-type: {0}!", unhandled);
|
{
|
||||||
|
LogError($"BinaryRobloxFile - Unhandled chunk-type: {unhandled}!");
|
||||||
break;
|
break;
|
||||||
default: break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using RobloxFiles.Enums;
|
using RobloxFiles.Enums;
|
||||||
using RobloxFiles.DataTypes;
|
using RobloxFiles.DataTypes;
|
||||||
using RobloxFiles.Utility;
|
using RobloxFiles.Utility;
|
||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace RobloxFiles.BinaryFormat.Chunks
|
namespace RobloxFiles.BinaryFormat.Chunks
|
||||||
{
|
{
|
||||||
public class PROP : IBinaryFileChunk
|
public class PROP : IBinaryFileChunk
|
||||||
{
|
{
|
||||||
private BinaryRobloxFile File;
|
private BinaryRobloxFile File;
|
||||||
public string Name { get; internal set; }
|
|
||||||
|
|
||||||
|
public string Name { get; internal set; }
|
||||||
public int ClassIndex { get; internal set; }
|
public int ClassIndex { get; internal set; }
|
||||||
public string ClassName { get; private set; }
|
|
||||||
|
private INST Class => File.Classes[ClassIndex];
|
||||||
|
public string ClassName => Class?.ClassName;
|
||||||
|
|
||||||
public PropertyType Type { get; internal set; }
|
public PropertyType Type { get; internal set; }
|
||||||
|
|
||||||
public byte TypeId
|
internal byte TypeId
|
||||||
{
|
{
|
||||||
get { return (byte)Type; }
|
get { return (byte)Type; }
|
||||||
internal set { Type = (PropertyType)value; }
|
set { Type = (PropertyType)value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -35,26 +36,29 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
|
|
||||||
public void Load(BinaryRobloxFileReader reader)
|
public void Load(BinaryRobloxFileReader reader)
|
||||||
{
|
{
|
||||||
BinaryRobloxFile file = reader.File;
|
File = reader.File;
|
||||||
File = file;
|
|
||||||
|
|
||||||
ClassIndex = reader.ReadInt32();
|
ClassIndex = reader.ReadInt32();
|
||||||
Name = reader.ReadString();
|
Name = reader.ReadString();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
byte propType = reader.ReadByte();
|
byte propType = reader.ReadByte();
|
||||||
Type = (PropertyType)propType;
|
Type = (PropertyType)propType;
|
||||||
|
}
|
||||||
|
catch (EndOfStreamException)
|
||||||
|
{
|
||||||
|
RobloxFile.LogError($"Got corrupted PROP chunk (@ {this})!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
INST inst = file.Classes[ClassIndex];
|
var ids = Class.InstanceIds;
|
||||||
ClassName = inst.ClassName;
|
int instCount = Class.NumInstances;
|
||||||
|
var props = new Property[instCount];
|
||||||
var ids = inst.InstanceIds;
|
|
||||||
int instCount = inst.NumInstances;
|
|
||||||
var props = new Property[inst.NumInstances];
|
|
||||||
|
|
||||||
for (int i = 0; i < instCount; i++)
|
for (int i = 0; i < instCount; i++)
|
||||||
{
|
{
|
||||||
int id = ids[i];
|
int id = ids[i];
|
||||||
Instance instance = file.Instances[id];
|
Instance instance = File.Instances[id];
|
||||||
|
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
{
|
{
|
||||||
@ -62,7 +66,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Property prop = new Property(instance, this);
|
var prop = new Property(instance, this);
|
||||||
props[i] = prop;
|
props[i] = prop;
|
||||||
|
|
||||||
instance.AddProperty(ref prop);
|
instance.AddProperty(ref prop);
|
||||||
@ -88,6 +92,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case PropertyType.String:
|
case PropertyType.String:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
string value = reader.ReadString();
|
string value = reader.ReadString();
|
||||||
@ -104,7 +109,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
{
|
{
|
||||||
case "Tags":
|
case "Tags":
|
||||||
case "AttributesSerialize":
|
case "AttributesSerialize":
|
||||||
|
{
|
||||||
return buffer;
|
return buffer;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Property prop = props[i];
|
Property prop = props[i];
|
||||||
@ -130,21 +137,31 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Bool:
|
case PropertyType.Bool:
|
||||||
|
{
|
||||||
readProperties(i => reader.ReadBoolean());
|
readProperties(i => reader.ReadBoolean());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Int:
|
case PropertyType.Int:
|
||||||
|
{
|
||||||
int[] ints = readInts();
|
int[] ints = readInts();
|
||||||
readProperties(i => ints[i]);
|
readProperties(i => ints[i]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Float:
|
case PropertyType.Float:
|
||||||
|
{
|
||||||
float[] floats = readFloats();
|
float[] floats = readFloats();
|
||||||
readProperties(i => floats[i]);
|
readProperties(i => floats[i]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Double:
|
case PropertyType.Double:
|
||||||
|
{
|
||||||
readProperties(i => reader.ReadDouble());
|
readProperties(i => reader.ReadDouble());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.UDim:
|
case PropertyType.UDim:
|
||||||
|
{
|
||||||
float[] UDim_Scales = readFloats();
|
float[] UDim_Scales = readFloats();
|
||||||
int[] UDim_Offsets = readInts();
|
int[] UDim_Offsets = readInts();
|
||||||
|
|
||||||
@ -156,7 +173,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.UDim2:
|
case PropertyType.UDim2:
|
||||||
|
{
|
||||||
float[] UDim2_Scales_X = readFloats(),
|
float[] UDim2_Scales_X = readFloats(),
|
||||||
UDim2_Scales_Y = readFloats();
|
UDim2_Scales_Y = readFloats();
|
||||||
|
|
||||||
@ -175,7 +194,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Ray:
|
case PropertyType.Ray:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
float posX = reader.ReadFloat(),
|
float posX = reader.ReadFloat(),
|
||||||
@ -186,14 +207,16 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
dirY = reader.ReadFloat(),
|
dirY = reader.ReadFloat(),
|
||||||
dirZ = reader.ReadFloat();
|
dirZ = reader.ReadFloat();
|
||||||
|
|
||||||
Vector3 origin = new Vector3(posX, posY, posZ);
|
var origin = new Vector3(posX, posY, posZ);
|
||||||
Vector3 direction = new Vector3(dirX, dirY, dirZ);
|
var direction = new Vector3(dirX, dirY, dirZ);
|
||||||
|
|
||||||
return new Ray(origin, direction);
|
return new Ray(origin, direction);
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Faces:
|
case PropertyType.Faces:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
byte faces = reader.ReadByte();
|
byte faces = reader.ReadByte();
|
||||||
@ -201,7 +224,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Axes:
|
case PropertyType.Axes:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
byte axes = reader.ReadByte();
|
byte axes = reader.ReadByte();
|
||||||
@ -209,17 +234,21 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.BrickColor:
|
case PropertyType.BrickColor:
|
||||||
|
{
|
||||||
int[] BrickColorIds = readInts();
|
int[] BrickColorIds = readInts();
|
||||||
|
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
int number = BrickColorIds[i];
|
BrickColor color = BrickColorIds[i];
|
||||||
return BrickColor.FromNumber(number);
|
return color;
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Color3:
|
case PropertyType.Color3:
|
||||||
|
{
|
||||||
float[] Color3_R = readFloats(),
|
float[] Color3_R = readFloats(),
|
||||||
Color3_G = readFloats(),
|
Color3_G = readFloats(),
|
||||||
Color3_B = readFloats();
|
Color3_B = readFloats();
|
||||||
@ -234,7 +263,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Vector2:
|
case PropertyType.Vector2:
|
||||||
|
{
|
||||||
float[] Vector2_X = readFloats(),
|
float[] Vector2_X = readFloats(),
|
||||||
Vector2_Y = readFloats();
|
Vector2_Y = readFloats();
|
||||||
|
|
||||||
@ -247,7 +278,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Vector3:
|
case PropertyType.Vector3:
|
||||||
|
{
|
||||||
float[] Vector3_X = readFloats(),
|
float[] Vector3_X = readFloats(),
|
||||||
Vector3_Y = readFloats(),
|
Vector3_Y = readFloats(),
|
||||||
Vector3_Z = readFloats();
|
Vector3_Z = readFloats();
|
||||||
@ -262,12 +295,26 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.CFrame:
|
case PropertyType.CFrame:
|
||||||
case PropertyType.Quaternion:
|
case PropertyType.Quaternion:
|
||||||
// Temporarily load the rotation matrices into their properties.
|
case PropertyType.OptionalCFrame:
|
||||||
// We'll update them to CFrames once we iterate over the position data.
|
{
|
||||||
float[][] matrices = new float[instCount][];
|
float[][] matrices = new float[instCount][];
|
||||||
|
|
||||||
|
if (Type == PropertyType.OptionalCFrame)
|
||||||
|
{
|
||||||
|
byte cframeType = (byte)PropertyType.CFrame;
|
||||||
|
byte readType = reader.ReadByte();
|
||||||
|
|
||||||
|
if (readType != cframeType)
|
||||||
|
{
|
||||||
|
RobloxFile.LogError($"Unexpected property type in OptionalCFrame (expected {cframeType}, got {readType})");
|
||||||
|
readProperties(i => null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < instCount; i++)
|
for (int i = 0; i < instCount; i++)
|
||||||
{
|
{
|
||||||
byte rawOrientId = reader.ReadByte();
|
byte rawOrientId = reader.ReadByte();
|
||||||
@ -296,11 +343,14 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
}
|
}
|
||||||
else if (Type == PropertyType.Quaternion)
|
else if (Type == PropertyType.Quaternion)
|
||||||
{
|
{
|
||||||
float qx = reader.ReadFloat(), qy = reader.ReadFloat(),
|
float qx = reader.ReadFloat(),
|
||||||
qz = reader.ReadFloat(), qw = reader.ReadFloat();
|
qy = reader.ReadFloat(),
|
||||||
|
qz = reader.ReadFloat(),
|
||||||
|
qw = reader.ReadFloat();
|
||||||
|
|
||||||
Quaternion quaternion = new Quaternion(qx, qy, qz, qw);
|
var quaternion = new Quaternion(qx, qy, qz, qw);
|
||||||
var rotation = quaternion.ToCFrame();
|
var rotation = quaternion.ToCFrame();
|
||||||
|
|
||||||
matrices[i] = rotation.GetComponents();
|
matrices[i] = rotation.GetComponents();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -321,7 +371,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
CFrame_Y = readFloats(),
|
CFrame_Y = readFloats(),
|
||||||
CFrame_Z = readFloats();
|
CFrame_Z = readFloats();
|
||||||
|
|
||||||
readProperties(i =>
|
var CFrames = new CFrame[instCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < instCount; i++)
|
||||||
{
|
{
|
||||||
float[] matrix = matrices[i];
|
float[] matrix = matrices[i];
|
||||||
|
|
||||||
@ -345,11 +397,34 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
components = position.Concat(matrix).ToArray();
|
components = position.Concat(matrix).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CFrame(components);
|
CFrames[i] = new CFrame(components);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (Type == PropertyType.OptionalCFrame)
|
||||||
|
{
|
||||||
|
byte boolType = (byte)PropertyType.Bool;
|
||||||
|
byte readType = reader.ReadByte();
|
||||||
|
|
||||||
|
if (readType != boolType)
|
||||||
|
{
|
||||||
|
RobloxFile.LogError($"Unexpected property type in OptionalCFrame (expected {boolType}, got {readType})");
|
||||||
|
readProperties(i => null);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < instCount; i++)
|
||||||
|
{
|
||||||
|
var cf = CFrames[i];
|
||||||
|
bool active = reader.ReadBoolean();
|
||||||
|
CFrames[i] = active ? cf : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readProperties(i => CFrames[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Enum:
|
case PropertyType.Enum:
|
||||||
|
{
|
||||||
uint[] enums = reader.ReadUInts(instCount);
|
uint[] enums = reader.ReadUInts(instCount);
|
||||||
|
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
@ -366,7 +441,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
|
|
||||||
if (info == null)
|
if (info == null)
|
||||||
{
|
{
|
||||||
RobloxFile.LogError($"Enum cast failed for {inst.ClassName}.{Name} using value {value}!");
|
RobloxFile.LogError($"Enum cast failed for {ClassName}.{Name} using value {value}!");
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,23 +449,27 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
RobloxFile.LogError($"Enum cast failed for {inst.ClassName}.{Name} using value {value}!");
|
RobloxFile.LogError($"Enum cast failed for {ClassName}.{Name} using value {value}!");
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Ref:
|
case PropertyType.Ref:
|
||||||
|
{
|
||||||
var instIds = reader.ReadInstanceIds(instCount);
|
var instIds = reader.ReadInstanceIds(instCount);
|
||||||
|
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
int instId = instIds[i];
|
int instId = instIds[i];
|
||||||
return instId >= 0 ? file.Instances[instId] : null;
|
return instId >= 0 ? File.Instances[instId] : null;
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Vector3int16:
|
case PropertyType.Vector3int16:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
short x = reader.ReadInt16(),
|
short x = reader.ReadInt16(),
|
||||||
@ -401,7 +480,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.NumberSequence:
|
case PropertyType.NumberSequence:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
int numKeys = reader.ReadInt32();
|
int numKeys = reader.ReadInt32();
|
||||||
@ -420,7 +501,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.ColorSequence:
|
case PropertyType.ColorSequence:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
int numKeys = reader.ReadInt32();
|
int numKeys = reader.ReadInt32();
|
||||||
@ -443,7 +526,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.NumberRange:
|
case PropertyType.NumberRange:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
float min = reader.ReadFloat();
|
float min = reader.ReadFloat();
|
||||||
@ -453,7 +538,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Rect:
|
case PropertyType.Rect:
|
||||||
|
{
|
||||||
float[] Rect_X0 = readFloats(), Rect_Y0 = readFloats(),
|
float[] Rect_X0 = readFloats(), Rect_Y0 = readFloats(),
|
||||||
Rect_X1 = readFloats(), Rect_Y1 = readFloats();
|
Rect_X1 = readFloats(), Rect_Y1 = readFloats();
|
||||||
|
|
||||||
@ -466,7 +553,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.PhysicalProperties:
|
case PropertyType.PhysicalProperties:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
bool custom = reader.ReadBoolean();
|
bool custom = reader.ReadBoolean();
|
||||||
@ -493,7 +582,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Color3uint8:
|
case PropertyType.Color3uint8:
|
||||||
|
{
|
||||||
byte[] Color3uint8_R = reader.ReadBytes(instCount),
|
byte[] Color3uint8_R = reader.ReadBytes(instCount),
|
||||||
Color3uint8_G = reader.ReadBytes(instCount),
|
Color3uint8_G = reader.ReadBytes(instCount),
|
||||||
Color3uint8_B = reader.ReadBytes(instCount);
|
Color3uint8_B = reader.ReadBytes(instCount);
|
||||||
@ -509,26 +600,32 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Int64:
|
case PropertyType.Int64:
|
||||||
long[] Int64s = reader.ReadInterleaved(instCount, (buffer, start) =>
|
{
|
||||||
|
long[] longs = reader.ReadInterleaved(instCount, (buffer, start) =>
|
||||||
{
|
{
|
||||||
long result = BitConverter.ToInt64(buffer, start);
|
long result = BitConverter.ToInt64(buffer, start);
|
||||||
return (long)((ulong)result >> 1) ^ (-(result & 1));
|
return (long)((ulong)result >> 1) ^ (-(result & 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
readProperties(i => Int64s[i]);
|
readProperties(i => longs[i]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.SharedString:
|
case PropertyType.SharedString:
|
||||||
|
{
|
||||||
uint[] SharedKeys = reader.ReadUInts(instCount);
|
uint[] SharedKeys = reader.ReadUInts(instCount);
|
||||||
|
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
uint key = SharedKeys[i];
|
uint key = SharedKeys[i];
|
||||||
return file.SharedStrings[key];
|
return File.SharedStrings[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.ProtectedString:
|
case PropertyType.ProtectedString:
|
||||||
|
{
|
||||||
readProperties(i =>
|
readProperties(i =>
|
||||||
{
|
{
|
||||||
int length = reader.ReadInt32();
|
int length = reader.ReadInt32();
|
||||||
@ -538,10 +635,12 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
RobloxFile.LogError($"Unhandled property type: {Type}!");
|
{
|
||||||
|
RobloxFile.LogError($"Unhandled property type: {Type} in {this}!");
|
||||||
break;
|
break;
|
||||||
//
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
@ -574,7 +673,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
Name = prop.Name,
|
Name = prop.Name,
|
||||||
Type = prop.Type,
|
Type = prop.Type,
|
||||||
|
|
||||||
ClassName = inst.ClassName,
|
File = writer.File,
|
||||||
ClassIndex = inst.ClassIndex
|
ClassIndex = inst.ClassIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -630,6 +729,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case PropertyType.Bool:
|
case PropertyType.Bool:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
bool value = prop.CastValue<bool>();
|
bool value = prop.CastValue<bool>();
|
||||||
@ -637,29 +737,27 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Int:
|
case PropertyType.Int:
|
||||||
var ints = new List<int>();
|
|
||||||
|
|
||||||
props.ForEach(prop =>
|
|
||||||
{
|
{
|
||||||
int value = prop.CastValue<int>();
|
var ints = props
|
||||||
ints.Add(value);
|
.Select(prop => prop.CastValue<int>())
|
||||||
});
|
.ToList();
|
||||||
|
|
||||||
writer.WriteInts(ints);
|
writer.WriteInts(ints);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Float:
|
case PropertyType.Float:
|
||||||
var floats = new List<float>();
|
|
||||||
|
|
||||||
props.ForEach(prop =>
|
|
||||||
{
|
{
|
||||||
float value = prop.CastValue<float>();
|
var floats = props
|
||||||
floats.Add(value);
|
.Select(prop => prop.CastValue<float>())
|
||||||
});
|
.ToList();
|
||||||
|
|
||||||
writer.WriteFloats(floats);
|
writer.WriteFloats(floats);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Double:
|
case PropertyType.Double:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
double value = prop.CastValue<double>();
|
double value = prop.CastValue<double>();
|
||||||
@ -667,7 +765,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.UDim:
|
case PropertyType.UDim:
|
||||||
|
{
|
||||||
var UDim_Scales = new List<float>();
|
var UDim_Scales = new List<float>();
|
||||||
var UDim_Offsets = new List<int>();
|
var UDim_Offsets = new List<int>();
|
||||||
|
|
||||||
@ -682,7 +782,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteInts(UDim_Offsets);
|
writer.WriteInts(UDim_Offsets);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.UDim2:
|
case PropertyType.UDim2:
|
||||||
|
{
|
||||||
var UDim2_Scales_X = new List<float>();
|
var UDim2_Scales_X = new List<float>();
|
||||||
var UDim2_Scales_Y = new List<float>();
|
var UDim2_Scales_Y = new List<float>();
|
||||||
|
|
||||||
@ -707,7 +809,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteInts(UDim2_Offsets_Y);
|
writer.WriteInts(UDim2_Offsets_Y);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Ray:
|
case PropertyType.Ray:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
Ray ray = prop.CastValue<Ray>();
|
Ray ray = prop.CastValue<Ray>();
|
||||||
@ -724,8 +828,10 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Faces:
|
case PropertyType.Faces:
|
||||||
case PropertyType.Axes:
|
case PropertyType.Axes:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
byte value = prop.CastValue<byte>();
|
byte value = prop.CastValue<byte>();
|
||||||
@ -733,18 +839,19 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.BrickColor:
|
case PropertyType.BrickColor:
|
||||||
var BrickColorIds = new List<int>();
|
|
||||||
|
|
||||||
props.ForEach(prop =>
|
|
||||||
{
|
{
|
||||||
BrickColor value = prop.CastValue<BrickColor>();
|
var brickColorIds = props
|
||||||
BrickColorIds.Add(value.Number);
|
.Select(prop => prop.CastValue<BrickColor>())
|
||||||
});
|
.Select(value => value.Number)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
writer.WriteInts(BrickColorIds);
|
writer.WriteInts(brickColorIds);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Color3:
|
case PropertyType.Color3:
|
||||||
|
{
|
||||||
var Color3_R = new List<float>();
|
var Color3_R = new List<float>();
|
||||||
var Color3_G = new List<float>();
|
var Color3_G = new List<float>();
|
||||||
var Color3_B = new List<float>();
|
var Color3_B = new List<float>();
|
||||||
@ -762,7 +869,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteFloats(Color3_B);
|
writer.WriteFloats(Color3_B);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Vector2:
|
case PropertyType.Vector2:
|
||||||
|
{
|
||||||
var Vector2_X = new List<float>();
|
var Vector2_X = new List<float>();
|
||||||
var Vector2_Y = new List<float>();
|
var Vector2_Y = new List<float>();
|
||||||
|
|
||||||
@ -777,7 +886,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteFloats(Vector2_Y);
|
writer.WriteFloats(Vector2_Y);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Vector3:
|
case PropertyType.Vector3:
|
||||||
|
{
|
||||||
var Vector3_X = new List<float>();
|
var Vector3_X = new List<float>();
|
||||||
var Vector3_Y = new List<float>();
|
var Vector3_Y = new List<float>();
|
||||||
var Vector3_Z = new List<float>();
|
var Vector3_Z = new List<float>();
|
||||||
@ -795,12 +906,18 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteFloats(Vector3_Z);
|
writer.WriteFloats(Vector3_Z);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.CFrame:
|
case PropertyType.CFrame:
|
||||||
case PropertyType.Quaternion:
|
case PropertyType.Quaternion:
|
||||||
|
case PropertyType.OptionalCFrame:
|
||||||
|
{
|
||||||
var CFrame_X = new List<float>();
|
var CFrame_X = new List<float>();
|
||||||
var CFrame_Y = new List<float>();
|
var CFrame_Y = new List<float>();
|
||||||
var CFrame_Z = new List<float>();
|
var CFrame_Z = new List<float>();
|
||||||
|
|
||||||
|
if (Type == PropertyType.OptionalCFrame)
|
||||||
|
writer.Write((byte)PropertyType.CFrame);
|
||||||
|
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
CFrame value = null;
|
CFrame value = null;
|
||||||
@ -810,6 +927,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
else
|
else
|
||||||
value = prop.CastValue<CFrame>();
|
value = prop.CastValue<CFrame>();
|
||||||
|
|
||||||
|
if (value == null)
|
||||||
|
value = new CFrame();
|
||||||
|
|
||||||
Vector3 pos = value.Position;
|
Vector3 pos = value.Position;
|
||||||
CFrame_X.Add(pos.X);
|
CFrame_X.Add(pos.X);
|
||||||
CFrame_Y.Add(pos.Y);
|
CFrame_Y.Add(pos.Y);
|
||||||
@ -845,27 +965,47 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteFloats(CFrame_Y);
|
writer.WriteFloats(CFrame_Y);
|
||||||
writer.WriteFloats(CFrame_Z);
|
writer.WriteFloats(CFrame_Z);
|
||||||
|
|
||||||
|
if (Type == PropertyType.OptionalCFrame)
|
||||||
|
{
|
||||||
|
writer.Write((byte)PropertyType.Bool);
|
||||||
|
|
||||||
|
props.ForEach(prop =>
|
||||||
|
{
|
||||||
|
if (prop.Value is null)
|
||||||
|
{
|
||||||
|
writer.Write(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.Write(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Enum:
|
case PropertyType.Enum:
|
||||||
var Enums = new List<uint>();
|
{
|
||||||
|
var enums = new List<uint>();
|
||||||
|
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
if (prop.Value is uint raw)
|
if (prop.Value is uint raw)
|
||||||
{
|
{
|
||||||
Enums.Add(raw);
|
enums.Add(raw);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int signed = (int)prop.Value;
|
int signed = (int)prop.Value;
|
||||||
uint value = (uint)signed;
|
uint value = (uint)signed;
|
||||||
|
|
||||||
Enums.Add(value);
|
enums.Add(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
writer.WriteInterleaved(Enums);
|
writer.WriteInterleaved(enums);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Ref:
|
case PropertyType.Ref:
|
||||||
|
{
|
||||||
var InstanceIds = new List<int>();
|
var InstanceIds = new List<int>();
|
||||||
|
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
@ -883,7 +1023,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
|
|
||||||
writer.WriteInstanceIds(InstanceIds);
|
writer.WriteInstanceIds(InstanceIds);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Vector3int16:
|
case PropertyType.Vector3int16:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
Vector3int16 value = prop.CastValue<Vector3int16>();
|
Vector3int16 value = prop.CastValue<Vector3int16>();
|
||||||
@ -893,7 +1035,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.NumberSequence:
|
case PropertyType.NumberSequence:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
NumberSequence value = prop.CastValue<NumberSequence>();
|
NumberSequence value = prop.CastValue<NumberSequence>();
|
||||||
@ -910,7 +1054,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.ColorSequence:
|
case PropertyType.ColorSequence:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
ColorSequence value = prop.CastValue<ColorSequence>();
|
ColorSequence value = prop.CastValue<ColorSequence>();
|
||||||
@ -932,7 +1078,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.NumberRange:
|
case PropertyType.NumberRange:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
NumberRange value = prop.CastValue<NumberRange>();
|
NumberRange value = prop.CastValue<NumberRange>();
|
||||||
@ -941,7 +1089,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Rect:
|
case PropertyType.Rect:
|
||||||
|
{
|
||||||
var Rect_X0 = new List<float>();
|
var Rect_X0 = new List<float>();
|
||||||
var Rect_Y0 = new List<float>();
|
var Rect_Y0 = new List<float>();
|
||||||
|
|
||||||
@ -968,7 +1118,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.WriteFloats(Rect_Y1);
|
writer.WriteFloats(Rect_Y1);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.PhysicalProperties:
|
case PropertyType.PhysicalProperties:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
bool custom = (prop.Value != null);
|
bool custom = (prop.Value != null);
|
||||||
@ -988,7 +1140,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Color3uint8:
|
case PropertyType.Color3uint8:
|
||||||
|
{
|
||||||
var Color3uint8_R = new List<byte>();
|
var Color3uint8_R = new List<byte>();
|
||||||
var Color3uint8_G = new List<byte>();
|
var Color3uint8_G = new List<byte>();
|
||||||
var Color3uint8_B = new List<byte>();
|
var Color3uint8_B = new List<byte>();
|
||||||
@ -1011,23 +1165,27 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
writer.Write(bBuffer);
|
writer.Write(bBuffer);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Int64:
|
case PropertyType.Int64:
|
||||||
var Int64s = new List<long>();
|
{
|
||||||
|
var longs = new List<long>();
|
||||||
|
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
long value = prop.CastValue<long>();
|
long value = prop.CastValue<long>();
|
||||||
Int64s.Add(value);
|
longs.Add(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
writer.WriteInterleaved(Int64s, value =>
|
writer.WriteInterleaved(longs, value =>
|
||||||
{
|
{
|
||||||
// Move the sign bit to the front.
|
// Move the sign bit to the front.
|
||||||
return (value << 1) ^ (value >> 63);
|
return (value << 1) ^ (value >> 63);
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.SharedString:
|
case PropertyType.SharedString:
|
||||||
|
{
|
||||||
var sharedKeys = new List<uint>();
|
var sharedKeys = new List<uint>();
|
||||||
SSTR sstr = file.SSTR;
|
SSTR sstr = file.SSTR;
|
||||||
|
|
||||||
@ -1051,7 +1209,7 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
|
|
||||||
if (!sstr.Lookup.ContainsKey(key))
|
if (!sstr.Lookup.ContainsKey(key))
|
||||||
{
|
{
|
||||||
uint id = (uint)(sstr.Lookup.Count);
|
uint id = (uint)sstr.Lookup.Count;
|
||||||
sstr.Strings.Add(id, shared);
|
sstr.Strings.Add(id, shared);
|
||||||
sstr.Lookup.Add(key, id);
|
sstr.Lookup.Add(key, id);
|
||||||
}
|
}
|
||||||
@ -1062,7 +1220,9 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
|
|
||||||
writer.WriteInterleaved(sharedKeys);
|
writer.WriteInterleaved(sharedKeys);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.ProtectedString:
|
case PropertyType.ProtectedString:
|
||||||
|
{
|
||||||
props.ForEach(prop =>
|
props.ForEach(prop =>
|
||||||
{
|
{
|
||||||
var protect = prop.CastValue<ProtectedString>();
|
var protect = prop.CastValue<ProtectedString>();
|
||||||
@ -1073,7 +1233,12 @@ namespace RobloxFiles.BinaryFormat.Chunks
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: break;
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RobloxFile.LogError($"Unhandled property type: {Type} in {this}!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Auto-generated list of creatable Roblox classes.
|
// Auto-generated list of creatable Roblox classes.
|
||||||
// Updated as of 0.474.0.420553
|
// Updated as of 0.476.0.421371
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@ -7,10 +7,6 @@ using RobloxFiles.DataTypes;
|
|||||||
using RobloxFiles.Enums;
|
using RobloxFiles.Enums;
|
||||||
using RobloxFiles.Utility;
|
using RobloxFiles.Utility;
|
||||||
|
|
||||||
#pragma warning disable CA1041 // Provide ObsoleteAttribute message
|
|
||||||
#pragma warning disable CA1051 // Do not declare visible instance fields
|
|
||||||
#pragma warning disable CA1707 // Identifiers should not contain underscores
|
|
||||||
#pragma warning disable CA1716 // Identifiers should not match keywords
|
|
||||||
#pragma warning disable IDE1006 // Naming Styles
|
#pragma warning disable IDE1006 // Naming Styles
|
||||||
|
|
||||||
namespace RobloxFiles
|
namespace RobloxFiles
|
||||||
@ -2095,6 +2091,14 @@ namespace RobloxFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MemoryStoreService : Instance
|
||||||
|
{
|
||||||
|
public MemoryStoreService()
|
||||||
|
{
|
||||||
|
IsService = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Message : Instance
|
public class Message : Instance
|
||||||
{
|
{
|
||||||
public string Text = "";
|
public string Text = "";
|
||||||
@ -2402,7 +2406,9 @@ namespace RobloxFiles
|
|||||||
public CFrame ModelMeshCFrame = new CFrame();
|
public CFrame ModelMeshCFrame = new CFrame();
|
||||||
public SharedString ModelMeshData = SharedString.FromBase64("yuZpQdnvvUBOTYh1jqZ2cA==");
|
public SharedString ModelMeshData = SharedString.FromBase64("yuZpQdnvvUBOTYh1jqZ2cA==");
|
||||||
public Vector3 ModelMeshSize = new Vector3();
|
public Vector3 ModelMeshSize = new Vector3();
|
||||||
|
public bool NeedsPivotMigration;
|
||||||
public BasePart PrimaryPart;
|
public BasePart PrimaryPart;
|
||||||
|
public CFrame WorldPivotData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Actor : Model
|
public class Actor : Model
|
||||||
@ -2421,6 +2427,7 @@ namespace RobloxFiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool AllowThirdPartySales;
|
public bool AllowThirdPartySales;
|
||||||
|
public ClientAnimatorThrottlingMode ClientAnimatorThrottling = ClientAnimatorThrottlingMode.Default;
|
||||||
public string CollisionGroups = "Default^0^1";
|
public string CollisionGroups = "Default^0^1";
|
||||||
public Camera CurrentCamera;
|
public Camera CurrentCamera;
|
||||||
public double DistributedGameTime;
|
public double DistributedGameTime;
|
||||||
@ -2532,10 +2539,11 @@ namespace RobloxFiles
|
|||||||
IsService = true;
|
IsService = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DEPRECATED_SerializedEmulatedPolicyInfo = "";
|
||||||
public string EmulatedCountryCode = "";
|
public string EmulatedCountryCode = "";
|
||||||
public string EmulatedGameLocale = "";
|
public string EmulatedGameLocale = "";
|
||||||
public bool PlayerEmulationEnabled;
|
public bool PlayerEmulationEnabled;
|
||||||
public string SerializedEmulatedPolicyInfo = "";
|
public byte[] SerializedEmulatedPolicyInfo = Array.Empty<byte>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Players : Instance
|
public class Players : Instance
|
||||||
@ -2678,6 +2686,14 @@ namespace RobloxFiles
|
|||||||
public int MaxPromptsVisible = 16;
|
public int MaxPromptsVisible = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class PublishService : Instance
|
||||||
|
{
|
||||||
|
public PublishService()
|
||||||
|
{
|
||||||
|
IsService = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class RbxAnalyticsService : Instance
|
public class RbxAnalyticsService : Instance
|
||||||
{
|
{
|
||||||
public RbxAnalyticsService()
|
public RbxAnalyticsService()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Auto-generated list of Roblox enums.
|
// Auto-generated list of Roblox enums.
|
||||||
// Updated as of 0.473.0.420291
|
// Updated as of 0.476.0.421371
|
||||||
|
|
||||||
namespace RobloxFiles.Enums
|
namespace RobloxFiles.Enums
|
||||||
{
|
{
|
||||||
@ -124,6 +124,13 @@ namespace RobloxFiles.Enums
|
|||||||
Orbital
|
Orbital
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ClientAnimatorThrottlingMode
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Disabled,
|
||||||
|
Enabled
|
||||||
|
}
|
||||||
|
|
||||||
public enum DevCameraOcclusionMode
|
public enum DevCameraOcclusionMode
|
||||||
{
|
{
|
||||||
Zoom,
|
Zoom,
|
||||||
|
Binary file not shown.
@ -377,6 +377,8 @@ return
|
|||||||
ModelMeshCFrame = "CFrame";
|
ModelMeshCFrame = "CFrame";
|
||||||
ModelMeshData = "SharedString";
|
ModelMeshData = "SharedString";
|
||||||
ModelMeshSize = "Vector3";
|
ModelMeshSize = "Vector3";
|
||||||
|
NeedsPivotMigration = "bool";
|
||||||
|
WorldPivotData = "OptionalCFrame";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,6 +217,7 @@ local formatLinks =
|
|||||||
["Instance"] = "Null";
|
["Instance"] = "Null";
|
||||||
|
|
||||||
["Color3uint8"] = "Color3";
|
["Color3uint8"] = "Color3";
|
||||||
|
["OptionalCFrame"] = "Null";
|
||||||
["ProtectedString"] = "String";
|
["ProtectedString"] = "String";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,10 +358,10 @@ local function generateClasses()
|
|||||||
writeLine("using RobloxFiles.Utility;")
|
writeLine("using RobloxFiles.Utility;")
|
||||||
writeLine()
|
writeLine()
|
||||||
|
|
||||||
writeLine("#pragma warning disable CA1041 // Provide ObsoleteAttribute message")
|
-- writeLine("#pragma warning disable CA1041 // Provide ObsoleteAttribute message")
|
||||||
writeLine("#pragma warning disable CA1051 // Do not declare visible instance fields")
|
-- writeLine("#pragma warning disable CA1051 // Do not declare visible instance fields")
|
||||||
writeLine("#pragma warning disable CA1707 // Identifiers should not contain underscores")
|
-- writeLine("#pragma warning disable CA1707 // Identifiers should not contain underscores")
|
||||||
writeLine("#pragma warning disable CA1716 // Identifiers should not match keywords")
|
-- writeLine("#pragma warning disable CA1716 // Identifiers should not match keywords")
|
||||||
writeLine("#pragma warning disable IDE1006 // Naming Styles")
|
writeLine("#pragma warning disable IDE1006 // Naming Styles")
|
||||||
writeLine()
|
writeLine()
|
||||||
|
|
||||||
@ -640,6 +641,10 @@ local function generateClasses()
|
|||||||
writeLine("[Obsolete]")
|
writeLine("[Obsolete]")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if valueType == "OptionalCFrame" then
|
||||||
|
valueType = "CFrame"
|
||||||
|
end
|
||||||
|
|
||||||
writeLine("public %s %s%s;", valueType, name, default)
|
writeLine("public %s %s%s;", valueType, name, default)
|
||||||
|
|
||||||
if propTags.Deprecated and j ~= #propNames then
|
if propTags.Deprecated and j ~= #propNames then
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
<Compile Include="Generated\Classes.cs" />
|
<Compile Include="Generated\Classes.cs" />
|
||||||
<Compile Include="Generated\Enums.cs" />
|
<Compile Include="Generated\Enums.cs" />
|
||||||
<Compile Include="Interfaces\IAttributeToken.cs" />
|
<Compile Include="Interfaces\IAttributeToken.cs" />
|
||||||
|
<Compile Include="Tokens\OptionalCFrame.cs" />
|
||||||
<Compile Include="Tree\Attributes.cs" />
|
<Compile Include="Tree\Attributes.cs" />
|
||||||
<Compile Include="Tree\Property.cs" />
|
<Compile Include="Tree\Property.cs" />
|
||||||
<Compile Include="Tree\Instance.cs" />
|
<Compile Include="Tree\Instance.cs" />
|
||||||
|
Binary file not shown.
@ -30,6 +30,23 @@ namespace RobloxFiles.Tokens
|
|||||||
return new CFrame(components);
|
return new CFrame(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteCFrame(Property prop, XmlDocument doc, XmlNode node)
|
||||||
|
{
|
||||||
|
CFrame cf = prop.CastValue<CFrame>();
|
||||||
|
float[] components = cf.GetComponents();
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
string coordName = Coords[i];
|
||||||
|
float coordValue = components[i];
|
||||||
|
|
||||||
|
XmlElement coord = doc.CreateElement(coordName);
|
||||||
|
coord.InnerText = coordValue.ToInvariantString();
|
||||||
|
|
||||||
|
node.AppendChild(coord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool ReadProperty(Property prop, XmlNode token)
|
public bool ReadProperty(Property prop, XmlNode token)
|
||||||
{
|
{
|
||||||
CFrame result = ReadCFrame(token);
|
CFrame result = ReadCFrame(token);
|
||||||
@ -46,19 +63,7 @@ namespace RobloxFiles.Tokens
|
|||||||
|
|
||||||
public void WriteProperty(Property prop, XmlDocument doc, XmlNode node)
|
public void WriteProperty(Property prop, XmlDocument doc, XmlNode node)
|
||||||
{
|
{
|
||||||
CFrame cf = prop.CastValue<CFrame>();
|
WriteCFrame(prop, doc, node);
|
||||||
float[] components = cf.GetComponents();
|
|
||||||
|
|
||||||
for (int i = 0; i < 12; i++)
|
|
||||||
{
|
|
||||||
string coordName = Coords[i];
|
|
||||||
float coordValue = components[i];
|
|
||||||
|
|
||||||
XmlElement coord = doc.CreateElement(coordName);
|
|
||||||
coord.InnerText = coordValue.ToInvariantString();
|
|
||||||
|
|
||||||
node.AppendChild(coord);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
Tokens/OptionalCFrame.cs
Normal file
33
Tokens/OptionalCFrame.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System.Xml;
|
||||||
|
using RobloxFiles.DataTypes;
|
||||||
|
|
||||||
|
namespace RobloxFiles.Tokens
|
||||||
|
{
|
||||||
|
public class OptionalCFrameToken : IXmlPropertyToken
|
||||||
|
{
|
||||||
|
public string XmlPropertyToken => "OptionalCoordinateFrame";
|
||||||
|
|
||||||
|
public bool ReadProperty(Property prop, XmlNode token)
|
||||||
|
{
|
||||||
|
XmlNode first = token.FirstChild;
|
||||||
|
prop.Type = PropertyType.OptionalCFrame;
|
||||||
|
|
||||||
|
if (first?.Name == "CFrame")
|
||||||
|
prop.Value = CFrameToken.ReadCFrame(first);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteProperty(Property prop, XmlDocument doc, XmlNode node)
|
||||||
|
{
|
||||||
|
CFrame value = prop.CastValue<CFrame>();
|
||||||
|
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
XmlElement cfNode = doc.CreateElement("CFrame");
|
||||||
|
CFrameToken.WriteCFrame(prop, doc, cfNode);
|
||||||
|
node.AppendChild(cfNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,8 +13,8 @@ namespace RobloxFiles.Tokens
|
|||||||
public bool ReadProperty(Property prop, XmlNode token)
|
public bool ReadProperty(Property prop, XmlNode token)
|
||||||
{
|
{
|
||||||
ProtectedString contents = token.InnerText;
|
ProtectedString contents = token.InnerText;
|
||||||
prop.Type = PropertyType.ProtectedString;
|
prop.Type = PropertyType.String;
|
||||||
prop.Value = contents;
|
prop.Value = contents.ToString();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,6 @@ namespace RobloxFiles
|
|||||||
{
|
{
|
||||||
var attributeSupport = new Dictionary<AttributeType, Tokenizer>();
|
var attributeSupport = new Dictionary<AttributeType, Tokenizer>();
|
||||||
var supportedTypes = new Dictionary<Type, AttributeType>();
|
var supportedTypes = new Dictionary<Type, AttributeType>();
|
||||||
|
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
var handlerTypes =
|
var handlerTypes =
|
||||||
@ -247,7 +246,7 @@ namespace RobloxFiles
|
|||||||
|
|
||||||
internal Attributes(MemoryStream stream)
|
internal Attributes(MemoryStream stream)
|
||||||
{
|
{
|
||||||
using (BinaryReader reader = new BinaryReader(stream))
|
using (var reader = new BinaryReader(stream))
|
||||||
Initialize(reader);
|
Initialize(reader);
|
||||||
|
|
||||||
stream.Dispose();
|
stream.Dispose();
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using RobloxFiles.BinaryFormat;
|
|
||||||
using RobloxFiles.BinaryFormat.Chunks;
|
using RobloxFiles.BinaryFormat.Chunks;
|
||||||
|
|
||||||
using RobloxFiles.DataTypes;
|
using RobloxFiles.DataTypes;
|
||||||
using RobloxFiles.Utility;
|
using RobloxFiles.Utility;
|
||||||
|
|
||||||
@ -42,14 +39,14 @@ namespace RobloxFiles
|
|||||||
Color3uint8,
|
Color3uint8,
|
||||||
Int64,
|
Int64,
|
||||||
SharedString,
|
SharedString,
|
||||||
ProtectedString
|
ProtectedString,
|
||||||
|
OptionalCFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Property
|
public class Property
|
||||||
{
|
{
|
||||||
public string Name { get; internal set; }
|
public string Name { get; internal set; }
|
||||||
public Instance Instance { get; internal set; }
|
public Instance Instance { get; internal set; }
|
||||||
|
|
||||||
public PropertyType Type { get; internal set; }
|
public PropertyType Type { get; internal set; }
|
||||||
|
|
||||||
public string XmlToken { get; internal set; }
|
public string XmlToken { get; internal set; }
|
||||||
@ -59,7 +56,9 @@ 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;
|
||||||
|
|
||||||
// !! FIXME: Map typeof(ProtectedString) to PropertyType.ProtectedString when binary files are allowed to read it.
|
// TODO: Map typeof(ProtectedString) to PropertyType.ProtectedString
|
||||||
|
// if binary files are ever publically 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>()
|
||||||
{
|
{
|
||||||
{ typeof(Axes), PropertyType.Axes },
|
{ typeof(Axes), PropertyType.Axes },
|
||||||
@ -103,8 +102,7 @@ namespace RobloxFiles
|
|||||||
RawBuffer = RawValue as byte[];
|
RawBuffer = RawValue as byte[];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (RawValue is SharedString sharedString)
|
||||||
if (RawValue is SharedString sharedString)
|
|
||||||
{
|
{
|
||||||
if (sharedString != null)
|
if (sharedString != null)
|
||||||
{
|
{
|
||||||
@ -112,8 +110,7 @@ namespace RobloxFiles
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (RawValue is ProtectedString protectedString)
|
||||||
if (RawValue is ProtectedString protectedString)
|
|
||||||
{
|
{
|
||||||
if (protectedString != null)
|
if (protectedString != null)
|
||||||
{
|
{
|
||||||
@ -128,6 +125,7 @@ namespace RobloxFiles
|
|||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case PropertyType.Int:
|
case PropertyType.Int:
|
||||||
|
{
|
||||||
if (Value is long)
|
if (Value is long)
|
||||||
{
|
{
|
||||||
Type = PropertyType.Int64;
|
Type = PropertyType.Int64;
|
||||||
@ -136,19 +134,27 @@ namespace RobloxFiles
|
|||||||
|
|
||||||
RawBuffer = BitConverter.GetBytes((int)Value);
|
RawBuffer = BitConverter.GetBytes((int)Value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Bool:
|
case PropertyType.Bool:
|
||||||
|
{
|
||||||
RawBuffer = BitConverter.GetBytes((bool)Value);
|
RawBuffer = BitConverter.GetBytes((bool)Value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Int64:
|
case PropertyType.Int64:
|
||||||
|
{
|
||||||
RawBuffer = BitConverter.GetBytes((long)Value);
|
RawBuffer = BitConverter.GetBytes((long)Value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Float:
|
case PropertyType.Float:
|
||||||
|
{
|
||||||
RawBuffer = BitConverter.GetBytes((float)Value);
|
RawBuffer = BitConverter.GetBytes((float)Value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyType.Double:
|
case PropertyType.Double:
|
||||||
|
{
|
||||||
RawBuffer = BitConverter.GetBytes((double)Value);
|
RawBuffer = BitConverter.GetBytes((double)Value);
|
||||||
break;
|
break;
|
||||||
default: break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,8 +169,7 @@ namespace RobloxFiles
|
|||||||
|
|
||||||
if (typeName == Name)
|
if (typeName == Name)
|
||||||
{
|
{
|
||||||
FieldInfo directField = instType
|
FieldInfo directField = instType.GetFields()
|
||||||
.GetFields()
|
|
||||||
.Where(field => field.Name.StartsWith(Name, StringComparison.InvariantCulture))
|
.Where(field => field.Name.StartsWith(Name, StringComparison.InvariantCulture))
|
||||||
.Where(field => field.DeclaringType == instType)
|
.Where(field => field.DeclaringType == instType)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
@ -276,6 +281,7 @@ namespace RobloxFiles
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
// Improvise what the buffer should be if this is a primitive.
|
// Improvise what the buffer should be if this is a primitive.
|
||||||
|
|
||||||
if (RawBuffer == null && Value != null)
|
if (RawBuffer == null && Value != null)
|
||||||
ImproviseRawBuffer();
|
ImproviseRawBuffer();
|
||||||
|
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -65,6 +65,10 @@ namespace RobloxFiles
|
|||||||
if (child.Name == "Item")
|
if (child.Name == "Item")
|
||||||
{
|
{
|
||||||
Instance item = XmlRobloxFileReader.ReadInstance(child, this);
|
Instance item = XmlRobloxFileReader.ReadInstance(child, this);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
item.Parent = this;
|
item.Parent = this;
|
||||||
}
|
}
|
||||||
else if (child.Name == "SharedStrings")
|
else if (child.Name == "SharedStrings")
|
||||||
|
Loading…
Reference in New Issue
Block a user