Skip to content

Commit bb6fca1

Browse files
committed
TypeTree - implement writing ManagedReferencesRegistry
1 parent 52ce553 commit bb6fca1

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

UnityPy/files/ObjectReader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def save_typetree(
226226
node = self._get_typetree_node(nodes)
227227
if not writer:
228228
writer = EndianBinaryWriter(endian=self.reader.endian)
229-
TypeTreeHelper.write_typetree(tree, node, writer)
229+
TypeTreeHelper.write_typetree(tree, node, writer, self.assets_file)
230230
data = writer.bytes
231231
self.set_raw_data(data)
232232
return data

UnityPy/helpers/TypeTreeHelper.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ def write_typetree(
149149
value: Union[dict[str, Any], Object],
150150
root_node: TypeTreeNode,
151151
writer: EndianBinaryWriter,
152+
assetsfile: Optional[SerializedFile] = None,
152153
) -> None:
153154
"""Writes the typetree of the object contained in the reader via the node list.
154155
@@ -161,7 +162,8 @@ def write_typetree(
161162
writer : EndianBinaryWriter
162163
Writer of the object to be parsed
163164
"""
164-
return write_value(value, root_node, writer)
165+
config = TypeTreeConfig(isinstance(value, dict), assetsfile, False)
166+
return write_value(value, root_node, writer, config)
165167

166168

167169
def read_value(
@@ -403,6 +405,7 @@ def write_value(
403405
value: Any,
404406
node: TypeTreeNode,
405407
writer: EndianBinaryWriter,
408+
config: TypeTreeConfig,
406409
) -> None:
407410
# print(reader.Position, node.m_Name, node.m_Type, node.m_MetaFlag)
408411
align = metaflag_is_aligned(node.m_MetaFlag)
@@ -413,21 +416,42 @@ def write_value(
413416
elif node.m_Type == "pair":
414417
write_value(value[0], node.m_Children[0], writer)
415418
write_value(value[1], node.m_Children[1], writer)
419+
elif node.m_Type == "ReferencedObject":
420+
for child in node.m_Children:
421+
if child.m_Type == "ReferencedObjectData":
422+
ref_type_nodes = get_ref_type_node(value, config.assetsfile)
423+
write_value(value[child.m_Name], ref_type_nodes, writer, config)
424+
else:
425+
write_value(value[child.m_Name], child, writer, config)
416426
elif node.m_Children and node.m_Children[0].m_Type == "Array":
417427
if metaflag_is_aligned(node.m_Children[0].m_MetaFlag):
418428
align = True
419429

420430
writer.write_int(len(value))
421431
subtype = node.m_Children[0].m_Children[1]
422-
[write_value(sub_value, subtype, writer) for sub_value in value]
432+
[write_value(sub_value, subtype, writer, config) for sub_value in value]
423433

424434
else: # Class
425435
if isinstance(value, dict):
426436
for child in node.m_Children:
427-
write_value(value[child.m_Name], child, writer)
437+
if child.m_Type == "ManagedReferencesRegistry":
438+
if config.has_registry:
439+
continue
440+
else:
441+
config = copy(config)
442+
config.has_registry = True
443+
write_value(value[child.m_Name], child, writer, config)
428444
else:
429445
for child in node.m_Children:
430-
write_value(getattr(value, clean_name(child.m_Name)), child, writer)
446+
if child.m_Type == "ManagedReferencesRegistry":
447+
if config.has_registry:
448+
continue
449+
else:
450+
config = copy(config)
451+
config.has_registry = True
452+
write_value(
453+
getattr(value, clean_name(child.m_Name)), child, writer, config
454+
)
431455

432456
if align:
433457
writer.align_stream()

0 commit comments

Comments
 (0)