diff --git a/DataTypes/BrickColor.cs b/DataTypes/BrickColor.cs index ec55098..c005855 100644 --- a/DataTypes/BrickColor.cs +++ b/DataTypes/BrickColor.cs @@ -47,7 +47,20 @@ namespace RobloxFiles.DataTypes ByPalette = BrickColors.PaletteMap.Select(number => ByNumber[number]).ToList(); } - + public override int GetHashCode() + { + return Number; + } + + public override bool Equals(object obj) + { + if (!(obj is BrickColor)) + return false; + + var bc = obj as BrickColor; + return Number == bc.Number; + } + public static BrickColor FromName(string name) { BrickColor result = null; diff --git a/DataTypes/CFrame.cs b/DataTypes/CFrame.cs index bc832c9..5d60d73 100644 --- a/DataTypes/CFrame.cs +++ b/DataTypes/CFrame.cs @@ -38,6 +38,40 @@ namespace RobloxFiles.DataTypes public Vector3 ColumnY => new Vector3(m21, m22, m23); public Vector3 ColumnZ => new Vector3(m31, m32, m33); + public override int GetHashCode() + { + var components = GetComponents(); + int hashCode = 0; + + foreach (float component in components) + hashCode ^= component.GetHashCode(); + + return hashCode; + } + + public override bool Equals(object obj) + { + if (!(obj is CFrame)) + return false; + + var other = obj as CFrame; + var compA = GetComponents(); + var compB = other.GetComponents(); + + for (int i = 0; i < 12; i++) + { + float a = compA[i], + b = compB[i]; + + if (a.Equals(b)) + continue; + + return false; + } + + return true; + } + public CFrame() { m14 = 0; diff --git a/DataTypes/Color3.cs b/DataTypes/Color3.cs index 254bca2..c5761ee 100644 --- a/DataTypes/Color3.cs +++ b/DataTypes/Color3.cs @@ -20,7 +20,26 @@ namespace RobloxFiles.DataTypes g = G.GetHashCode(), b = B.GetHashCode(); - return (r ^ g ^ b); + return r ^ g ^ b; + } + + public override bool Equals(object obj) + { + if (!(obj is Color3)) + return false; + + var other = obj as Color3; + + if (!R.Equals(other.R)) + return false; + + if (!G.Equals(other.G)) + return false; + + if (!B.Equals(other.B)) + return false; + + return true; } internal Color3(Attribute attr) diff --git a/DataTypes/Color3uint8.cs b/DataTypes/Color3uint8.cs index 1031f8e..b79944e 100644 --- a/DataTypes/Color3uint8.cs +++ b/DataTypes/Color3uint8.cs @@ -18,7 +18,18 @@ public override int GetHashCode() { - return (R << 24) | (G << 8) | B; + return (R << 16) | (G << 8) | B; + } + + public override bool Equals(object obj) + { + if (!(obj is Color3uint8)) + return false; + + int rgb0 = GetHashCode(), + rgb1 = obj.GetHashCode(); + + return rgb0.Equals(rgb1); } public static implicit operator Color3(Color3uint8 color) diff --git a/DataTypes/ColorSequence.cs b/DataTypes/ColorSequence.cs index 68fa610..1f3ea36 100644 --- a/DataTypes/ColorSequence.cs +++ b/DataTypes/ColorSequence.cs @@ -28,6 +28,41 @@ namespace RobloxFiles.DataTypes }; } + public override int GetHashCode() + { + int hash = 0; + + foreach (var keypoint in Keypoints) + hash ^= keypoint.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is ColorSequence)) + return false; + + var colorSeq = obj as ColorSequence; + var otherKeys = colorSeq.Keypoints; + + if (Keypoints.Length != otherKeys.Length) + return false; + + for (int i = 0; i < Keypoints.Length; i++) + { + var keyA = Keypoints[i]; + var keyB = otherKeys[i]; + + if (keyA.Equals(keyB)) + continue; + + return false; + } + + return true; + } + public ColorSequence(ColorSequenceKeypoint[] keypoints) { int numKeys = keypoints.Length; diff --git a/DataTypes/ColorSequenceKeypoint.cs b/DataTypes/ColorSequenceKeypoint.cs index cff98f4..b3498e1 100644 --- a/DataTypes/ColorSequenceKeypoint.cs +++ b/DataTypes/ColorSequenceKeypoint.cs @@ -25,5 +25,33 @@ Time = attr.readFloat(); Value = new Color3(attr); } + + public override int GetHashCode() + { + int hash = Time.GetHashCode() + ^ Value.GetHashCode() + ^ Envelope.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is ColorSequenceKeypoint)) + return false; + + var otherKey = obj as ColorSequenceKeypoint; + + if (!Time.Equals(otherKey.Time)) + return false; + + if (!Value.Equals(otherKey.Value)) + return false; + + if (!Envelope.Equals(otherKey.Envelope)) + return false; + + return true; + } } } diff --git a/DataTypes/Content.cs b/DataTypes/Content.cs index 5a1c46b..bab08d4 100644 --- a/DataTypes/Content.cs +++ b/DataTypes/Content.cs @@ -23,5 +23,19 @@ { return new Content(url); } + + public override int GetHashCode() + { + return Url.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is Content)) + return false; + + var content = obj as Content; + return Url.Equals(content.Url); + } } } diff --git a/DataTypes/NumberRange.cs b/DataTypes/NumberRange.cs index ee9f7ac..420f120 100644 --- a/DataTypes/NumberRange.cs +++ b/DataTypes/NumberRange.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.Contracts; namespace RobloxFiles.DataTypes { @@ -15,31 +16,38 @@ namespace RobloxFiles.DataTypes Max = num; } - private static void checkRange(float min, float max) - { - if (max - min >= 0) - return; - - throw new Exception("NumberRange: invalid range"); - } - public NumberRange(float min = 0, float max = 0) { - checkRange(min, max); - + Contract.Requires(max - min >= 0, "Max must be greater than min."); + Contract.EndContractBlock(); + Min = min; Max = max; } - internal NumberRange(Attribute attr) + internal NumberRange(Attribute attr) : this(attr.readFloat(), attr.readFloat()) { - float min = attr.readFloat(); - float max = attr.readFloat(); + } - checkRange(min, max); + public override int GetHashCode() + { + return Min.GetHashCode() ^ Max.GetHashCode(); + } - Min = min; - Max = max; + public override bool Equals(object obj) + { + if (!(obj is NumberRange)) + return false; + + var other = obj as NumberRange; + + if (!Min.Equals(other.Min)) + return false; + + if (!Max.Equals(other.Max)) + return false; + + return true; } } } diff --git a/DataTypes/NumberSequence.cs b/DataTypes/NumberSequence.cs index bc9c0e8..08bca67 100644 --- a/DataTypes/NumberSequence.cs +++ b/DataTypes/NumberSequence.cs @@ -62,5 +62,40 @@ namespace RobloxFiles.DataTypes Keypoints = keypoints; } + + public override int GetHashCode() + { + int hash = 0; + + foreach (var keypoint in Keypoints) + hash ^= keypoint.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is NumberSequence)) + return false; + + var colorSeq = obj as NumberSequence; + var otherKeys = colorSeq.Keypoints; + + if (Keypoints.Length != otherKeys.Length) + return false; + + for (int i = 0; i < Keypoints.Length; i++) + { + var keyA = Keypoints[i]; + var keyB = otherKeys[i]; + + if (keyA.Equals(keyB)) + continue; + + return false; + } + + return true; + } } } diff --git a/DataTypes/NumberSequenceKeypoint.cs b/DataTypes/NumberSequenceKeypoint.cs index d2e7368..97751c9 100644 --- a/DataTypes/NumberSequenceKeypoint.cs +++ b/DataTypes/NumberSequenceKeypoint.cs @@ -24,5 +24,33 @@ Time = attr.readFloat(); Value = attr.readFloat(); } + + public override int GetHashCode() + { + int hash = Time.GetHashCode() + ^ Value.GetHashCode() + ^ Envelope.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is NumberSequenceKeypoint)) + return false; + + var otherKey = obj as NumberSequenceKeypoint; + + if (!Time.Equals(otherKey.Time)) + return false; + + if (!Value.Equals(otherKey.Value)) + return false; + + if (!Envelope.Equals(otherKey.Envelope)) + return false; + + return true; + } } } diff --git a/DataTypes/PhysicalProperties.cs b/DataTypes/PhysicalProperties.cs index d9d843f..871c6d6 100644 --- a/DataTypes/PhysicalProperties.cs +++ b/DataTypes/PhysicalProperties.cs @@ -46,5 +46,41 @@ namespace RobloxFiles.DataTypes FrictionWeight = attr.readFloat(); ElasticityWeight = attr.readFloat(); } + + public override int GetHashCode() + { + int hash = Density.GetHashCode() + ^ Friction.GetHashCode() + ^ Elasticity.GetHashCode() + ^ FrictionWeight.GetHashCode() + ^ ElasticityWeight.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is PhysicalProperties)) + return false; + + var other = obj as PhysicalProperties; + + if (!Density.Equals(other.Density)) + return false; + + if (!Friction.Equals(other.Friction)) + return false; + + if (!Elasticity.Equals(other.Elasticity)) + return false; + + if (!FrictionWeight.Equals(other.FrictionWeight)) + return false; + + if (!ElasticityWeight.Equals(other.ElasticityWeight)) + return false; + + return true; + } } } diff --git a/DataTypes/ProtectedString.cs b/DataTypes/ProtectedString.cs index 97e763b..2b11f4e 100644 --- a/DataTypes/ProtectedString.cs +++ b/DataTypes/ProtectedString.cs @@ -1,4 +1,5 @@ -using System.Text; +using System; +using System.Text; namespace RobloxFiles.DataTypes { @@ -50,5 +51,29 @@ namespace RobloxFiles.DataTypes { return new ProtectedString(value); } + + public override bool Equals(object obj) + { + if (!(obj is ProtectedString)) + return false; + + var other = obj as ProtectedString; + var otherBuffer = other.RawBuffer; + + if (RawBuffer.Length != otherBuffer.Length) + return false; + + for (int i = 0; i < RawBuffer.Length; i++) + if (RawBuffer[i] != otherBuffer[i]) + return false; + + return true; + } + + public override int GetHashCode() + { + var str = Convert.ToBase64String(RawBuffer); + return str.GetHashCode(); + } } } diff --git a/DataTypes/Quaternion.cs b/DataTypes/Quaternion.cs index 8f37d5a..5dc9336 100644 --- a/DataTypes/Quaternion.cs +++ b/DataTypes/Quaternion.cs @@ -40,7 +40,6 @@ namespace RobloxFiles.DataTypes public Quaternion(CFrame cf) { - CFrame matrix = (cf - cf.Position); float[] ac = cf.GetComponents(); float m11 = ac[3], m12 = ac[4], m13 = ac[5], @@ -204,5 +203,37 @@ namespace RobloxFiles.DataTypes return new Quaternion(s1 * v2 + s2 * v1 + v1.Cross(v2), s1 * s2 - v1.Dot(v2)); } + + public override int GetHashCode() + { + int hash = X.GetHashCode() + ^ Y.GetHashCode() + ^ Z.GetHashCode() + ^ W.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Quaternion)) + return false; + + var other = obj as Quaternion; + + if (!X.Equals(other.X)) + return false; + + if (!Y.Equals(other.Y)) + return false; + + if (!Z.Equals(other.Z)) + return false; + + if (!W.Equals(other.W)) + return false; + + return true; + } } } diff --git a/DataTypes/Ray.cs b/DataTypes/Ray.cs index 47d61f8..fb82d8e 100644 --- a/DataTypes/Ray.cs +++ b/DataTypes/Ray.cs @@ -50,5 +50,29 @@ Vector3 closestPoint = ClosestPoint(point); return (point - closestPoint).Magnitude; } + + public override bool Equals(object obj) + { + if (!(obj is Ray)) + return false; + + var other = obj as Ray; + + if (!Origin.Equals(other.Origin)) + return false; + + if (!Direction.Equals(other.Direction)) + return false; + + return true; + } + + public override int GetHashCode() + { + int hash = Origin.GetHashCode() + ^ Direction.GetHashCode(); + + return hash; + } } } diff --git a/DataTypes/Rect.cs b/DataTypes/Rect.cs index 4cec9b3..3793ed1 100644 --- a/DataTypes/Rect.cs +++ b/DataTypes/Rect.cs @@ -27,5 +27,29 @@ Min = new Vector2(attr); Max = new Vector2(attr); } + + public override int GetHashCode() + { + int hash = Min.GetHashCode() + ^ Max.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Rect)) + return false; + + var other = obj as Rect; + + if (!Min.Equals(other.Min)) + return false; + + if (!Max.Equals(other.Max)) + return false; + + return true; + } } } diff --git a/DataTypes/Region3.cs b/DataTypes/Region3.cs index 7c2a00c..9297416 100644 --- a/DataTypes/Region3.cs +++ b/DataTypes/Region3.cs @@ -41,5 +41,29 @@ namespace RobloxFiles.DataTypes return new Region3(emin, emax); } + + public override int GetHashCode() + { + int hash = Min.GetHashCode() + ^ Max.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Region3)) + return false; + + var other = obj as Region3; + + if (!Min.Equals(other.Min)) + return false; + + if (!Max.Equals(other.Max)) + return false; + + return true; + } } } diff --git a/DataTypes/Region3int16.cs b/DataTypes/Region3int16.cs index 7b47d4c..33a5d8e 100644 --- a/DataTypes/Region3int16.cs +++ b/DataTypes/Region3int16.cs @@ -16,5 +16,29 @@ Min = new Vector3int16(attr); Max = new Vector3int16(attr); } + + public override int GetHashCode() + { + int hash = Min.GetHashCode() + ^ Max.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Region3int16)) + return false; + + var other = obj as Region3int16; + + if (!Min.Equals(other.Min)) + return false; + + if (!Max.Equals(other.Max)) + return false; + + return true; + } } } diff --git a/DataTypes/SharedString.cs b/DataTypes/SharedString.cs index 760ae8b..bda010d 100644 --- a/DataTypes/SharedString.cs +++ b/DataTypes/SharedString.cs @@ -23,6 +23,20 @@ namespace RobloxFiles.DataTypes public byte[] SharedValue => Find(ComputedKey ?? Key); public override string ToString() => $"Key: {ComputedKey ?? Key}"; + public override int GetHashCode() + { + return Key.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is SharedString)) + return false; + + var other = (obj as SharedString); + return Key.Equals(other.Key); + } + internal SharedString(string key) { Key = key; diff --git a/DataTypes/UDim.cs b/DataTypes/UDim.cs index 0087454..addfce9 100644 --- a/DataTypes/UDim.cs +++ b/DataTypes/UDim.cs @@ -28,5 +28,29 @@ { return new UDim(a.Scale - b.Scale, a.Offset - b.Offset); } + + public override int GetHashCode() + { + int hash = Scale.GetHashCode() + ^ Offset.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is UDim)) + return false; + + var other = obj as UDim; + + if (!Scale.Equals(other.Scale)) + return false; + + if (!Offset.Equals(other.Offset)) + return false; + + return true; + } } } \ No newline at end of file diff --git a/DataTypes/UDim2.cs b/DataTypes/UDim2.cs index 21b913d..5292488 100644 --- a/DataTypes/UDim2.cs +++ b/DataTypes/UDim2.cs @@ -36,5 +36,29 @@ return new UDim2(scaleX, offsetX, scaleY, offsetY); } + + public override int GetHashCode() + { + int hash = X.GetHashCode() + ^ Y.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is UDim2)) + return false; + + var other = obj as UDim2; + + if (!X.Equals(other.X)) + return false; + + if (!Y.Equals(other.Y)) + return false; + + return true; + } } } diff --git a/DataTypes/Vector2.cs b/DataTypes/Vector2.cs index 6e28a2f..60ec2eb 100644 --- a/DataTypes/Vector2.cs +++ b/DataTypes/Vector2.cs @@ -103,5 +103,29 @@ namespace RobloxFiles.DataTypes { return this + (other - this) * t; } + + public override int GetHashCode() + { + int hash = X.GetHashCode() + ^ Y.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Vector2)) + return false; + + var other = obj as Vector2; + + if (!X.Equals(other.X)) + return false; + + if (!Y.Equals(other.Y)) + return false; + + return true; + } } } \ No newline at end of file diff --git a/DataTypes/Vector2int16.cs b/DataTypes/Vector2int16.cs index 6e1535e..365d5df 100644 --- a/DataTypes/Vector2int16.cs +++ b/DataTypes/Vector2int16.cs @@ -65,5 +65,29 @@ namespace RobloxFiles.DataTypes public static Vector2int16 operator /(Vector2int16 a, Vector2int16 b) => div(a, b); public static Vector2int16 operator /(Vector2int16 v, short n) => upcastShortOp(v, n, div); public static Vector2int16 operator /(short n, Vector2int16 v) => upcastShortOp(n, v, div); + + public override int GetHashCode() + { + int hash = X.GetHashCode() + ^ Y.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Vector2int16)) + return false; + + var other = obj as Vector2int16; + + if (!X.Equals(other.X)) + return false; + + if (!Y.Equals(other.Y)) + return false; + + return true; + } } } diff --git a/DataTypes/Vector3.cs b/DataTypes/Vector3.cs index 251db23..41fa15e 100644 --- a/DataTypes/Vector3.cs +++ b/DataTypes/Vector3.cs @@ -66,36 +66,6 @@ namespace RobloxFiles.DataTypes return new Vector3(coords); } - public override bool Equals(object obj) - { - if (obj is Vector3) - { - Vector3 other = obj as Vector3; - - if (!X.FuzzyEquals(other.X)) - return false; - - if (!Y.FuzzyEquals(other.Y)) - return false; - - if (!Z.FuzzyEquals(other.Z)) - return false; - - return true; - } - - return base.Equals(obj); - } - - public override int GetHashCode() - { - int x = X.GetHashCode(), - y = Y.GetHashCode(), - z = Z.GetHashCode(); - - return x ^ y ^ z; - } - private delegate Vector3 Operator(Vector3 a, Vector3 b); private static Vector3 upcastFloatOp(Vector3 vec, float num, Operator upcast) @@ -189,5 +159,33 @@ namespace RobloxFiles.DataTypes return result; } + + public override int GetHashCode() + { + int hash = X.GetHashCode() + ^ Y.GetHashCode() + ^ Z.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Vector3)) + return false; + + var other = obj as Vector3; + + if (!X.Equals(other.X)) + return false; + + if (!Y.Equals(other.Y)) + return false; + + if (!Z.Equals(other.Z)) + return false; + + return true; + } } } diff --git a/DataTypes/Vector3int16.cs b/DataTypes/Vector3int16.cs index 82da093..570bf19 100644 --- a/DataTypes/Vector3int16.cs +++ b/DataTypes/Vector3int16.cs @@ -72,5 +72,33 @@ namespace RobloxFiles.DataTypes public static Vector3int16 operator /(Vector3int16 a, Vector3int16 b) => div(a, b); public static Vector3int16 operator /(Vector3int16 v, short n) => upcastShortOp(v, n, div); public static Vector3int16 operator /(short n, Vector3int16 v) => upcastShortOp(n, v, div); + + public override int GetHashCode() + { + int hash = X.GetHashCode() + ^ Y.GetHashCode() + ^ Z.GetHashCode(); + + return hash; + } + + public override bool Equals(object obj) + { + if (!(obj is Vector3int16)) + return false; + + var other = obj as Vector3int16; + + if (!X.Equals(other.X)) + return false; + + if (!Y.Equals(other.Y)) + return false; + + if (!Z.Equals(other.Z)) + return false; + + return true; + } } } diff --git a/Generated/Classes.cs b/Generated/Classes.cs index c8c1229..ce731da 100644 --- a/Generated/Classes.cs +++ b/Generated/Classes.cs @@ -1,5 +1,5 @@ // Auto-generated list of creatable Roblox classes. -// Updated as of 0.443.0.409841 +// Updated as of 0.447.1.411123 using System; @@ -108,6 +108,14 @@ namespace RobloxFiles { } + public class AvatarEditorService : Instance + { + public AvatarEditorService() + { + IsService = true; + } + } + public class Backpack : Instance { } @@ -1690,7 +1698,6 @@ namespace RobloxFiles public CFrame C0 = new CFrame(); public CFrame C1 = new CFrame(); public bool Enabled = true; - public bool IsAutoJoint = true; public BasePart Part0; public BasePart Part1; } @@ -1991,6 +1998,14 @@ namespace RobloxFiles { } + public class NetworkClient : NetworkPeer + { + public NetworkClient() + { + IsService = true; + } + } + public class NoCollisionConstraint : Instance { public bool Enabled = true; @@ -2163,8 +2178,6 @@ namespace RobloxFiles public class Terrain : BasePart { - public string ClusterGrid = ""; - public string ClusterGridV2 = ""; public byte[] ClusterGridV3 = Array.Empty(); public bool Decoration; public byte[] MaterialColors = Convert.FromBase64String("AAAAAAAAan8/P39rf2Y/ilY+j35fi21PZmxvZbDqw8faiVpHOi4kHh4lZlw76JxKc3trhHtagcLgc4RKxr21zq2UlJSM"); @@ -2179,7 +2192,6 @@ namespace RobloxFiles public abstract class TriangleMeshPart : BasePart { - public CollisionFidelity CollisionFidelity = CollisionFidelity.Default; public Vector3 InitialSize = new Vector3(1, 1, 1); public byte[] LODData = Array.Empty(); public SharedString PhysicalConfigData = SharedString.FromBase64("1B2M2Y8AsgTpgAmY7PhCfg=="); @@ -2280,7 +2292,6 @@ namespace RobloxFiles public int StreamingMinRadius = 64; public StreamingPauseMode StreamingPauseMode = StreamingPauseMode.Default; public int StreamingTargetRadius = 1024; - public bool TemporaryLegacyPhysicsSolverOverrideStreaming; public bool TerrainWeldsFixed = true; } @@ -3209,6 +3220,14 @@ namespace RobloxFiles public float Scale = 1; } + public class UnvalidatedAssetService : Instance + { + public UnvalidatedAssetService() + { + IsService = true; + } + } + public class UserInputService : Instance { public UserInputService() diff --git a/Generated/Enums.cs b/Generated/Enums.cs index d330a73..b64a36b 100644 --- a/Generated/Enums.cs +++ b/Generated/Enums.cs @@ -1,5 +1,5 @@ // Auto-generated list of Roblox enums. -// Updated as of 0.443.0.409841 +// Updated as of 0.447.1.411123 namespace RobloxFiles.Enums { @@ -104,14 +104,6 @@ namespace RobloxFiles.Enums Orbital } - public enum CollisionFidelity - { - Default, - Hull, - Box, - PreciseConvexDecomposition - } - public enum DevCameraOcclusionMode { Zoom, diff --git a/Plugins/GenerateApiDump.rbxm b/Plugins/GenerateApiDump.rbxm index 039f959..53e67bd 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 ad819da..527dc81 100644 --- a/Plugins/GenerateApiDump/PropertyPatches.lua +++ b/Plugins/GenerateApiDump/PropertyPatches.lua @@ -278,12 +278,6 @@ return } }; - JointInstance = - { - Add = { IsAutoJoint = "bool" }; - Defaults = { IsAutoJoint = true }; - }; - Lighting = { Add = @@ -349,10 +343,12 @@ return Model = { - Add = + Add = { ModelInPrimary = "CFrame"; - ModelMeshData = "BinaryString"; + ModelMeshCFrame = "CFrame"; + ModelMeshData = "SharedString"; + ModelMeshSize = "Vector3"; }; }; @@ -538,18 +534,13 @@ return { Add = { - ClusterGrid = "string"; - ClusterGridV2 = "string"; ClusterGridV3 = "BinaryString"; - - SmoothGrid = "BinaryString"; PhysicsGrid = "BinaryString"; + SmoothGrid = "BinaryString"; }; Defaults = { - Decoration = false; - SmoothGrid = "AQU="; PhysicsGrid = "AgMAAAAAAAAAAAAAAAA="; MaterialColors = "AAAAAAAAan8/P39rf2Y/ilY+j35fi21PZmxvZbDqw8faiVpHOi4kHh4lZlw76JxKc3trhHtagcLgc4RKxr21zq2UlJSM"; @@ -585,14 +576,12 @@ return LODData = "BinaryString"; PhysicsData = "BinaryString"; PhysicalConfigData = "SharedString"; - CollisionFidelity = "Enum:CollisionFidelity"; }; Defaults = { InitialSize = Vector3.new(1, 1, 1); PhysicalConfigData = "1B2M2Y8AsgTpgAmY7PhCfg=="; - CollisionFidelity = Enum.CollisionFidelity.Default; }; }; @@ -656,7 +645,6 @@ return StreamingPauseMode = "Enum:StreamingPauseMode"; TerrainWeldsFixed = "bool"; - TemporaryLegacyPhysicsSolverOverrideStreaming = "bool"; }; Defaults = @@ -669,7 +657,6 @@ return StreamingPauseMode = Enum.StreamingPauseMode.Default; TerrainWeldsFixed = true; - TemporaryLegacyPhysicsSolverOverrideStreaming = false; } } } \ No newline at end of file diff --git a/RobloxFile.cs b/RobloxFile.cs index 852cd09..aba5b69 100644 --- a/RobloxFile.cs +++ b/RobloxFile.cs @@ -11,6 +11,8 @@ namespace RobloxFiles /// public abstract class RobloxFile : Instance { + public static bool LogErrors = false; + protected abstract void ReadFile(byte[] buffer); /// diff --git a/RobloxFileFormat.dll b/RobloxFileFormat.dll index 9fc7d2b..a3360c3 100644 Binary files a/RobloxFileFormat.dll and b/RobloxFileFormat.dll differ diff --git a/Tree/Attributes.cs b/Tree/Attributes.cs index bba5e16..c019c21 100644 --- a/Tree/Attributes.cs +++ b/Tree/Attributes.cs @@ -87,7 +87,9 @@ namespace RobloxFiles } catch { - Console.WriteLine($"RobloxFile - Got unknown Enum {name} in Attribute."); + if (RobloxFile.LogErrors) + Console.Error.WriteLine($"RobloxFile - Got unknown Enum {name} in Attribute."); + return null; } } diff --git a/Tree/Instance.cs b/Tree/Instance.cs index add63e0..4d7847d 100644 --- a/Tree/Instance.cs +++ b/Tree/Instance.cs @@ -512,6 +512,11 @@ namespace RobloxFiles if (field.GetCustomAttribute() != null) continue; + if (fieldName == "Archivable" || fieldName.EndsWith("k__BackingField")) + continue; + else if (fieldName == "Bevel_Roundness") + fieldName = "Bevel Roundness"; + PropertyType propType = PropertyType.Unknown; if (Property.Types.ContainsKey(fieldType)) diff --git a/Tree/Property.cs b/Tree/Property.cs index a2a3989..a1dc37d 100644 --- a/Tree/Property.cs +++ b/Tree/Property.cs @@ -202,6 +202,9 @@ namespace RobloxFiles } else { + if (!RobloxFile.LogErrors) + return false; + Console.Error.WriteLine($"RobloxFiles.Property - No defined member for {Instance.ClassName}.{Name}"); } } @@ -236,6 +239,9 @@ namespace RobloxFiles } catch { + if (!RobloxFile.LogErrors) + return; + Console.Error.WriteLine($"RobloxFiles.Property - Failed to cast value {value} into property {Instance.ClassName}.{Name}"); } } @@ -252,6 +258,9 @@ namespace RobloxFiles } catch { + if (!RobloxFile.LogErrors) + return; + Console.Error.WriteLine($"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 edd070c..9aa7ab0 100644 --- a/XmlFormat/IO/XmlFileReader.cs +++ b/XmlFormat/IO/XmlFileReader.cs @@ -107,11 +107,12 @@ namespace RobloxFiles.XmlFormat }; if (!tokenHandler.ReadProperty(prop, propNode)) - Console.WriteLine("Could not read property: " + prop.GetFullName() + '!'); + if (RobloxFile.LogErrors) + Console.Error.WriteLine("Could not read property: " + prop.GetFullName() + '!'); instance.AddProperty(ref prop); } - else + else if (RobloxFile.LogErrors) { Console.WriteLine("No IXmlPropertyToken found for property type: " + propType + '!'); } diff --git a/XmlFormat/IO/XmlFileWriter.cs b/XmlFormat/IO/XmlFileWriter.cs index f0c3c44..7f3f920 100644 --- a/XmlFormat/IO/XmlFileWriter.cs +++ b/XmlFormat/IO/XmlFileWriter.cs @@ -94,7 +94,9 @@ namespace RobloxFiles.XmlFormat if (handler == null) { - Console.WriteLine("XmlDataWriter.WriteProperty: No token handler found for property type: {0}", propType); + if (RobloxFile.LogErrors) + Console.Error.WriteLine("XmlDataWriter.WriteProperty: No token handler found for property type: {0}", propType); + return null; } diff --git a/XmlFormat/Tokens/Content.cs b/XmlFormat/Tokens/Content.cs index 1933bac..60c4242 100644 --- a/XmlFormat/Tokens/Content.cs +++ b/XmlFormat/Tokens/Content.cs @@ -30,6 +30,9 @@ namespace RobloxFiles.XmlFormat.PropertyTokens } catch { + if (!RobloxFile.LogErrors) + return true; + Console.WriteLine("ContentToken: Got illegal base64 string: {0}", data); } } diff --git a/XmlFormat/XmlRobloxFile.cs b/XmlFormat/XmlRobloxFile.cs index 25cf721..8ad56ae 100644 --- a/XmlFormat/XmlRobloxFile.cs +++ b/XmlFormat/XmlRobloxFile.cs @@ -98,7 +98,10 @@ namespace RobloxFiles else if (refId != "null") { string name = refProp.GetFullName(); - Console.WriteLine("XmlRobloxFile: Could not resolve reference for {0}", name); + + if (LogErrors) + Console.Error.WriteLine("XmlRobloxFile: Could not resolve reference for {0}", name); + refProp.Value = null; } }