尝试修复挑战系统中的用户名错误

This commit is contained in:
2025-11-13 00:23:33 +08:00
parent d0825f3f48
commit 7b84351b81
4 changed files with 86 additions and 13 deletions

View File

@@ -10,7 +10,7 @@ alwaysApply: true
语言设置:除非用户另有指示,所有常规交互响应都应该使用中文。然而,模式声明(例如\[MODE: RESEARCH\])和特定格式化输出(例如代码块、清单等)应保持英文,以确保格式一致性。 语言设置:除非用户另有指示,所有常规交互响应都应该使用中文。然而,模式声明(例如\[MODE: RESEARCH\])和特定格式化输出(例如代码块、清单等)应保持英文,以确保格式一致性。
**工具调用: 你应该使用工具调用而不是通过命令行编辑文件** **工具调用: 你应该使用edit_file而不是通过命令行编辑文件**
你必须完全理解这个项目, 并明白文件夹PWF里的文件你没有权力更改 你必须完全理解这个项目, 并明白文件夹PWF里的文件你没有权力更改

View File

@@ -0,0 +1,34 @@
# 背景
文件名: 2025-11-12_4_battle-username-target.md
创建于: 2025-11-13_00:10:51
创建者: LIUBAI095
主分支: main
任务分支: 未创建
Yolo模式: Off
# 任务描述
挑战插件需支持通过用户ID或用户名发起PVP挑战。
# 项目概览
WPSCombatSystem 负责玩家战斗流程当前挑战命令仅接受数值型用户ID用户基础资料由 WPSConfigAPI 管理。
# 分析
- `WPSCombatBattle._handle_challenge` 在解析目标参数时仅执行 `int()` 转换,失败即判定格式错误。
- `combat_service.create_pvp_challenge` 函数签名也要求目标ID为整数。
- `user_info` 表包含 `username` 字段,且其他插件存在根据用户名反查 `user_id` 的逻辑。
# 提议的解决方案
待定
# 当前执行步骤:"1. 创建任务文件"
# 任务进度
2025-11-13_00:19:55
- 已修改: Plugins/WPSCombatSystem/combat_plugin_battle.py
- 更改: 挑战命令支持按用户名优先解析并更新帮助信息
- 原因: 允许用户通过用户名或ID发起挑战
- 阻碍因素: 无
- 状态: 未确认
2025-11-13_00:21:27
- 已修改: Plugins/WPSCombatSystem/combat_plugin_battle.py Plugins/WPSConfigSystem.py
- 更改: 通过 Architecture 获取 WPSConfigAPI 实现用户名解析,新增接口并去除直接数据库访问
- 原因: 避免插件直接访问数据库,统一通过配置接口解析用户
- 阻碍因素: 无
- 状态: 未确认
# 最终审查

View File

