Palworld-co-op-to-server-fix/lib/rawdata/group.py

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