120 lines
4.5 KiB
Python
120 lines
4.5 KiB
Python
from typing import Sequence
|
|
|
|
from lib.archive import *
|
|
|
|
|
|
def decode(
|
|
reader: FArchiveReader, type_name: str, size: int, path: str
|
|
) -> dict[str, Any]:
|
|
if type_name != "MapProperty":
|
|
raise Exception(f"Expected MapProperty, got {type_name}")
|
|
value = reader.property(type_name, size, path, allow_custom=False)
|
|
# Decode the raw bytes and replace the raw data
|
|
group_map = value["value"]
|
|
for group in group_map:
|
|
group_type = group["value"]["GroupType"]["value"]["value"]
|
|
group_bytes = group["value"]["RawData"]["value"]["values"]
|
|
group["value"]["RawData"]["value"] = decode_bytes(group_bytes, group_type)
|
|
return value
|
|
|
|
|
|
def decode_bytes(group_bytes: Sequence[int], group_type: str) -> dict[str, Any]:
|
|
reader = FArchiveReader(bytes(group_bytes))
|
|
group_data = {
|
|
"group_type": group_type,
|
|
"group_id": reader.guid(),
|
|
"group_name": reader.fstring(),
|
|
"individual_character_handle_ids": reader.tarray(instance_id_reader),
|
|
}
|
|
if group_type in [
|
|
"EPalGroupType::Guild",
|
|
"EPalGroupType::IndependentGuild",
|
|
"EPalGroupType::Organization",
|
|
]:
|
|
org = {
|
|
"org_type": reader.byte(),
|
|
"base_ids": reader.tarray(uuid_reader),
|
|
}
|
|
group_data |= org
|
|
if group_type in ["EPalGroupType::Guild", "EPalGroupType::IndependentGuild"]:
|
|
guild = {
|
|
"base_camp_level": reader.i32(),
|
|
"map_object_instance_ids_base_camp_points": reader.tarray(uuid_reader),
|
|
"guild_name": reader.fstring(),
|
|
}
|
|
group_data |= guild
|
|
if group_type == "EPalGroupType::IndependentGuild":
|
|
indie = {
|
|
"player_uid": reader.guid(),
|
|
"guild_name_2": reader.fstring(),
|
|
"player_info": {
|
|
"last_online_real_time": reader.i64(),
|
|
"player_name": reader.fstring(),
|
|
},
|
|
}
|
|
group_data |= indie
|
|
if group_type == "EPalGroupType::Guild":
|
|
guild = {"admin_player_uid": reader.guid(), "players": []}
|
|
player_count = reader.i32()
|
|
for _ in range(player_count):
|
|
player = {
|
|
"player_uid": reader.guid(),
|
|
"player_info": {
|
|
"last_online_real_time": reader.i64(),
|
|
"player_name": reader.fstring(),
|
|
},
|
|
}
|
|
guild["players"].append(player)
|
|
group_data |= guild
|
|
#if not reader.eof():
|
|
#raise Exception("Warning: EOF not reached")
|
|
return group_data
|
|
|
|
|
|
def encode(
|
|
writer: FArchiveWriter, property_type: str, properties: dict[str, Any]
|
|
) -> int:
|
|
if property_type != "MapProperty":
|
|
raise Exception(f"Expected MapProperty, got {property_type}")
|
|
del properties["custom_type"]
|
|
group_map = properties["value"]
|
|
for group in group_map:
|
|
if "values" in group["value"]["RawData"]["value"]:
|
|
continue
|
|
p = group["value"]["RawData"]["value"]
|
|
encoded_bytes = encode_bytes(p)
|
|
group["value"]["RawData"]["value"] = {"values": [b for b in encoded_bytes]}
|
|
return writer.property_inner(property_type, properties)
|
|
|
|
|
|
def encode_bytes(p: dict[str, Any]) -> bytes:
|
|
writer = FArchiveWriter()
|
|
writer.guid(p["group_id"])
|
|
writer.fstring(p["group_name"])
|
|
writer.tarray(instance_id_writer, p["individual_character_handle_ids"])
|
|
if p["group_type"] in [
|
|
"EPalGroupType::Guild",
|
|
"EPalGroupType::IndependentGuild",
|
|
"EPalGroupType::Organization",
|
|
]:
|
|
writer.byte(p["org_type"])
|
|
writer.tarray(uuid_writer, p["base_ids"])
|
|
if p["group_type"] in ["EPalGroupType::Guild", "EPalGroupType::IndependentGuild"]:
|
|
writer.i32(p["base_camp_level"])
|
|
writer.tarray(uuid_writer, p["map_object_instance_ids_base_camp_points"])
|
|
writer.fstring(p["guild_name"])
|
|
if p["group_type"] == "EPalGroupType::IndependentGuild":
|
|
writer.guid(p["player_uid"])
|
|
writer.fstring(p["guild_name_2"])
|
|
writer.i64(p["player_info"]["last_online_real_time"])
|
|
writer.fstring(p["player_info"]["player_name"])
|
|
if p["group_type"] == "EPalGroupType::Guild":
|
|
writer.guid(p["admin_player_uid"])
|
|
writer.i32(len(p["players"]))
|
|
for i in range(len(p["players"])):
|
|
writer.guid(p["players"][i]["player_uid"])
|
|
writer.i64(p["players"][i]["player_info"]["last_online_real_time"])
|
|
writer.fstring(p["players"][i]["player_info"]["player_name"])
|
|
encoded_bytes = writer.bytes()
|
|
return encoded_bytes
|