From fdfab9f1e46c67985e9763e556d86a825b6df73e Mon Sep 17 00:00:00 2001 From: Oscar Date: Mon, 29 Dec 2025 17:43:52 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(#4188):=20=E4=BB=8E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E6=8F=92=E4=BB=B6=E6=97=B6=E5=85=88=E7=BB=88?= =?UTF-8?q?=E6=AD=A2=E5=B9=B6=E8=A7=A3=E7=BB=91=E5=B7=B2=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E5=90=8C=E5=90=8D=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/star_manager.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index 34ec24015..3d429ae0f 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -944,6 +944,25 @@ async def install_plugin_from_file(self, zip_file_path: str): dir_name = os.path.basename(zip_file_path).replace(".zip", "") dir_name = dir_name.removesuffix("-master").removesuffix("-main").lower() desti_dir = os.path.join(self.plugin_store_path, dir_name) + + # 检查是否已安装同名插件,先终止旧插件 + existing_plugin = None + for star in self.context.get_all_stars(): + if star.root_dir_name == dir_name: + existing_plugin = star + break + + if existing_plugin: + logger.info(f"检测到插件 {existing_plugin.name} 已安装,正在终止旧插件...") + try: + await self._terminate_plugin(existing_plugin) + except Exception: + logger.warning(traceback.format_exc()) + if existing_plugin.name and existing_plugin.module_path: + await self._unbind_plugin( + existing_plugin.name, existing_plugin.module_path + ) + self.updator.unzip_file(zip_file_path, desti_dir) # remove the zip From 6ee5729b382a261b876d2920acbcbc97219eaefb Mon Sep 17 00:00:00 2001 From: Oscar Date: Tue, 30 Dec 2025 13:28:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(star):=20=E4=BC=98=E5=8C=96=E4=BB=8E?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=AE=89=E8=A3=85=E6=8F=92=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=90=8C=E5=90=8D=E5=86=B2=E7=AA=81=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=BE=B9=E7=BC=98=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/star_manager.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index 3d429ae0f..cf3ab0698 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -945,7 +945,7 @@ async def install_plugin_from_file(self, zip_file_path: str): dir_name = dir_name.removesuffix("-master").removesuffix("-main").lower() desti_dir = os.path.join(self.plugin_store_path, dir_name) - # 检查是否已安装同名插件,先终止旧插件 + # 第一步:检查是否已安装同目录名的插件,先终止旧插件 existing_plugin = None for star in self.context.get_all_stars(): if star.root_dir_name == dir_name: @@ -965,6 +965,28 @@ async def install_plugin_from_file(self, zip_file_path: str): self.updator.unzip_file(zip_file_path, desti_dir) + # 第二步:解压后,读取新插件的 metadata.yaml,检查是否存在同名但不同目录的插件 + try: + new_metadata = self._load_plugin_metadata(desti_dir) + if new_metadata and new_metadata.name: + for star in self.context.get_all_stars(): + if ( + star.name == new_metadata.name + and star.root_dir_name != dir_name + ): + logger.warning( + f"检测到同名插件 {star.name} 存在于不同目录 {star.root_dir_name},正在终止..." + ) + try: + await self._terminate_plugin(star) + except Exception: + logger.warning(traceback.format_exc()) + if star.name and star.module_path: + await self._unbind_plugin(star.name, star.module_path) + break # 只处理第一个匹配的 + except Exception as e: + logger.debug(f"读取新插件 metadata.yaml 失败,跳过同名检查: {e!s}") + # remove the zip try: os.remove(zip_file_path)