Core: add generator_version to network protocol

This commit is contained in:
Fabian Dill 2023-04-25 13:26:52 +02:00 committed by Fabian Dill
parent 4c3eaf2996
commit 6c459066a7
4 changed files with 25 additions and 14 deletions

View File

@ -157,6 +157,7 @@ class CommonContext:
disconnected_intentionally: bool = False disconnected_intentionally: bool = False
server: typing.Optional[Endpoint] = None server: typing.Optional[Endpoint] = None
server_version: Version = Version(0, 0, 0) server_version: Version = Version(0, 0, 0)
generator_version: Version = Version(0, 0, 0)
current_energy_link_value: typing.Optional[int] = None # to display in UI, gets set by server current_energy_link_value: typing.Optional[int] = None # to display in UI, gets set by server
last_death_link: float = time.time() # last send/received death link on AP layer last_death_link: float = time.time() # last send/received death link on AP layer
@ -260,6 +261,7 @@ class CommonContext:
self.items_received = [] self.items_received = []
self.locations_info = {} self.locations_info = {}
self.server_version = Version(0, 0, 0) self.server_version = Version(0, 0, 0)
self.generator_version = Version(0, 0, 0)
self.server = None self.server = None
self.server_task = None self.server_task = None
self.hint_cost = None self.hint_cost = None
@ -646,11 +648,16 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
logger.info('Room Information:') logger.info('Room Information:')
logger.info('--------------------------------') logger.info('--------------------------------')
version = args["version"] version = args["version"]
ctx.server_version = tuple(version) ctx.server_version = Version(*version)
version = ".".join(str(item) for item in version)
logger.info(f'Server protocol version: {version}') if "generator_version" in args:
logger.info("Server protocol tags: " + ", ".join(args["tags"])) ctx.generator_version = Version(*args["generator_version"])
logger.info(f'Server protocol version: {ctx.server_version.as_simple_string()}, '
f'generator version: {ctx.generator_version.as_simple_string()}, '
f'tags: {", ".join(args["tags"])}')
else:
logger.info(f'Server protocol version: {ctx.server_version.as_simple_string()}, '
f'tags: {", ".join(args["tags"])}')
if args['password']: if args['password']:
logger.info('Password required') logger.info('Password required')
ctx.update_permissions(args.get("permissions", {})) ctx.update_permissions(args.get("permissions", {}))

View File

