GitHub Viewer
from __future__ import annotations
from typing import (
TYPE_CHECKING,
Any,
Dict,
Generic,
List,
Optional,
Type,
TypeVar,
Union,
cast,
)
from attrs import define
from ..classes import MonoBehaviour
from ..classes.ClassIDTypeToClassMap import ClassIDTypeToClassMap
from ..enums import ClassIDType
from ..exceptions import TypeTreeError
from ..helpers import TypeTreeHelper
from ..helpers.Tpk import get_typetree_node
from ..helpers.TypeTreeNode import TypeTreeNode
from ..streams import EndianBinaryReader, EndianBinaryWriter
if TYPE_CHECKING:
from ..files.SerializedFile import SerializedFile, SerializedType
T = TypeVar("T")
NodeInput = Union[TypeTreeNode, List[Dict[str, Union[str, int]]]]
@define(
slots=True,
)
class ObjectReader(Generic[T]):
assets_file: SerializedFile
reader: EndianBinaryReader
path_id: int
type_id: int
serialized_type: Optional[SerializedType]
class_id: int
type: ClassIDType
byte_start: int
byte_size: int
is_destroyed: Optional[int]
is_stripped: Optional[int]
data: Optional[bytes] = None
_read_until: Optional[int] = None
@property
def version(self):
return self.assets_file.version
@property
def version2(self):
return self.assets_file.header.version
@property
def platform(self):
return self.assets_file.target_platform
# saves where the parser stopped
# in case that not all data is read
# and the obj.data is changed, the unknown data can be added again
@classmethod
def from_reader(cls, assets_file: SerializedFile, reader: EndianBinaryReader) -> ObjectReader[Any]:
header = assets_file.header
types = assets_file.types
# AssetStudio ObjectInfo init
if assets_file.big_id_enabled:
path_id = reader.read_long()
elif header.version < 14:
path_id = reader.read_int()
else:
reader.align_stream()
path_id = reader.read_long()
if header.version >= 22:
byte_start = reader.read_long()
else:
byte_start = reader.read_u_int()
byte_start += header.data_offset
byte_size = reader.read_u_int()
type_id = reader.read_int()
serialized_type = None
if header.version < 16:
class_id = reader.read_u_short()
for typ in types:
if typ.class_id == type_id:
serialized_type = typ
break
else:
typ = types[type_id]
serialized_type = typ
class_id = typ.class_id
clz_type = ClassIDType(class_id)
is_destroyed = None
if header.version < 11:
is_destroyed = reader.read_u_short()
if 11