fix: 修复 _pubg_lookup_tool 误传 AiocqhttpMessageEvent 导致 TypeError 崩溃

三层防御:
1. _pubg_lookup_tool 检测 player_name 类型,非 str 时从 AstrMessageEvent 恢复
2. _fetch_all 增加 player_name/platform 类型断言和自动转换
3. _api_request 参数清洗,过滤非 str/int/float 的值

v1.4.2
This commit is contained in:
sakuradairong
2026-05-18 16:27:21 +08:00
parent 26ca2ca6f7
commit 0acd244cb8
3 changed files with 47 additions and 3 deletions

View File

@@ -1,5 +1,15 @@
# CHANGELOG
## 1.4.2 (2026-05-18)
### 修复
- **崩溃修复**`_pubg_lookup_tool` 在 LLM Function Calling 模式下,`player_name` 被错误绑定为 `AiocqhttpMessageEvent` 对象,导致 `_api_request` → aiohttp/yarl 拼接 URL 参数时抛出 `TypeError: Invalid variable type`
### 变更
- `_pubg_lookup_tool`:增加 `player_name` 非字符串类型检测与事件对象恢复逻辑
- `_fetch_all`:增加 `player_name`/`platform` 类型防御和自动转换
- `_api_request`:增加 `params` 参数清洗,自动过滤非法类型值
## 1.4.1 (2026-05-17)
### 修复

38
main.py
View File

@@ -410,6 +410,12 @@ async def _api_request(
retry: int = 0,
request_timeout: int = 10,
) -> dict:
# 参数清洗:仅保留 str / int / float 类型的值,过滤 event 等非法对象
if params is not None:
params = {
k: v for k, v in params.items()
if isinstance(v, (str, int, float))
}
for attempt in range(retry + 1):
try:
async with session.get(
@@ -447,7 +453,7 @@ async def _api_request(
"astrbot_plugin_pubg",
"sakuradairong",
"PUBG 玩家战绩查询插件",
"1.4.1",
"1.4.2",
"https://github.com/sakuradairong/astrbot_plugin_pubg",
)
class PubgPlugin(Star):
@@ -547,8 +553,30 @@ class PubgPlugin(Star):
except Exception:
pass
async def _pubg_lookup_tool(self, event, player_name: str, platform: str = "steam") -> str:
async def _pubg_lookup_tool(self, event, player_name: str = "", platform: str = "steam") -> str:
"""Agent 可调用的 PUBG 查询工具函数。"""
# === 参数防御:确保 player_name 是纯字符串,而非 event 对象 ===
if not isinstance(player_name, str):
logger.warning(f"[pubg_plugin] _pubg_lookup_tool: player_name 类型异常 ({type(player_name).__name__}), 尝试修复")
if isinstance(player_name, AstrMessageEvent):
# event 被当作 player_name 传入,尝试从消息中提取玩家名
raw = player_name.message_str.strip()
parts = raw.split()
# 格式可能为 "/pubg <name>"、"查询 <name>" 或直接 "<name>"
if len(parts) >= 2 and parts[0] in ("/pubg", "pubg", "查ID", "查询"):
player_name = parts[1]
elif len(parts) >= 1:
player_name = parts[0]
else:
return "请提供玩家昵称。用法: /pubg <玩家名> [平台]"
else:
player_name = str(player_name)
# 确保 platform 是字符串
if not isinstance(platform, str):
platform = str(platform) if isinstance(platform, (int, float)) else "steam"
# 校验 player_name 非空
if not player_name.strip():
return "玩家昵称不能为空。用法: /pubg <玩家名> [平台]"
api_key = self._get_api_key()
if not api_key:
return "未配置 PUBG API Key请在插件配置中填写 api_key。"
@@ -559,6 +587,12 @@ class PubgPlugin(Star):
return str(e)
async def _fetch_all(self, player_name: str, platform: str, api_key: str):
# 参数防御:确保 player_name 和 platform 是字符串
if not isinstance(player_name, str):
logger.warning(f"[pubg_plugin] _fetch_all: player_name 类型异常 ({type(player_name).__name__}), 强制转换")
player_name = str(player_name)
if not isinstance(platform, str):
platform = str(platform)
headers = {
"Authorization": f"Bearer {api_key}",
"Accept": "application/vnd.api+json",

View File

@@ -1,6 +1,6 @@
name: astrbot_plugin_pubg
display_name: PUBG 战绩查询
desc: PUBG 玩家终身战绩与最近对局查询插件
version: 1.4.1
version: 1.4.2
author: sakuradairong
repo: https://github.com/sakuradairong/astrbot_plugin_pubg