Core: apworld manifest launcher component (#5340)

adds a launcher component that builds all apworlds on top of #4516
---------

Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com>
Co-authored-by: qwint <qwint.42@gmail.com>
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
This commit is contained in:
Fabian Dill
2025-09-24 23:25:46 +02:00
committed by GitHub
parent 4525bae879
commit 4ae87edf37

View File

@@ -5,7 +5,7 @@ import weakref
from enum import Enum, auto from enum import Enum, auto
from typing import Optional, Callable, List, Iterable, Tuple from typing import Optional, Callable, List, Iterable, Tuple
from Utils import local_path, open_filename from Utils import local_path, open_filename, is_frozen
class Type(Enum): class Type(Enum):
@@ -243,3 +243,39 @@ icon_paths = {
'icon': local_path('data', 'icon.png'), 'icon': local_path('data', 'icon.png'),
'discord': local_path('data', 'discord-mark-blue.png'), 'discord': local_path('data', 'discord-mark-blue.png'),
} }
if not is_frozen():
def _build_apworlds():
import json
import os
import zipfile
from worlds import AutoWorldRegister
from worlds.Files import APWorldContainer
apworlds_folder = os.path.join("build", "apworlds")
os.makedirs(apworlds_folder, exist_ok=True)
for worldname, worldtype in AutoWorldRegister.world_types.items():
file_name = os.path.split(os.path.dirname(worldtype.__file__))[1]
world_directory = os.path.join("worlds", file_name)
if os.path.isfile(os.path.join(world_directory, "archipelago.json")):
manifest = json.load(open(os.path.join(world_directory, "archipelago.json")))
else:
manifest = {}
zip_path = os.path.join(apworlds_folder, file_name + ".apworld")
apworld = APWorldContainer(str(zip_path))
apworld.game = worldtype.game
manifest.update(apworld.get_manifest())
apworld.manifest_path = f"{file_name}/archipelago.json"
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED,
compresslevel=9) as zf:
for path in pathlib.Path(world_directory).rglob("*.*"):
relative_path = os.path.join(*path.parts[path.parts.index("worlds") + 1:])
if "__MACOSX" in relative_path or ".DS_STORE" in relative_path or "__pycache__" in relative_path:
continue
if not relative_path.endswith("archipelago.json"):
zf.write(path, relative_path)
zf.writestr(apworld.manifest_path, json.dumps(manifest))
components.append(Component('Build apworlds', func=_build_apworlds, cli=True,))