diff --git a/astrbot/core/star/star_tools.py b/astrbot/core/star/star_tools.py index fe5563b7dd..58a6137b20 100644 --- a/astrbot/core/star/star_tools.py +++ b/astrbot/core/star/star_tools.py @@ -18,6 +18,7 @@ """ import inspect +import logging import os import uuid from collections.abc import Awaitable, Callable @@ -39,6 +40,47 @@ from astrbot.core.utils.astrbot_path import get_astrbot_data_path from astrbot.core.utils.io import ensure_dir +logger = logging.getLogger("astrbot") + + +def _resolve_plugin_from_star_map(module, star_map): + return star_map.get(module.__name__) + + +def _resolve_plugin_from_prefix(module, star_map): + if "." not in module.__name__: + return None + caller_name = module.__name__ + # Prefer main modules or shorter paths deterministically + sorted_keys = sorted( + star_map.keys(), key=lambda k: (not k.endswith(".main"), len(k)) + ) + for mod_name in sorted_keys: + mod_package = mod_name.rpartition(".")[0] if "." in mod_name else mod_name + if caller_name == mod_package or caller_name.startswith(mod_package + "."): + return star_map[mod_name] + return None + + +def _resolve_plugin_from_path(module): + if not (hasattr(module, "__file__") and module.__file__): + return None + try: + from astrbot.core.utils.astrbot_path import get_astrbot_plugin_path + + plugin_root = Path(get_astrbot_plugin_path()).resolve() + module_path = Path(module.__file__).resolve() + return module_path.relative_to(plugin_root).parts[0] + except Exception: + return None + + +def _fallback_plugin_name(module): + logger.warning( + f"无法获取模块 {module.__name__} 的元数据信息,已安全回退到 'unknown_plugin'" + ) + return "unknown_plugin" + class StarTools: """提供给插件使用的便捷工具函数集合 @@ -291,15 +333,16 @@ def get_data_dir(cls, plugin_name: str | None = None) -> Path: if not module: raise RuntimeError("无法获取调用者模块信息") - metadata = star_map.get(module.__name__, None) + metadata = _resolve_plugin_from_star_map( + module, star_map + ) or _resolve_plugin_from_prefix(module, star_map) - if not metadata: - raise RuntimeError(f"无法获取模块 {module.__name__} 的元数据信息") - - plugin_name = metadata.name - - if not plugin_name: - raise ValueError("无法获取插件名称") + if metadata: + plugin_name = metadata.name + else: + plugin_name = _resolve_plugin_from_path( + module + ) or _fallback_plugin_name(module) data_dir = Path( os.path.join(get_astrbot_data_path(), "plugin_data", plugin_name),