forked from MooncellWiki/UnityPy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypeTreeGenerator.py
More file actions
92 lines (76 loc) · 2.92 KB
/
Copy pathTypeTreeGenerator.py
File metadata and controls
92 lines (76 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import os
from typing import Dict, List, Tuple
from .TypeTreeNode import TypeTreeNode
try:
from TypeTreeGeneratorAPI import TypeTreeGenerator as TypeTreeGeneratorBase
except ImportError:
class TypeTreeGeneratorBase:
def __init__(self, unity_version: str):
raise ImportError("TypeTreeGeneratorAPI isn't installed!")
def load_dll(self, dll: bytes): ...
def load_il2cpp(self, il2cpp: bytes, metadata: bytes): ...
def get_nodes_as_json(self, assembly: str, fullname: str) -> str: ...
def get_nodes(self, assembly: str, fullname: str) -> List[TypeTreeNode]: ...
class TypeTreeGenerator(TypeTreeGeneratorBase):
cache: Dict[Tuple[str, str], TypeTreeNode]
def __init__(self, unity_version: str):
super().__init__(unity_version)
self.cache = {}
def load_local_game(self, root_dir: str):
root_files = os.listdir(root_dir)
data_dir = os.path.join(
root_dir, next(f for f in root_files if f.endswith("_Data"))
)
if "GameAssembly.dll" in root_files:
ga_fp = os.path.join(root_dir, "GameAssembly.dll")
gm_fp = os.path.join(
data_dir, "il2cpp_data", "Metadata", "global-metadata.dat"
)
ga_raw = open(ga_fp, "rb").read()
gm_raw = open(gm_fp, "rb").read()
self.load_il2cpp(ga_raw, gm_raw)
else:
self.load_local_dll_folder(os.path.join(data_dir, "Managed"))
def load_local_dll_folder(self, dll_dir: str):
for f in os.listdir(dll_dir):
fp = os.path.join(dll_dir, f)
with open(fp, "rb") as f:
data = f.read()
self.load_dll(data)
def get_nodes_up(self, assembly: str, fullname: str) -> TypeTreeNode:
root = self.cache.get((assembly, fullname))
if root is not None:
return root
base_nodes = self.get_nodes(f"{assembly}.dll", fullname)
base_root = base_nodes[0]
root = TypeTreeNode(
base_root.m_Level,
base_root.m_Type,
base_root.m_Name,
0,
0,
m_MetaFlag=base_root.m_MetaFlag,
)
stack: List[TypeTreeNode] = []
parent = root
prev = root
for base_node in base_nodes[1:]:
node = TypeTreeNode(
base_node.m_Level,
base_node.m_Type,
base_node.m_Name,
0,
0,
m_MetaFlag=base_node.m_MetaFlag,
)
if node.m_Level > prev.m_Level:
stack.append(parent)
parent = prev
elif node.m_Level < prev.m_Level:
while node.m_Level <= parent.m_Level:
parent = stack.pop()
parent.m_Children.append(node)
prev = node
self.cache[(assembly, fullname)] = root
return root
__all__ = ("TypeTreeGenerator",)