@ -3,9 +3,6 @@ from __future__ import annotations
import argparse import argparse
import asyncio import asyncio
import copy import copy
import functools
import logging
import zlib
import collections import collections
import datetime import datetime
import functools import functools
@ -162,7 +159,7 @@ class Context:
read_data: typing.Dict[str, object] read_data: typing.Dict[str, object]
stored_data_notification_clients: typing.Dict[str, typing.Set[Client]] stored_data_notification_clients: typing.Dict[str, typing.Set[Client]]
slot_info: typing.Dict[int, NetworkSlot] slot_info: typing.Dict[int, NetworkSlot]
generator_version = Version(0, 0, 0)
checksums: typing.Dict[str, str] checksums: typing.Dict[str, str]
item_names: typing.Dict[int, str] = Utils.KeyedDefaultDict(lambda code: f'Unknown item (ID:{code})') 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]]] item_name_groups: typing.Dict[str, typing.Dict[str, typing.Set[str]]]
@ -226,7 +223,7 @@ class Context:
self.save_dirty = False self.save_dirty = False
self.tags = ['AP'] self.tags = ['AP']
self.games: typing.Dict[int, str] = {} self.games: typing.Dict[int, str] = {}
self.minimum_client_versions: typing.Dict[int, Utils.Version] = {} self.minimum_client_versions: typing.Dict[int, Version] = {}
self.seed_name = "" self.seed_name = ""
self.groups = {} self.groups = {}
self.group_collected: typing.Dict[int, typing.Set[int]] = {} self.group_collected: typing.Dict[int, typing.Set[int]] = {}
@ -384,15 +381,17 @@ class Context:
def _load(self, decoded_obj: dict, game_data_packages: typing.Dict[str, typing.Any], def _load(self, decoded_obj: dict, game_data_packages: typing.Dict[str, typing.Any],
use_embedded_server_options: bool): use_embedded_server_options: bool):
self.read_data = {} self.read_data = {}
mdata_ver = decoded_obj["minimum_versions"]["server"] mdata_ver = decoded_obj["minimum_versions"]["server"]
if mdata_ver > Utils.version_tuple: if mdata_ver > version_tuple:
raise RuntimeError(f"Supplied Multidata (.archipelago) requires a server of at least version {mdata_ver}," raise RuntimeError(f"Supplied Multidata (.archipelago) requires a server of at least version {mdata_ver},"
f"however this server is of version {Utils.version_tuple}") f"however this server is of version {version_tuple}")
self.generator_version = Version(*decoded_obj["version"])
clients_ver = decoded_obj["minimum_versions"].get("clients", {}) clients_ver = decoded_obj["minimum_versions"].get("clients", {})
self.minimum_client_versions = {} self.minimum_client_versions = {}
for player, version in clients_ver.items(): for player, version in clients_ver.items():
self.minimum_client_versions[player] = max(Utils.Version(*version), min_client_version) self.minimum_client_versions[player] = max(Version(*version), min_client_version)
self.slot_info = decoded_obj["slot_info"] self.slot_info = decoded_obj["slot_info"]
self.games = {slot: slot_info.game for slot, slot_info in self.slot_info.items()} self.games = {slot: slot_info.game for slot, slot_info in self.slot_info.items()}
@ -758,7 +757,8 @@ async def on_client_connected(ctx: Context, client: Client):
# tags are for additional features in the communication. # tags are for additional features in the communication.
# Name them by feature or fork, as you feel is appropriate. # Name them by feature or fork, as you feel is appropriate.
'tags': ctx.tags, 'tags': ctx.tags,
'version': Utils.version_tuple, 'version': version_tuple,
'generator_version': ctx.generator_version,
'permissions': get_permissions(ctx), 'permissions': get_permissions(ctx),
'hint_cost': ctx.hint_cost, 'hint_cost': ctx.hint_cost,
'location_check_points': ctx.location_check_points, 'location_check_points': ctx.location_check_points,

View File

@ -38,6 +38,9 @@ class Version(typing.NamedTuple):
minor: int minor: int
build: int build: int
def as_simple_string(self) -> str:
return ".".join(str(item) for item in self)
__version__ = "0.4.1" __version__ = "0.4.1"
version_tuple = tuplize_version(__version__) version_tuple = tuplize_version(__version__)

View File

@ -67,6 +67,7 @@ Sent to clients when they connect to an Archipelago server.
| Name | Type | Notes | | Name | Type | Notes |
|-----------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-----------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| version | [NetworkVersion](#NetworkVersion) | Object denoting the version of Archipelago which the server is running. | | version | [NetworkVersion](#NetworkVersion) | Object denoting the version of Archipelago which the server is running. |
| generator_version | [NetworkVersion](#NetworkVersion) | Object denoting the version of Archipelago which generated the multiworld. |
| tags | list\[str\] | Denotes special features or capabilities that the sender is capable of. Example: `WebHost` | | tags | list\[str\] | Denotes special features or capabilities that the sender is capable of. Example: `WebHost` |
| password | bool | Denoted whether a password is required to join this room. | | password | bool | Denoted whether a password is required to join this room. |
| permissions | dict\[str, [Permission](#Permission)\[int\]\] | Mapping of permission name to [Permission](#Permission), keys are: "release", "collect" and "remaining". | | permissions | dict\[str, [Permission](#Permission)\[int\]\] | Mapping of permission name to [Permission](#Permission), keys are: "release", "collect" and "remaining". |