82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
from typing import Any, Sequence
|
|
|
|
from lib.archive import *
|
|
|
|
|
|
def decode(
|
|
reader: FArchiveReader, type_name: str, size: int, path: str
|
|
) -> dict[str, Any]:
|
|
if type_name != "ArrayProperty":
|
|
raise Exception(f"Expected ArrayProperty, got {type_name}")
|
|
value = reader.property(type_name, size, path, allow_custom=False)
|
|
data_bytes = value["value"]["values"]
|
|
value["value"] = decode_bytes(data_bytes)
|
|
return value
|
|
|
|
|
|
def connect_info_item_reader(reader: FArchiveReader) -> dict[str, Any]:
|
|
return {
|
|
"connect_to_model_instance_id": reader.guid(),
|
|
"index": reader.byte(),
|
|
}
|
|
|
|
|
|
def connect_info_item_writer(writer: FArchiveWriter, properties: dict[str, Any]):
|
|
writer.guid(properties["connect_to_model_instance_id"])
|
|
writer.byte(properties["index"])
|
|
|
|
|
|
def decode_bytes(c_bytes: Sequence[int]) -> dict[str, Any]:
|
|
if len(c_bytes) == 0:
|
|
return None
|
|
reader = FArchiveReader(bytes(c_bytes))
|
|
data = {}
|
|
data["supported_level"] = reader.i32()
|
|
data["connect"] = {
|
|
"index": reader.byte(),
|
|
"any_place": reader.tarray(connect_info_item_reader),
|
|
}
|
|
# We are guessing here, we don't have information about the type without mapping object names -> types
|
|
# Stairs have 2 connectors (up and down),
|
|
# Roofs have 4 connectors (front, back, right, left)
|
|
if not reader.eof():
|
|
data["other_connectors"] = []
|
|
while not reader.eof():
|
|
data["other_connectors"].append(
|
|
{
|
|
"index": reader.byte(),
|
|
"connect": reader.tarray(connect_info_item_reader),
|
|
}
|
|
)
|
|
if len(data["other_connectors"]) not in [2, 4]:
|
|
print(
|
|
f"Warning: unknown connector type with {len(data['other_connectors'])} connectors"
|
|
)
|
|
return data
|
|
|
|
|
|
def encode(
|
|
writer: FArchiveWriter, property_type: str, properties: dict[str, Any]
|
|
) -> int:
|
|
if property_type != "ArrayProperty":
|
|
raise Exception(f"Expected ArrayProperty, got {property_type}")
|
|
del properties["custom_type"]
|
|
encoded_bytes = encode_bytes(properties["value"])
|
|
properties["value"] = {"values": [b for b in encoded_bytes]}
|
|
return writer.property_inner(property_type, properties)
|
|
|
|
|
|
def encode_bytes(p: dict[str, Any]) -> bytes:
|
|
if p is None:
|
|
return bytes()
|
|
writer = FArchiveWriter()
|
|
writer.i32(p["supported_level"])
|
|
writer.byte(p["connect"]["index"])
|
|
writer.tarray(connect_info_item_writer, p["connect"]["any_place"])
|
|
if "other_connectors" in p:
|
|
for other in p["other_connectors"]:
|
|
writer.byte(other["index"])
|
|
writer.tarray(connect_info_item_writer, other["connect"])
|
|
encoded_bytes = writer.bytes()
|
|
return encoded_bytes
|