@@ -4,9 +4,11 @@ from __future__ import annotations
from typing import Optional, Sequence from typing import Optional, Sequence
from PWF.Convention.Runtime.Architecture import Architecture
from PWF.Convention.Runtime.GlobalConfig import ConsoleFrontColor, ProjectConfig from PWF.Convention.Runtime.GlobalConfig import ConsoleFrontColor, ProjectConfig
from Plugins.WPSAPI import GuideEntry from Plugins.WPSAPI import GuideEntry
from Plugins.WPSConfigSystem import WPSConfigAPI
from .combat_plugin_base import WPSCombatBase from .combat_plugin_base import WPSCombatBase
@@ -23,7 +25,7 @@ class WPSCombatBattle(WPSCombatBase):
return ( return (
GuideEntry( GuideEntry(
title="挑战", title="挑战",
identifier="挑战 <目标用户ID>", identifier="挑战 <目标用户>",
description="向指定玩家发起 PVP 挑战。", description="向指定玩家发起 PVP 挑战。",
metadata={"别名": "challenge"}, metadata={"别名": "challenge"},
icon="⚔️", icon="⚔️",
@@ -103,7 +105,7 @@ class WPSCombatBattle(WPSCombatBase):
处理PVP命令 处理PVP命令
命令格式: 命令格式:
- 挑战 <目标用户ID> - 挑战 <目标用户>
- 接受挑战 <挑战ID> - 接受挑战 <挑战ID>
- 拒绝挑战 <挑战ID> - 拒绝挑战 <挑战ID>
- 战斗 <战斗ID> <技能名> - 战斗 <战斗ID> <技能名>
@@ -147,30 +149,28 @@ class WPSCombatBattle(WPSCombatBase):
"""处理挑战命令""" """处理挑战命令"""
if not args: if not args:
return await self.send_markdown_message( return await self.send_markdown_message(
"❌ 请指定目标用户ID\n用法:`挑战 <目标用户ID>`", "❌ 请指定目标用户\n用法:`挑战 <目标用户名|用户ID>`",
chat_id, chat_id,
user_id user_id
) )
target_identifier = args[0]
try: target_id, error_message = self._resolve_target_user(target_identifier)
target_id = int(args[0]) if error_message:
except ValueError: return await self.send_markdown_message(error_message, chat_id, user_id)
if target_id is None:
return await self.send_markdown_message( return await self.send_markdown_message(
"用户ID格式错误", "未找到目标用户请确认用户名或ID",
chat_id, chat_id,
user_id user_id
) )
if target_id == user_id: if target_id == user_id:
return await self.send_markdown_message( return await self.send_markdown_message(
"❌ 不能挑战自己", "❌ 不能挑战自己",
chat_id, chat_id,
user_id user_id
) )
service = self.service() service = self.service()
success, msg, challenge_id = service.create_pvp_challenge(user_id, target_id) success, msg, challenge_id = service.create_pvp_challenge(user_id, target_id)
return await self.send_markdown_message(msg, chat_id, user_id) return await self.send_markdown_message(msg, chat_id, user_id)
async def _handle_accept( async def _handle_accept(
@@ -291,7 +291,7 @@ class WPSCombatBattle(WPSCombatBase):
"""帮助信息""" """帮助信息"""
return """# ⚔️ PVP对战系统 return """# ⚔️ PVP对战系统
**命令格式:** **命令格式:**
- `挑战 <目标用户ID>`发起PVP挑战 - `挑战 <目标用户名|用户ID>`发起PVP挑战
- `接受挑战 <挑战ID>`:接受挑战 - `接受挑战 <挑战ID>`:接受挑战
- `拒绝挑战 <挑战ID>`:拒绝挑战 - `拒绝挑战 <挑战ID>`:拒绝挑战
- `战斗 <战斗ID> <技能名>`:执行战斗动作 - `战斗 <战斗ID> <技能名>`:执行战斗动作
@@ -305,11 +305,38 @@ class WPSCombatBattle(WPSCombatBase):
- 可随时投降 - 可随时投降
**示例:** **示例:**
- `挑战 玩家A`向用户名为玩家A的用户发起挑战
- `挑战 12345`向用户12345发起挑战 - `挑战 12345`向用户12345发起挑战
- `接受挑战 1`接受挑战ID为1的挑战 - `接受挑战 1`接受挑战ID为1的挑战
- `战斗 1 攻击`在战斗1中使用"攻击"技能 - `战斗 1 攻击`在战斗1中使用"攻击"技能
- `投降 1`在战斗1中投降 - `投降 1`在战斗1中投降
""" """
def _resolve_target_user(self, identifier: str) -> tuple[Optional[int], Optional[str]]:
text = identifier.strip()
if not text:
return None, "❌ 请指定目标用户"
try:
config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI)
except Exception as exc:
logger.Log(
"Error",
f"{ConsoleFrontColor.RED}获取 WPSConfigAPI 实例失败: {exc}{ConsoleFrontColor.RESET}",
)
return None, "❌ 系统繁忙,请稍后重试"
try:
resolved_id = config_api.find_user_id_by_username(text)
if resolved_id is not None:
return resolved_id, None
except Exception as exc:
logger.Log(
"Error",
f"{ConsoleFrontColor.RED}解析用户名 {text} 失败: {exc}{ConsoleFrontColor.RESET}",
)
return None, "❌ 系统繁忙,请稍后重试"
if text.isdigit():
return int(text), None
return None, None
__all__ = ["WPSCombatBattle"] __all__ = ["WPSCombatBattle"]

View File

@@ -202,6 +202,18 @@ class WPSConfigAPI(WPSAPI):
value = record.get("username") value = record.get("username")
return str(value) if value else f"user_{user_id}" return str(value) if value else f"user_{user_id}"
def find_user_id_by_username(self, username: str) -> Optional[int]:
text = (username or "").strip()
if not text:
return None
cursor = get_db().conn.cursor()
cursor.execute(
"SELECT user_id FROM user_info WHERE username = ? COLLATE NOCASE",
(text,),
)
row = cursor.fetchone()
return int(row["user_id"]) if row else None
def get_user_url(self, user_id: int) -> Optional[str]: def get_user_url(self, user_id: int) -> Optional[str]:
record = self._get_user_record(user_id) record = self._get_user_record(user_id)
if not record: if not record: