From 79bb43b77cb7b3222506049986db0a7bc6127207 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 8 Dec 2022 21:23:31 +0100 Subject: [PATCH] Core: embed custom datapackage into .archipelago (#1288) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- Main.py | 12 ++++++++++-- MultiServer.py | 12 +++++++++++- docs/network protocol.md | 13 ++++++++----- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Main.py b/Main.py index 31351fc5..aaf19261 100644 --- a/Main.py +++ b/Main.py @@ -11,7 +11,7 @@ import zipfile from typing import Dict, List, Tuple, Optional, Set from BaseClasses import Item, MultiWorld, CollectionState, Region, RegionType, LocationProgressType, Location -from worlds.alttp.Items import item_name_groups +import worlds from worlds.alttp.Regions import is_main_entrance from Fill import distribute_items_restrictive, flood_items, balance_multiworld_progression, distribute_planned from worlds.alttp.Shops import SHOP_ID_START, total_shop_slots, FillDisabledShopSlots @@ -368,6 +368,13 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No for player in world.groups.get(location.item.player, {}).get("players", [])]): precollect_hint(location) + # custom datapackage + datapackage = {} + for game_world in world.worlds.values(): + if game_world.data_version == 0 and game_world.game not in datapackage: + datapackage[game_world.game] = worlds.network_data_package["games"][game_world.game] + datapackage[game_world.game]["item_name_groups"] = game_world.item_name_groups + multidata = { "slot_data": slot_data, "slot_info": slot_info, @@ -387,7 +394,8 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No "version": tuple(version_tuple), "tags": ["AP"], "minimum_versions": minimum_versions, - "seed_name": world.seed_name + "seed_name": world.seed_name, + "datapackage": datapackage, } AutoWorld.call_all(world, "modify_multidata", multidata) diff --git a/MultiServer.py b/MultiServer.py index 072e5aa1..be53119f 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -124,6 +124,7 @@ class Context: stored_data_notification_clients: typing.Dict[str, typing.Set[Client]] item_names: typing.Dict[int, str] = Utils.KeyedDefaultDict(lambda code: f'Unknown item (ID:{code})') + item_name_groups: typing.Dict[str, typing.Dict[str, typing.Set[str]]] location_names: typing.Dict[int, str] = Utils.KeyedDefaultDict(lambda code: f'Unknown location (ID:{code})') all_item_and_group_names: typing.Dict[str, typing.Set[str]] forced_auto_forfeits: typing.Dict[str, bool] @@ -202,7 +203,6 @@ class Context: self.non_hintable_names = collections.defaultdict(frozenset) self._load_game_data() - self._init_game_data() # Datapackage retrieval def _load_game_data(self): @@ -412,6 +412,16 @@ class Context: server_options = decoded_obj.get("server_options", {}) self._set_options(server_options) + # custom datapackage + for game_name, data in decoded_obj.get("datapackage", {}).items(): + logging.info(f"Loading custom datapackage for game {game_name}") + self.gamespackage[game_name] = data + self.item_name_groups[game_name] = data["item_name_groups"] + del data["item_name_groups"] # remove from datapackage, but keep in self.item_name_groups + self._init_game_data() + for game_name, data in self.item_name_groups.items(): + self.read_data[f"item_name_groups_{game_name}"] = lambda lgame=game_name: self.item_name_groups[lgame] + # saving def save(self, now=False) -> bool: diff --git a/docs/network protocol.md b/docs/network protocol.md index 74e3fab1..5b574a0d 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -367,16 +367,19 @@ Used to request a single or multiple values from the server's data storage, see | keys | list\[str\] | Keys to retrieve the values for. | Additional arguments sent in this package will also be added to the [Retrieved](#Retrieved) package it triggers. -Some special keys exist with specific return data: -| Name | Type | Notes | -|----------------------------|-----------------------|----------------------------------------------| -| \_read_hints_{team}_{slot} | list\[[Hint](#Hint)\] | All Hints belonging to the requested Player. | -| \_read_slot_data_{slot} | any | slot_data belonging to the requested slot. | +Some special keys exist with specific return data, all of them have the prefix `_read_`, so `hints_{team}_{slot}` is `_read_hints_{team}_{slot}`. + +| Name | Type | Notes | +|-------------------------------|------------------------|---------------------------------------------------| +| hints_{team}_{slot} | list\[[Hint](#Hint)\] | All Hints belonging to the requested Player. | +| slot_data_{slot} | any | slot_data belonging to the requested slot. | +| item_name_groups_{game_name} | dict\[str, list\[str]] | item_name_groups belonging to the requested game. | ### Set Used to write data to the server's data storage, that data can then be shared across worlds or just saved for later. Values for keys in the data storage can be retrieved with a [Get](#Get) package, or monitored with a [SetNotify](#SetNotify) package. +Keys that start with `_read_` cannot be set. #### Arguments | Name | Type | Notes | |------------|-------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|