diff --git a/src/ManualClient.py b/src/ManualClient.py index d11da85..f28e1e0 100644 --- a/src/ManualClient.py +++ b/src/ManualClient.py @@ -2,17 +2,18 @@ import asyncio import os import re +import json import sys import time import typing from typing import Any, Optional import requests -from worlds import AutoWorldRegister, network_data_package from worlds.LauncherComponents import icon_paths -import json import traceback - +import urllib +from typing import Any, Optional +from worlds import AutoWorldRegister, network_data_package import ModuleUpdate ModuleUpdate.update() @@ -895,7 +896,18 @@ def read_apmanual_file(apmanual_file): async def main(args): config_file = {} - if args.apmanual_file: + if args.apmanual_file and args.apmanual_file.startswith("archipelago://"): + url = urllib.parse.urlparse(args.apmanual_file) + args.connect = url.netloc + if url.username: + args.name = urllib.parse.unquote(url.username) + if url.password: + args.password = urllib.parse.unquote(url.password) + queries = urllib.parse.parse_qs(url.query) + if "game" in queries: + config_file['game'] = queries["game"][0] + + elif args.apmanual_file and os.path.exists(args.apmanual_file): config_file = read_apmanual_file(args.apmanual_file) ctx = ManualContext(args.connect, args.password, config_file.get("game"), config_file.get("player_name")) ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop") diff --git a/src/__init__.py b/src/__init__.py index 003b94b..aad5fb0 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -24,7 +24,7 @@ from BaseClasses import CollectionState, ItemClassification, Item from Options import PerGameCommonOptions -from worlds.AutoWorld import World +from worlds.AutoWorld import World, AutoWorldRegister from .hooks.World import \ hook_get_filler_item_name, before_create_regions, after_create_regions, \ @@ -557,9 +557,21 @@ class VersionedComponent(Component): def __init__(self, display_name: str, script_name: Optional[str] = None, func: Optional[Callable] = None, version: int = 0, file_identifier: Optional[Callable[[str], bool]] = None, icon: Optional[str] = None): super().__init__(display_name=display_name, script_name=script_name, func=func, component_type=Type.CLIENT, file_identifier=file_identifier, icon=icon) self.version = version + self.supports_uri = True + + @property + def game_name(self) -> list[str]: + return [name for name in AutoWorldRegister.world_types.keys() if name.startswith("Manual_")] + + @game_name.setter + def game_name(self, value: str): + # This needs to exist because the base class sets it to [] in the __init__ method + if value: + raise ValueError("Manual Client does not support setting game_name manually.") + def add_client_to_launcher() -> None: - version = 2025_08_12 # YYYYMMDD + version = 2025_11_19 # YYYYMMDD found = False if "manual" not in icon_paths: @@ -569,6 +581,11 @@ def add_client_to_launcher() -> None: for c in components: if c.display_name == "Manual Client": found = True + if not getattr(c, "supports_uri", False): + components.remove(c) + found = False + break + if getattr(c, "version", 0) < version: # We have a newer version of the Manual Client than the one the last apworld added c.version = version c.func = launch_client