Ctrl K
ComunidadGuías…

src/webui/map_domain/backgrounds.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Apply saved background choices and expose picker options."""

from __future__ import annotations

from collections.abc import Callable
from typing import Any

from src.webui.map_presets import builtin_map_options, builtin_map_preset_by_asset

from .presentation import public_map_definition


def apply_background_selection(
    game_key: str,
    automatic_map: dict[str, Any] | None,
    selection: dict[str, str],
    upload_exists: Callable[[str], bool],
) -> dict[str, Any] | None:
    kind = selection["kind"]
    if kind in {"auto", "plugin"}:
        return automatic_map
    if kind == "none":
        return _map_with_background(automatic_map, None, fallback_name="场景地图")
    if kind == "builtin":
        preset = builtin_map_preset_by_asset(selection.get("id", ""))
        if not preset:
            return automatic_map
        return _map_with_background(
            automatic_map,
            preset["background"],
            fallback=preset,
            fallback_name=str(preset["name"]),
        )
    if kind in {"upload", "generated"}:
        asset_id = selection.get("asset_id", "")
        if not upload_exists(asset_id):
            return automatic_map
        generated = kind == "generated"
        background = {
            "id": asset_id,
            "ref": f"{kind}:map-background:{asset_id}",
            "name": "生成地图背景" if generated else "自定义地图背景",
            "url": f"/api/games/{game_key}/map-background-asset/{asset_id}",
        }
        return _map_with_background(
            automatic_map,
            background,
            fallback_name="生成地图背景" if generated else "自定义地图背景",
        )
    return automatic_map


def background_options(
    assets: dict[str, list[dict[str, Any]]],
    selection: dict[str, str],
) -> list[dict[str, Any]]:
    options: list[dict[str, Any]] = [
        {"id": "auto", "kind": "auto", "name": "自动推荐"},
        {"id": "none", "kind": "none", "name": "关闭背景"},
    ]
    options.extend({
        "id": f"builtin:{item['id']}",
        "kind": "builtin",
        "name": item["name"],
        "description": item["description"],
        "url": item["url"],
        "selection": {"kind": "builtin", "id": item["id"]},
    } for item in builtin_map_options())
    for definition in assets.get("maps", []):
        public = public_map_definition(definition, assets)
        if not public or not public.get("background"):
            continue
        options.append({
            "id": public["id"],
            "kind": "plugin",
            "name": public["name"],
            "description": public.get("description", ""),
            "plugin_name": public.get("plugin_name", ""),
            "url": public["background"].get("url", ""),
            "selection": {"kind": "plugin", "map_id": public["id"]},
        })
    if selection["kind"] in {"upload", "generated"}:
        kind = selection["kind"]
        options.append({
            "id": f"{kind}:{selection.get('asset_id', '')}",
            "kind": kind,
            "name": "当前生成背景" if kind == "generated" else "当前上传背景",
            "selection": dict(selection),
        })
    return options


def _map_with_background(
    base: dict[str, Any] | None,
    background: dict[str, Any] | None,
    *,
    fallback: dict[str, Any] | None = None,
    fallback_name: str,
) -> dict[str, Any]:
    if base and base.get("plugin_id"):
        merged = dict(base)
        merged["background"] = background
        return merged
    if fallback:
        merged = dict(fallback)
        merged["background"] = background
        return merged
    return {
        "id": "builtin:map:custom" if background else "builtin:map:none",
        "source_id": "custom" if background else "none",
        "name": fallback_name,
        "description": "",
        "mode": "graph",
        "plugin_id": "",
        "plugin_name": "DiceFrame",
        "background": background,
        "default_view": {"x": 0, "y": 0, "zoom": 1},
    }