6565 "from UnityPy.classes import *" ,
6666 "from UnityPy.classes.math import (ColorRGBA, Matrix3x4f, Matrix4x4f, Quaternionf, Vector2f, Vector3f, Vector4f, float3, float4,)" ,
6767 '''T = TypeVar("T")
68- def typetree_defined (clazz : T) -> T:
68+ def UTTCGen (clazz : T) -> T:
6969 """dataclass-like decorator for typetree classess with nested type support
7070
7171 limitations:
@@ -115,6 +115,17 @@ def __repr__(self) -> str:
115115 clazz.__init__ = __init__
116116 clazz.__repr__ = __repr__
117117 return clazz
118+
119+ # Helper functions
120+ def UTTCGen_Reread(Mono: MonoBehaviour):
121+ script = Mono.m_Script.read()
122+ fullname = script.m_ClassName
123+ if script.m_Namespace:
124+ fullname = f"{script.m_Namespace}.{fullname}"
125+ definition = TYPETREE_DEFS.get(fullname, None)
126+ assert definition is not None, f"Typetree definition for {fullname} not found"
127+ raw_def = Mono.object_reader.read_typetree(definition)
128+ return raw_def, fullname
118129''' ,
119130 ]
120131)
@@ -123,9 +134,41 @@ def __repr__(self) -> str:
123134
124135
125136def translate_name (m_Name : str , ** kwargs ):
137+ NG = "<>|`="
126138 m_Name = m_Name .replace ("<>" , "__generic_" ) # Generic templates
127139 m_Name = m_Name .replace ("<" , "_" ).replace (">" , "_" ) # Templated
128- m_Name = m_Name .replace ("=" , "_" ) # Special chars
140+ for c in NG :
141+ m_Name = m_Name .replace (c , "_" )
142+ RESERVED_NAMES = {
143+ "class" ,
144+ "def" ,
145+ "return" ,
146+ "if" ,
147+ "else" ,
148+ "elif" ,
149+ "for" ,
150+ "while" ,
151+ "in" ,
152+ "is" ,
153+ "not" ,
154+ "and" ,
155+ "or" ,
156+ "from" ,
157+ "import" ,
158+ "as" ,
159+ "with" ,
160+ "try" ,
161+ "except" ,
162+ "finally" ,
163+ "raise" ,
164+ "assert" ,
165+ "break" ,
166+ "continue" ,
167+ "pass" ,
168+ "yield" ,
169+ }
170+ if m_Name in RESERVED_NAMES :
171+ m_Name = "_" + m_Name
129172 return m_Name
130173
131174
@@ -169,6 +212,7 @@ def translate_type(
169212
170213
171214def declare_field (name : str , type : str , org_type : str = None ):
215+ name = translate_name (name )
172216 if type not in {"object" , "List[object]" , "PPtr[object]" }:
173217 return f"{ name } : { type } "
174218 else :
@@ -200,7 +244,8 @@ def dfs(u):
200244 for clazz in graph :
201245 if not vis [clazz ]:
202246 flag &= dfs (clazz )
203- assert flag , "graph contains cycle"
247+ # XXX: Shouldn't happen. Need to figure out how this is possible
248+ # assert flag, "graph contains cycle"
204249 return topo
205250
206251
@@ -252,7 +297,7 @@ def emit_line(*lines: str):
252297 clazz = translate_name (clazz )
253298 clazzes .append (clazz )
254299 clazz_fields = list ()
255- emit_line (f"@typetree_defined " )
300+ emit_line (f"@UTTCGen " )
256301 if lvl1 :
257302 parent = translate_type (fields [0 ].m_Type , strip = True , fallback = False )
258303 emit_line (f"class { clazz } ({ parent } ):" )
@@ -264,10 +309,16 @@ def emit_line(*lines: str):
264309 raise ValueError # XXX: Should NEVER happen
265310 pa_dep1 = dp [parent ]
266311 cur_dep1 = pa_dep1
267- for i , field in enumerate (filter (lambda field : field .m_Level == 1 , fields )):
268- if i < pa_dep1 :
312+ for dep , (i , field ) in enumerate (
313+ filter (lambda field : field [1 ].m_Level == 1 , enumerate (fields ))
314+ ):
315+ if dep < pa_dep1 :
269316 # Skip parent fields at lvl1
270317 continue
318+ if i + 1 < len (fields ) and fields [i + 1 ].m_Type == "Array" :
319+ if field .m_Type .startswith ("List" ):
320+ # Rename this to Type[]
321+ field .m_Type = fields [i + 3 ].m_Type + "[]"
271322 name , type = field .m_Name , translate_type (
272323 field .m_Type , typenames = classname_nodes | import_defs
273324 )
0 commit comments