from __future__ import annotations import os from typing import Any UNITY_EDITOR_PREFS_REG_PATH = r"Software\Unity Technologies\Unity Editor 5.x" UNITY_OSS_PREF_KEYS = { "access_key_id": "OssDownload_AccessKeyId", "access_key_secret": "OssDownload_AccessKeySecret", "endpoint": "OssDownload_Endpoint", "bucket": "OssDownload_Bucket", } ENV_OSS_KEYS = { "access_key_id": ( "TH1_OSS_ACCESS_KEY_ID", "OSS_ACCESS_KEY_ID", "ALIYUN_ACCESS_KEY_ID", "ALIBABA_CLOUD_ACCESS_KEY_ID", ), "access_key_secret": ( "TH1_OSS_ACCESS_KEY_SECRET", "OSS_ACCESS_KEY_SECRET", "ALIYUN_ACCESS_KEY_SECRET", "ALIBABA_CLOUD_ACCESS_KEY_SECRET", ), "endpoint": ("TH1_OSS_ENDPOINT", "OSS_ENDPOINT"), "bucket": ("TH1_OSS_BUCKET", "OSS_BUCKET"), } def _clean_string(value: str) -> str: return value.replace("\x00", "").strip() def _decode_editor_prefs_value(value: Any) -> str: if isinstance(value, bytes): raw = value.split(b"\x00", 1)[0] for encoding in ("utf-8", "mbcs", "latin-1"): try: return _clean_string(raw.decode(encoding)) except Exception: pass return "" if isinstance(value, str): return _clean_string(value) return "" def _read_windows_unity_pref(pref_key: str) -> str: try: import winreg except Exception: return "" try: with winreg.OpenKey(winreg.HKEY_CURRENT_USER, UNITY_EDITOR_PREFS_REG_PATH) as key: index = 0 while True: try: name, value, _value_type = winreg.EnumValue(key, index) except OSError: break index += 1 if name == pref_key or name.startswith(f"{pref_key}_h"): decoded = _decode_editor_prefs_value(value) if decoded: return decoded except OSError: return "" return "" def load_unity_oss_editor_prefs() -> dict[str, str]: config: dict[str, str] = {} for field, pref_key in UNITY_OSS_PREF_KEYS.items(): value = _read_windows_unity_pref(pref_key) if value: config[field] = value return config def load_env_oss_config() -> dict[str, str]: config: dict[str, str] = {} for field, env_names in ENV_OSS_KEYS.items(): for env_name in env_names: value = os.environ.get(env_name, "").strip() if value: config[field] = value break return config def merge_default_oss_config(config: dict[str, Any]) -> dict[str, Any]: merged = dict(config) merged.update(load_unity_oss_editor_prefs()) merged.update(load_env_oss_config()) return merged def merge_local_oss_config(config: dict[str, Any], local_config: dict[str, Any]) -> dict[str, Any]: merged = dict(config) for key, value in local_config.items(): if key in UNITY_OSS_PREF_KEYS and isinstance(value, str) and not value.strip(): continue merged[key] = value return merged