Patched fatal flaw with property setter.

Turns out the property setter was failing to cover inheritance, so referent properties were being corrupted in the process. This should now be fixed.

I've also deprecated IsA<T>() in favor of using C#'s own `is` operator and stopped locking the parent of service classes to avoid saving issues.
This commit is contained in:
CloneTrooper1019 2020-08-21 10:31:12 -05:00
parent 2ff5d82218
commit 1314be22bb
5 changed files with 26 additions and 30 deletions

View File

@ -27,7 +27,6 @@ namespace RobloxFiles.BinaryFormat.Chunks
Instance child = file.Instances[childId]; Instance child = file.Instances[childId];
child.Parent = (parentId >= 0 ? file.Instances[parentId] : file); child.Parent = (parentId >= 0 ? file.Instances[parentId] : file);
child.ParentLocked = child.IsService;
} }
} }

View File

@ -362,7 +362,12 @@ namespace RobloxFiles.BinaryFormat.Chunks
readProperties(i => readProperties(i =>
{ {
int instId = instIds[i]; int instId = instIds[i];
return instId >= 0 ? file.Instances[instId] : null; Instance result = null;
if (instId >= 0)
result = file.Instances[instId];
return result;
}); });
break; break;

Binary file not shown.

View File

@ -53,11 +53,8 @@ namespace RobloxFiles
/// <summary>Indicates whether this Instance is a Service.</summary> /// <summary>Indicates whether this Instance is a Service.</summary>
public bool IsService { get; internal set; } public bool IsService { get; internal set; }
/// <summary>Raw list of CollectionService tags assigned to this Instance.</summary>
private List<string> RawTags = new List<string>();
/// <summary>A list of CollectionService tags assigned to this Instance.</summary> /// <summary>A list of CollectionService tags assigned to this Instance.</summary>
public List<string> Tags => RawTags; public List<string> Tags { get; } = new List<string>();
/// <summary>The attributes defined for this Instance.</summary> /// <summary>The attributes defined for this Instance.</summary>
public Attributes Attributes { get; private set; } public Attributes Attributes { get; private set; }
@ -144,6 +141,7 @@ namespace RobloxFiles
/// <summary> /// <summary>
/// Returns true if the provided instance inherits from the provided instance type. /// Returns true if the provided instance inherits from the provided instance type.
/// </summary> /// </summary>
[Obsolete("Use the `is` operator instead.")]
public bool IsA<T>() where T : Instance public bool IsA<T>() where T : Instance
{ {
Type myType = GetType(); Type myType = GetType();
@ -161,7 +159,7 @@ namespace RobloxFiles
{ {
T result = null; T result = null;
if (IsA<T>()) if (this is T)
result = this as T; result = this as T;
return result; return result;
@ -212,7 +210,7 @@ namespace RobloxFiles
public T[] GetChildrenOfType<T>() where T : Instance public T[] GetChildrenOfType<T>() where T : Instance
{ {
T[] ofType = GetChildren() T[] ofType = GetChildren()
.Where(child => child.IsA<T>()) .Where(child => child is T)
.Cast<T>() .Cast<T>()
.ToArray(); .ToArray();
@ -224,7 +222,7 @@ namespace RobloxFiles
/// </summary> /// </summary>
public Instance[] GetDescendants() public Instance[] GetDescendants()
{ {
List<Instance> results = new List<Instance>(); var results = new List<Instance>();
foreach (Instance child in Children) foreach (Instance child in Children)
{ {
@ -245,7 +243,7 @@ namespace RobloxFiles
public T[] GetDescendantsOfType<T>() where T : Instance public T[] GetDescendantsOfType<T>() where T : Instance
{ {
T[] ofType = GetDescendants() T[] ofType = GetDescendants()
.Where(desc => desc.IsA<T>()) .Where(desc => desc is T)
.Cast<T>() .Cast<T>()
.ToArray(); .ToArray();
@ -361,9 +359,9 @@ namespace RobloxFiles
while (check != null) while (check != null)
{ {
if (check.IsA<T>()) if (check is T)
{ {
ancestor = (T)check; ancestor = check as T;
break; break;
} }
@ -415,30 +413,26 @@ namespace RobloxFiles
public T FindFirstChildWhichIsA<T>(bool recursive = false) where T : Instance public T FindFirstChildWhichIsA<T>(bool recursive = false) where T : Instance
{ {
var query = Children var query = Children
.Where(child => child.IsA<T>()) .Where(child => child is T)
.Cast<T>(); .Cast<T>();
T result = null;
if (query.Any()) if (query.Any())
{ return query.First();
result = query.First();
} if (recursive)
else if (recursive)
{ {
foreach (Instance child in Children) foreach (Instance child in Children)
{ {
T found = child.FindFirstChildWhichIsA<T>(true); T found = child.FindFirstChildWhichIsA<T>(true);
if (found != null) if (found == null)
{ continue;
result = found;
break; return found;
}
} }
} }
return result; return null;
} }
/// <summary> /// <summary>
@ -539,6 +533,7 @@ namespace RobloxFiles
{ {
case "String": case "String":
case "Double": case "Double":
case "Int64":
xmlToken = xmlToken.ToLowerInvariant(); xmlToken = xmlToken.ToLowerInvariant();
break; break;
case "Boolean": case "Boolean":
@ -550,9 +545,6 @@ namespace RobloxFiles
case "Int32": case "Int32":
xmlToken = "int"; xmlToken = "int";
break; break;
case "Int64":
xmlToken = "int64";
break;
case "Rect": case "Rect":
xmlToken = "Rect2D"; xmlToken = "Rect2D";
break; break;
@ -564,7 +556,7 @@ namespace RobloxFiles
if (!props.ContainsKey(fieldName)) if (!props.ContainsKey(fieldName))
{ {
Property newProp = new Property() var newProp = new Property()
{ {
Value = field.GetValue(this), Value = field.GetValue(this),
XmlToken = xmlToken, XmlToken = xmlToken,

View File

@ -228,7 +228,7 @@ namespace RobloxFiles
var valueType = value?.GetType(); var valueType = value?.GetType();
Type memberType = member.MemberType; Type memberType = member.MemberType;
if (memberType == valueType || value == null) if (value == null || memberType.IsAssignableFrom(valueType))
{ {
try try
{ {