diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3f975c..7851945 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
## 更新记录
+### version: 2.6:
+
+新增 **资历 角色名称 [服务器]** 指令,支持两轮对话选择资历总览或分类总览,并以图片形式展示角色资历点数完成进度。
+
+新增资历菜单与点数基础数据缓存,减少长期稳定接口的重复请求。
+
+调整功能帮助页分类,指令分组改为日常、官方、角色、职业、休闲、阵营、副本、活动、交易、杂项、排行、推送和避雷。
+
+调整指令触发词:**诛恶事件** 改为 **诛恶**,**排行** 改为 **名剑排行**。
+
### version: 2.5:
增加部分新指令,调整功能页面
@@ -58,4 +68,4 @@
### version: 1.0.0:
-大部分重要功能已经实现
\ No newline at end of file
+大部分重要功能已经实现
diff --git a/README.md b/README.md
index 65f413c..c035a19 100644
--- a/README.md
+++ b/README.md
@@ -2,24 +2,27 @@
基于 [AstrBot](https://docs.astrbot.app/) 框架开发的剑网三游戏数据查询插件。插件主要通过 JX3API、JX3BOX、茶馆等外部接口获取游戏数据,整理为文本消息、富媒体消息,或通过 `HTML + Jinja2` 模板渲染成图片后发送。
-当前插件以“查询型功能”为主,覆盖日常、奇遇、名剑、阵营、交易、职业、排行、副本、活动、名片、百战、推送和本地避雷等场景。部分功能需要配置 JX3API Token,少量职业/角色类接口还需要推栏 ticket。
+当前插件以“查询型功能”为主,覆盖日常、官方、角色、职业、休闲、阵营、副本、活动、交易、杂项、排行、推送和本地避雷等场景。部分功能需要配置 JX3API Token,少量职业/角色类接口还需要推栏 ticket。
## 功能概览
-插件内置 `功能` 指令,会以图片形式展示完整指令列表、参数说明和是否需要令牌。当前帮助页按 16 个功能分组维护,约 87 条指令。
+插件内置 `功能` 指令,会以图片形式展示完整指令列表、参数说明和是否需要令牌。当前帮助页按 13 个功能分组维护,约 88 条指令。
主要功能包括:
-- 日常与官方:日常、月历、名望、公告、维护、区服、开服、状态、技改。
-- 职业与角色:角色、阵眼、奇穴、技能、小药、宏、配装、资历排行、试炼排行。
-- 奇遇:角色奇遇、未做奇遇、奇遇统计、近期奇遇、奇遇汇总、奇遇攻略。
-- 名剑:战绩、名剑排行、名剑统计。
-- 阵营:沙盘、阵营拍卖、阵营事件、关隘首领、帮战记录、统战 YY。
-- 交易:金价、外观物价、交易行、贴吧物价。
-- 活动:扶摇、诛恶事件、本日赤兔、本周赤兔、刷马、的卢。
-- 其他:拜师、收徒、名片、百战、精耐、招募、掉落、解密、八卦、骗子查询。
-- 本地功能:避雷添加、查看、查询、修改、删除。
+- 日常功能:日常、月历、名望、诛恶。
+- 官方功能:公告、维护、技改、区服、开服、状态。
+- 角色功能:角色、资历、名片、所有名片、奇遇、未做奇遇、战绩、精耐。
+- 职业功能:小药、宏、配装、阵眼、奇穴、技能。
+- 休闲功能:烟花、拜师、收徒、随机名片、攻略、奇遇统计、近期奇遇、奇遇汇总。
+- 阵营功能:沙盘、阵营拍卖、阵营事件、关隘首领、帮战记录、统战 YY。
+- 副本功能:百战、招募、掉落、解密。
+- 活动功能:扶摇、本日赤兔、本周赤兔、刷马、的卢。
+- 交易功能:金价、物价、交易行、贴吧物价。
+- 杂项功能:科举、花价、装饰、器物、八卦、骗子、骚话。
+- 排行功能:名剑统计、名剑排行、资历排行、试炼排行和各类风云录榜单。
- 推送功能:开服推送、新闻推送、刷马推送、赤兔推送。
+- 避雷功能:避雷查看、添加、删除、修改、查询。
## 安装与依赖
@@ -43,7 +46,7 @@ pip install -r requirements.txt
- `apscheduler`:后台推送任务调度。
- `matplotlib`:部分图像/数据展示依赖。
-插件元信息在 `metadata.yaml` 中维护,要求 AstrBot 版本 `>=4.11.0`。
+插件元信息在 `metadata.yaml` 中维护,当前版本为 `v2.6`,要求 AstrBot 版本 `>=4.11.0`。
## 插件配置
@@ -166,9 +169,12 @@ pip install -r requirements.txt
```text
日常
+诛恶
+资历 飞翔大野猪
奇遇 飞翔大野猪
未做奇遇 飞翔大野猪 梦江南
战绩 飞翔大野猪 梦江南 33
+名剑排行 50 33
贴吧物价 狐金 5 梦江南
统战 梦江南
```
@@ -234,6 +240,7 @@ astrbot_plugin_jx3/
- `image_msg()`:直接发送图片 URL 或图片数据。
- `plain_chain()`:发送文本 + 图片等富媒体消息链。
- `handler_plain_image_msg()`:先发文本,再发图片,适用于部分组合型功能。
+- `handler_zili_msg()`:资历查询专用两轮会话,先发送 `0-18` 分类菜单,再按用户选择渲染资历进度图片。
所有可选服务器参数都会通过 `serverdefault()` 补齐默认服务器。
@@ -332,10 +339,28 @@ html_renderer.render_custom_template()
- 避雷记录。
- 推送任务状态缓存。
+- 资历菜单与资历点数基础数据缓存,默认缓存 30 天,接口失败时可使用旧缓存兜底。
`core/sqlite.py` 封装了异步增删改查;`core/bilei_data.py` 基于该封装实现避雷数据管理。
-### 8. 后台推送
+### 8. 资历查询
+
+`资历 角色名称 [服务器]` 是 2.6 新增的两轮对话功能。
+
+第一轮会发送固定分类菜单,用户输入 `0-18` 后进入第二轮:
+
+- `0`:展示角色资历总览,并列出 18 个大类的完成进度。
+- `1-18`:展示对应大类总览,并列出该大类下所有子类的完成进度。
+
+实现流程:
+
+1. 通过角色信息接口 `jx3_jueshexinxi` 获取角色 `globalId`。
+2. 用 `globalId` 请求 JX3BOX 角色资历接口,获取已完成资历 ID 列表。
+3. 从资历菜单接口和资历点数接口读取基础数据,并缓存到本地 SQLite。
+4. 展开菜单中单个 ID 和数组 ID,按资历点数计算 `已完成点数 / 总点数` 与百分比。
+5. 使用 `templates/zili.html` 渲染进度条图片。
+
+### 9. 后台推送
`core/async_task.py` 使用 APScheduler 实现轮询推送。
diff --git a/core/jx3_data.py b/core/jx3_data.py
index 5b19866..117af7d 100644
--- a/core/jx3_data.py
+++ b/core/jx3_data.py
@@ -1,5 +1,5 @@
import json
-from datetime import datetime
+from datetime import datetime, timedelta
from typing import Dict, Any, Optional, List, Union
from collections import defaultdict
@@ -34,8 +34,32 @@ TONG_RANK_NAMES = {
"本周浩气五十强",
}
+ACHIEVEMENT_CHOICES = [
+ (0, None, "资历总览"),
+ (1, "1", "杂闻总览"),
+ (2, "2", "武学总览"),
+ (3, "3", "修为总览"),
+ (4, "4", "装备总览"),
+ (5, "5", "技艺总览"),
+ (6, "6", "阅读总览"),
+ (7, "7", "任务总览"),
+ (8, "8", "足迹总览"),
+ (9, "9", "战斗总览"),
+ (10, "10", "声望总览"),
+ (11, "11", "秘境总览"),
+ (12, "12", "帮会总览"),
+ (13, "13", "阵营总览"),
+ (14, "15", "节日总览"),
+ (15, "16", "活动总览"),
+ (16, "17", "风雨江湖路总览"),
+ (17, "40", "家园总览"),
+ (18, "41", "剑侠录总览"),
+]
+
+ACHIEVEMENT_CHOICE_MAP = {index: (menu_id, title) for index, menu_id, title in ACHIEVEMENT_CHOICES}
+
class JX3Service:
- def __init__(self, api_data_path: str, config: AstrBotConfig, sqlite: AsyncSQLiteDB):
+ def __init__(self, api_data_path: str, config: AstrBotConfig, sqlite: AsyncSQLiteDB, cache_sqlite: Optional[AsyncSQLiteDB] = None):
# 加载API配置文件
try:
with open(api_data_path, 'r', encoding='utf-8') as f:
@@ -49,6 +73,7 @@ class JX3Service:
self._config = config
# 引用sqlite
self._sql_db = sqlite
+ self._cache_db = cache_sqlite or sqlite
# 获取配置中的 Token
self.token = self._config.get("jx3api_token", "")
@@ -2386,6 +2411,244 @@ class JX3Service:
return return_data
+ async def _load_achievement_cache(self, key: str) -> tuple[Optional[Dict[str, Any]], bool]:
+ """读取资历基础数据缓存,返回数据和是否已过期"""
+ try:
+ row = await self._cache_db.select_one("achievement_cache", "key=?", (key,))
+ except Exception as e:
+ logger.error(f"读取资历缓存失败: {e}")
+ return None, True
+
+ if not row:
+ return None, True
+
+ try:
+ payload = json.loads(row.get("content", "{}"))
+ updated_at = datetime.strptime(row.get("updated_at", ""), "%Y-%m-%d %H:%M:%S")
+ expired = datetime.now() - updated_at > timedelta(days=30)
+ return payload, expired
+ except Exception as e:
+ logger.error(f"解析资历缓存失败: {e}")
+ return None, True
+
+
+ async def _save_achievement_cache(self, key: str, payload: Dict[str, Any]):
+ """写入资历基础数据缓存"""
+ try:
+ await self._cache_db.execute(
+ """
+ INSERT INTO achievement_cache (key, content, updated_at)
+ VALUES (?, ?, ?)
+ ON CONFLICT(key) DO UPDATE SET
+ content=excluded.content,
+ updated_at=excluded.updated_at
+ """,
+ (
+ key,
+ json.dumps(payload, ensure_ascii=False),
+ datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ ),
+ )
+ except Exception as e:
+ logger.error(f"写入资历缓存失败: {e}")
+
+
+ async def _get_achievement_base_data(self, cache_key: str, config_key: str) -> Optional[Dict[str, Any]]:
+ """获取资历菜单或点数数据,优先使用未过期缓存"""
+ cached, expired = await self._load_achievement_cache(cache_key)
+ if cached and not expired:
+ return cached
+
+ data: Optional[Dict[str, Any]] = await self._base_request(config_key, "GET")
+ if data and isinstance(data, dict):
+ await self._save_achievement_cache(cache_key, data)
+ return data
+
+ if cached:
+ logger.warning(f"资历基础数据接口失败,使用旧缓存: {cache_key}")
+ return cached
+
+ return None
+
+
+ def _flatten_achievement_ids(self, values: Any) -> list[int]:
+ """展开菜单中的单个资历 ID 和数组资历 ID"""
+ result = []
+
+ if isinstance(values, list):
+ for item in values:
+ result.extend(self._flatten_achievement_ids(item))
+ return result
+
+ try:
+ result.append(int(values))
+ except (TypeError, ValueError):
+ pass
+
+ return result
+
+
+ def _category_achievement_ids(self, category: Dict[str, Any]) -> list[int]:
+ """提取分类及其子分类包含的资历 ID"""
+ ids = self._flatten_achievement_ids(category.get("achievements", []))
+ for child in category.get("children", []) or []:
+ if isinstance(child, dict):
+ ids.extend(self._flatten_achievement_ids(child.get("achievements", [])))
+ return ids
+
+
+ def _build_achievement_progress(
+ self,
+ name: str,
+ achievement_ids: list[int],
+ point_map: Dict[str, Any],
+ completed_ids: set[int],
+ ) -> Dict[str, Any]:
+ """按资历点数计算完成进度"""
+ unique_ids = set(achievement_ids)
+ total_points = 0
+ completed_points = 0
+ completed_count = 0
+
+ for achievement_id in unique_ids:
+ try:
+ point = int(point_map.get(str(achievement_id), 0) or 0)
+ except (TypeError, ValueError):
+ point = 0
+
+ total_points += point
+ if achievement_id in completed_ids:
+ completed_count += 1
+ completed_points += point
+
+ percent = round(completed_points / total_points * 100, 2) if total_points else 0
+
+ return {
+ "name": name,
+ "total_points": total_points,
+ "completed_points": completed_points,
+ "percent": percent,
+ "percent_text": f"{percent:.2f}%",
+ "achievement_count": len(unique_ids),
+ "completed_count": completed_count,
+ }
+
+
+ async def zili(self, name: str, server: str, choice: int) -> Dict[str, Any]:
+ """角色资历"""
+ return_data = self._init_return_data()
+
+ if choice not in ACHIEVEMENT_CHOICE_MAP:
+ return_data["msg"] = "无效序号,结束会话"
+ return return_data
+
+ role_params = {"server": server, "name": name, "token": self.token}
+ role_data: Optional[Dict[str, Any]] = await self._base_request(
+ "jx3_jueshexinxi", "GET", params=role_params
+ )
+ if not role_data or not isinstance(role_data, dict):
+ return_data["msg"] = "未查询到角色"
+ return return_data
+
+ global_id = role_data.get("globalId")
+ if not global_id:
+ return_data["msg"] = "无法获取角色全区 ID"
+ return return_data
+
+ achievement_data = await self._api.get(
+ "https://next2.jx3box.com/api/next2/user-achievements",
+ params={"jx3id": global_id},
+ out_key="data",
+ )
+ if not achievement_data or not isinstance(achievement_data, dict):
+ return_data["msg"] = "未查询到资历数据"
+ return return_data
+
+ completed_ids = set()
+ achievements = achievement_data.get("achievements") or ""
+ if isinstance(achievements, str):
+ for item in achievements.split(","):
+ try:
+ completed_ids.add(int(item.strip()))
+ except ValueError:
+ continue
+ elif isinstance(achievements, list):
+ completed_ids = set(self._flatten_achievement_ids(achievements))
+
+ menu_payload = await self._get_achievement_base_data(
+ "achievement_menus",
+ "jx3box_achievement_menus",
+ )
+ point_payload = await self._get_achievement_base_data(
+ "achievement_points",
+ "jx3box_achievement_points",
+ )
+ if not menu_payload or not point_payload:
+ return_data["msg"] = "基础资历数据获取失败"
+ return return_data
+
+ menus = menu_payload.get("menus", {})
+ points = point_payload.get("points", {})
+ if not isinstance(menus, dict) or not isinstance(points, dict):
+ return_data["msg"] = "基础资历数据格式异常"
+ return return_data
+
+ selected_menu_id, selected_title = ACHIEVEMENT_CHOICE_MAP[choice]
+ items = []
+
+ if choice == 0:
+ total_ids = []
+ for _, menu_id, title in ACHIEVEMENT_CHOICES[1:]:
+ category = menus.get(str(menu_id), {})
+ if not isinstance(category, dict):
+ continue
+ category_ids = self._category_achievement_ids(category)
+ total_ids.extend(category_ids)
+ items.append(
+ self._build_achievement_progress(title, category_ids, points, completed_ids)
+ )
+ summary = self._build_achievement_progress(selected_title, total_ids, points, completed_ids)
+ else:
+ category = menus.get(str(selected_menu_id), {})
+ if not isinstance(category, dict) or not category:
+ return_data["msg"] = "未找到该资历分类"
+ return return_data
+
+ category_ids = self._category_achievement_ids(category)
+ summary = self._build_achievement_progress(selected_title, category_ids, points, completed_ids)
+ for child in category.get("children", []) or []:
+ if not isinstance(child, dict):
+ continue
+ child_ids = self._flatten_achievement_ids(child.get("achievements", []))
+ items.append(
+ self._build_achievement_progress(child.get("name", "未命名"), child_ids, points, completed_ids)
+ )
+
+ try:
+ return_data["temp"] = await load_template("zili.html")
+ except FileNotFoundError as e:
+ logger.error(f"加载模板失败: {e}")
+ return_data["msg"] = "系统错误:模板文件不存在"
+ return return_data
+
+ return_data["data"] = {
+ "title": selected_title,
+ "summary": summary,
+ "items": items,
+ "role_name": role_data.get("roleName", name),
+ "server": role_data.get("serverName", server),
+ "zone": role_data.get("zoneName", ""),
+ "force_name": role_data.get("forceName", "无"),
+ "camp_name": role_data.get("campName", "无"),
+ "tong_name": role_data.get("tongName", "无"),
+ "updated_at": achievement_data.get("updated_at", ""),
+ "update_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ }
+ return_data["code"] = 200
+
+ return return_data
+
+
async def jueshe(self,name: str, server: str) -> Dict[str, Any]:
"""角色"""
return_data = self._init_return_data()
@@ -2408,7 +2671,7 @@ class JX3Service:
f"服务器:{data.get('zoneName', '无')}·{data.get('serverName', '无')}\n"
f"名称:{data.get('roleName', '无')}\n"
f"角色ID:{data.get('roleId', '无')}\n"
- f"全区ID:{data.get('globalRoleId', '无')}\n"
+ f"全区ID:{data.get('globalId', '无')}\n"
f"职业:{data.get('forceName', '无')}·{data.get('bodyName', '无')}\n"
f"帮会:{data.get('tongName', '无')}\n"
f"阵营:{data.get('campName', '无')}\n"
diff --git a/core/message.py b/core/message.py
index 27fa47e..f3cfb28 100644
--- a/core/message.py
+++ b/core/message.py
@@ -13,6 +13,29 @@ from .bilei_data import BiLeidata
class MessageBuilder:
"""回复消息构建"""
+ ZILI_MENU_TEXT = (
+ "请选择资历查询类型:\n"
+ "0:资历总览\n"
+ "1:杂闻总览\n"
+ "2:武学总览\n"
+ "3:修为总览\n"
+ "4:装备总览\n"
+ "5:技艺总览\n"
+ "6:阅读总览\n"
+ "7:任务总览\n"
+ "8:足迹总览\n"
+ "9:战斗总览\n"
+ "10:声望总览\n"
+ "11:秘境总览\n"
+ "12:帮会总览\n"
+ "13:阵营总览\n"
+ "14:节日总览\n"
+ "15:活动总览\n"
+ "16:风雨江湖路总览\n"
+ "17:家园总览\n"
+ "18:剑侠录总览"
+ )
+
def __init__(self, server: str, jx3api: JX3Service, bilei: BiLeidata, jx3at: AsyncTask, icons: dict[str, dict[str, str]]):
self.server = server
self.jx3api = jx3api
@@ -187,6 +210,64 @@ class MessageBuilder:
await event.send(event.plain_result("猪脑过载,请稍后再试"))
+ async def handler_zili_msg(self, event: AstrMessageEvent, name: str, server: str):
+ """资历查询专用两轮会话,第一轮文本菜单,第二轮图片"""
+ try:
+ await event.send(event.plain_result(self.ZILI_MENU_TEXT))
+ user_id = event.get_sender_id()
+
+ @session_waiter(timeout=30)
+ async def zili_select_waiter(controller: SessionController, new_event: AstrMessageEvent):
+ if new_event.get_sender_id() != user_id:
+ return
+
+ msg = new_event.get_message_str().strip()
+ if not msg.isdigit():
+ await new_event.send(MessageChain().message("输入异常,结束会话"))
+ controller.stop()
+ return
+
+ choice = int(msg)
+ if choice < 0 or choice > 18:
+ await new_event.send(MessageChain().message("无效序号,结束会话"))
+ controller.stop()
+ return
+
+ try:
+ data = await self.jx3api.zili(name, server, choice)
+ if data["code"] != 200:
+ await new_event.send(MessageChain().message(data.get("msg", "获取资历数据失败")))
+ controller.stop()
+ return
+
+ options = {
+ "quality": 100,
+ "device_scale_factor_level": "normal",
+ "full_page": True,
+ "omit_background": False,
+ "type": "jpeg"
+ }
+ data["data"]["icons"] = self.icons
+ url = await self.html_render(data["temp"], data["data"], options=options)
+ await new_event.send(new_event.image_result(url))
+ except Exception as e:
+ logger.error(f"资历查询执行错误: {e}")
+ await new_event.send(MessageChain().message("猪脑过载,请稍后再试"))
+
+ controller.stop()
+
+ try:
+ await zili_select_waiter(event)
+ except TimeoutError:
+ await event.send(event.plain_result("选择超时,已结束会话"))
+ except Exception:
+ logger.error("资历选择发生异常", exc_info=True)
+
+ except Exception as e:
+ logger.error(f"资历会话执行错误: {e}")
+ await event.send(event.plain_result("猪脑过载,请稍后再试"))
+
+
async def jx3_helps(self, event: AstrMessageEvent):
"""剑三 功能"""
return await self.T2I_image_msg(event, self.jx3api.helps)
@@ -292,6 +373,11 @@ class MessageBuilder:
return await self.plain_msg(event, self.jx3api.shaohua)
+ async def jx3_zili(self, event: AstrMessageEvent, name: str, server: str = ""):
+ """剑三 资历 角色名称 服务器"""
+ return await self.handler_zili_msg(event, name, self.serverdefault(server))
+
+
async def jx3_jiemi(self, event: AstrMessageEvent):
"""剑三 解密"""
return await self.plain_msg(event, self.jx3api.jiemi)
diff --git a/data/api_config.json b/data/api_config.json
index 655d768..e0f74cb 100644
--- a/data/api_config.json
+++ b/data/api_config.json
@@ -591,6 +591,23 @@
"mount": "",
"star": "1"
}
+ },
+ "jx3box_achievement_menus":{
+ "url":"https://node.jx3box.com/api/node/achievement/menus",
+ "method":"GET",
+ "description":"魔盒资历菜单列表",
+ "params":{
+ "general": "1",
+ "client": "std"
+ }
+ },
+ "jx3box_achievement_points":{
+ "url":"https://node.jx3box.com/api/node/achievement/points",
+ "method":"GET",
+ "description":"魔盒资历点数列表",
+ "params":{
+ "client": "std"
+ }
}
diff --git a/main.py b/main.py
index dd1f268..dc86607 100644
--- a/main.py
+++ b/main.py
@@ -17,7 +17,7 @@ from .core.fun_basic import load_as_base64
@register("astrbot_plugin_jx3",
"fxdyz",
"通过调用剑网三API接口获取游戏数据,处理发送。",
- "2.5",
+ "2.6",
"https://github.com/qsc20001102/astrbot_plugin_jx3api"
)
class Jx3ApiPlugin(Star):
@@ -57,6 +57,7 @@ class Jx3ApiPlugin(Star):
# 数据库初始化
await self.init_bilei_data()
await self.init_tuishong_data()
+ await self.init_achievement_cache_data()
# 连接插件数据
await self.plugin_sql_db.connect()
@@ -142,7 +143,7 @@ class Jx3ApiPlugin(Star):
self.plugin_sql_db = AsyncSQLiteDB(str(self.plugin_data_path))
# 剑网三功能实例化
self.bilei = BiLeidata(self.local_sql_db)
- self.jx3api = JX3Service(str(self.api_data_path), self.conf, self.plugin_sql_db)
+ self.jx3api = JX3Service(str(self.api_data_path), self.conf, self.plugin_sql_db, self.local_sql_db)
self.jx3at = AsyncTask(cast(Context, self.context), self.conf, self.jx3api, self.local_sql_db)
self.jx3cmd = MessageBuilder(self.server, self.jx3api, self.bilei, self.jx3at, self.icons)
self.jx3cmd = MessageBuilder(self.server, self.jx3api, self.bilei, self.jx3at, self.icons)
@@ -182,6 +183,17 @@ class Jx3ApiPlugin(Star):
""")
+ async def init_achievement_cache_data(self):
+ """初始化资历基础数据缓存表"""
+ await self.local_sql_db.execute("""
+ CREATE TABLE IF NOT EXISTS achievement_cache(
+ key TEXT PRIMARY KEY,
+ content TEXT NOT NULL,
+ updated_at TEXT NOT NULL
+ )
+ """)
+
+
def ini_command_map(self):
"""初始化指令集"""
self.command_map = {
@@ -206,6 +218,7 @@ class Jx3ApiPlugin(Star):
"资历排行": self.jx3cmd.jx3_zilipaixing,
"试炼排行": self.jx3cmd.jx3_shilianpaixing,
"骚话": self.jx3cmd.jx3_shaohua,
+ "资历": self.jx3cmd.jx3_zili,
"解密": self.jx3cmd.jx3_jiemi,
"沙盘": self.jx3cmd.jx3_shapan,
"攻略": self.jx3cmd.jx3_qiyugonglue,
@@ -213,7 +226,7 @@ class Jx3ApiPlugin(Star):
"配装": self.jx3cmd.jx3_peizhuang,
"百战": self.jx3cmd.jx3_baizhan,
"扶摇": self.jx3cmd.jx3_fuyaojjiutian,
- "诛恶事件": self.jx3cmd.jx3_zhueevent,
+ "诛恶": self.jx3cmd.jx3_zhueevent,
"本日赤兔": self.jx3cmd.jx3_benrichitu,
"本周赤兔": self.jx3cmd.jx3_benzhouchitu,
"拍卖": self.jx3cmd.jx3_zhengyingpaimai,
@@ -230,7 +243,7 @@ class Jx3ApiPlugin(Star):
"近期奇遇": self.jx3cmd.jx3_jinqiqiyu,
"奇遇汇总": self.jx3cmd.jx3_qiyuhuizong,
"战绩": self.jx3cmd.jx3_zhanji,
- "排行": self.jx3cmd.jx3_mingjianpaihang,
+ "名剑排行": self.jx3cmd.jx3_mingjianpaihang,
"名剑统计": self.jx3cmd.jx3_mingjiantongji,
"招募": self.jx3cmd.jx3_tuanduizhaomu,
"拜师": self.jx3cmd.jx3_baishi,
diff --git a/metadata.yaml b/metadata.yaml
index 7bed29e..34c33ae 100644
--- a/metadata.yaml
+++ b/metadata.yaml
@@ -1,7 +1,7 @@
name: astrbot_plugin_jx3
display_name: 剑网三游戏数据查询工具
desc: 通过接口调用剑网三API接口获取游戏数据,处理发送。
-version: v2.5
+version: v2.6
author: 飞翔大野猪
repo: https://github.com/qsc20001102/astrbot_plugin_jx3
astrbot_version: ">=4.11.0"
diff --git a/templates/helps.html b/templates/helps.html
index ce99ee0..6554bd5 100644
--- a/templates/helps.html
+++ b/templates/helps.html
@@ -369,8 +369,8 @@ body {
剑三机器人功能指令
按使用场景重新分组,保留每条指令的名称、使用示例与说明。卡片底色表示指令是否需要令牌,免令牌与需令牌功能一眼区分。
-
87条指令
-
16个功能分组
+
88条指令
+
13个功能分组
@@ -394,13 +394,13 @@ body {
日常功能
- 3 条
+ 4 条
免令牌 3
-
+ 需令牌 1
-
+
日常活动
@@ -409,7 +409,7 @@ body {
日常 [服务器] [天数]
查询指定日期的日常活动。
-
+
日常预测
@@ -418,7 +418,7 @@ body {
月历
查看当前日期前后 15 天日常安排。
-
+
名望事件
@@ -427,140 +427,16 @@ body {
名望 [穹野卫]
查询指定名望势力事件。
-
-
-
-
-
-
-
- 乐
-
休闲功能
-
-
- 4 条
- 免令牌 1
- 需令牌 3
-
-
-
-
-
-
- 骚话
- 随机返回一句趣味骚话,用于群内互动。
-
-
-
-
- 烟花 角色名 [服务器]
- 查询指定角色烟花记录。
-
-
-
-
- 拜师 [搜索关键词] [服务器]
- 查询徒弟找师傅信息。
-
-
-
-
- 收徒 [搜索关键词] [服务器]
- 查询师傅找徒弟信息。
-
-
-
-
-
-
-
-
- 杂
-
杂项功能
-
-
- 7 条
- 免令牌 4
- 需令牌 3
-
-
-
-
-
-
- 科举 内容
- 按题目关键字查询科举答案。
-
-
-
-
- 花价 名称 [服务器] [家园地图]
- 查询家园鲜花价格,支持服务器与家园地图筛选。
-
-
-
-
- 装饰 名称
- 查询家园装饰物名称、来源与相关信息。
-
-
-
-
- 器物 地图名称
- 查询指定地图可收集的器物图谱。
-
-
-
-
- 八卦 类型
- 查询 818 / 616 / 避雷等八卦记录。
-
- 解密
- 查询当前机关解密结果与下轮时间。
+ 诛恶
+ 查询诛恶事件服务器、地图和时间记录。
-
-
-
- 骗子 QQ号
- 按 QQ 号查询骗子记录。
-
-
+
@@ -573,11 +449,10 @@ body {
6 条
免令牌 6
-
-
+
新闻资讯
@@ -586,7 +461,7 @@ body {
公告 [数量]
获取最新官方公告,数量默认为 5 条。
-
+
维护公告
@@ -595,7 +470,7 @@ body {
维护 [数量]
获取最新官方维护公告,数量默认为 5 条。
-
+
最新技改
@@ -604,7 +479,7 @@ body {
技改
获取最近一次官方职业技改内容。
-
+
搜索区服
@@ -613,7 +488,7 @@ body {
区服 [服务器]
查询服务器基础信息。
-
+
开服查询
@@ -622,7 +497,7 @@ body {
开服 [服务器]
查询指定服务器开服状态。
-
+
全服状态
@@ -631,77 +506,41 @@ body {
状态
查询所有服务器当前状态。
-
+
- 市
-
交易功能
+ 角
+ 角色功能
- 4 条
-
- 需令牌 4
+ 8 条
+ 需令牌 8
-
+
- 金价 [服务器]
- 查询指定服务器金价行情。
-
-
-
-
- 物价 外观名称 [服务器]
- 查询指定外观在服务器内的物价行情。
-
-
-
-
- 交易行 物品名称 [服务器]
- 查询指定物品交易行价格与挂单信息。
+ 角色 名称 [服务器]
+ 查询角色基础信息。
- 贴吧物价 物品名称 [记录数量] [服务器]
- 查询指定物品的贴吧交易记录。
+ 资历 角色名 [服务器]
+ 按分类查询角色资历点数完成进度。
-
-
-
-
-
-
-
- 名
-
名片功能
-
-
- 3 条
-
- 需令牌 3
-
-
-
-
+
角色名片
@@ -710,7 +549,7 @@ body {
名片 角色名 [服务器]
查询角色当前名片。
-
+
所有名片
@@ -719,16 +558,43 @@ body {
所有名片 角色名 [服务器]
查询角色已拥有或可展示的全部名片。
-
+
- 随机 职业 体型 [服务器]
- 按职业、体型、服务器随机抽取名片。
+ 奇遇 角色名 [服务器]
+ 查询指定角色已触发奇遇。
-
+
+
+
+ 未做奇遇 角色名 [服务器]
+ 查询指定角色尚未完成的奇遇。
+
+
+
+
+ 战绩 角色名 [服务器] [模式]
+ 查询角色名剑大会战绩,支持 22 / 33 模式。
+
+
+
+
+ 精耐 角色名 [服务器]
+ 查询角色百战精力、耐力和技能列表。
+
+
@@ -739,13 +605,13 @@ body {
职业功能
- 7 条
+ 6 条
免令牌 3
- 需令牌 4
+ 需令牌 3
-
+
小药推荐
@@ -754,7 +620,7 @@ body {
小药
查询指定心法常用小药、宴席与辅助搭配。
-
+
心法宏
@@ -763,7 +629,7 @@ body {
宏 心法
查询指定心法推荐宏设置。
-
+
心法配装
@@ -772,16 +638,7 @@ body {
配装 心法 [筛选]
查询指定心法配装,支持 PvP / PvE 筛选。
-
-
-
- 角色 名称 [服务器]
- 查询角色基础信息。
-
-
+
心法阵眼
@@ -790,7 +647,7 @@ body {
阵眼 心法
查询指定心法阵眼效果。
-
+
奇穴详情
@@ -799,7 +656,7 @@ body {
奇穴 心法
查询指定心法奇穴详情。
-
+
技能详情
@@ -808,7 +665,96 @@ body {
技能 心法
查询指定心法技能详情。
-
+
+
+
+
+
+
+
+ 乐
+
休闲功能
+
+
+ 8 条
+ 免令牌 1
+ 需令牌 7
+
+
+
+
+
+
+ 烟花 角色名 [服务器]
+ 查询指定角色烟花记录。
+
+
+
+
+ 拜师 [搜索关键词] [服务器]
+ 查询徒弟找师傅信息。
+
+
+
+
+ 收徒 [搜索关键词] [服务器]
+ 查询师傅找徒弟信息。
+
+
+
+
+ 随机名片 职业 体型 [服务器]
+ 按职业、体型、服务器随机抽取名片。
+
+
+
+
+ 攻略 奇遇名称
+ 查询指定奇遇的触发条件、奖励与流程攻略。
+
+
+
+
+ 奇遇统计 奇遇名称 [服务器]
+ 统计指定奇遇触发次数
+
+
+
+
+ 近期奇遇 [服务器]
+ 查询指定服务器最近触发的奇遇记录
+
+
+
+
+ 奇遇汇总 [天数] [服务器]
+ 统计指定服务器最近一段时间的奇遇触发汇总
+
+
@@ -825,7 +771,7 @@ body {
-
+
阵营沙盘
@@ -834,7 +780,7 @@ body {
沙盘 [服务器]
查询指定服务器阵营沙盘与据点状态。
-
+
阵营拍卖
@@ -843,7 +789,7 @@ body {
拍卖 物品名称 [服务器]
查询阵营拍卖物品及服务器记录。
-
+
阵营事件
@@ -852,7 +798,7 @@ body {
阵营事件
查询跨服阵营事件记录。
-
+
关隘首领
@@ -879,7 +825,7 @@ body {
统战 [服务器]
查询指定服务器阵营统战 YY 信息。
-
+
@@ -890,119 +836,12 @@ body {
副本功能
- 2 条
-
- 需令牌 2
+ 4 条
+ 需令牌 4
-
-
-
- 招募 副本名称 [服务器]
- 查询指定服务器副本招募信息。
-
-
-
-
- 掉落 物品名称 [数量] [服务器]
- 查询团队秘境贵重物品掉落记录
-
-
-
-
-
-
-
-
- 奇
-
奇遇功能
-
-
- 6 条
- 免令牌 1
- 需令牌 5
-
-
-
-
-
-
- 攻略 奇遇名称
- 查询指定奇遇的触发条件、奖励与流程攻略。
-
-
-
-
- 奇遇 角色名 [服务器]
- 查询指定角色已触发奇遇。
-
-
-
-
- 未做奇遇 角色名 [服务器]
- 查询指定角色尚未完成的奇遇。
-
-
-
-
- 奇遇统计 奇遇名称 [服务器]
- 统计指定奇遇触发次数
-
-
-
-
- 近期奇遇 [服务器]
- 查询指定服务器最近触发的奇遇记录
-
-
-
-
- 奇遇汇总 [天数] [服务器]
- 统计指定服务器最近一段时间的奇遇触发汇总
-
-
-
-
-
-
-
-
- 战
-
百战功能
-
-
- 2 条
-
- 需令牌 2
-
-
-
-
+
百战首领
@@ -1011,16 +850,34 @@ body {
百战
查询本期百战异闻录首领与关卡信息。
-
+
- 精耐 角色名 [服务器]
- 查询角色百战精力、耐力和技能列表。
+ 招募 副本名称 [服务器]
+ 查询指定服务器副本招募信息。
-
+
+
+
+ 掉落 物品名称 [数量] [服务器]
+ 查询团队秘境贵重物品掉落记录
+
+
+
+
+ 解密
+ 查询当前机关解密结果与下轮时间。
+
+
@@ -1031,13 +888,12 @@ body {
活动功能
- 6 条
-
- 需令牌 6
+ 5 条
+ 需令牌 5
-
+
扶摇九天
@@ -1046,15 +902,6 @@ body {
扶摇 [服务器]
查询指定服务器扶摇九天活动记录。
-
-
-
- 诛恶事件
- 查询诛恶事件服务器、地图和时间记录。
-
@@ -1073,7 +920,7 @@ body {
本周赤兔
查询本周赤兔时间、区服和地图记录。
-
+
马场刷新
@@ -1082,7 +929,7 @@ body {
刷马 [服务器]
查询指定服务器马场刷新记录。
-
+
的卢记录
@@ -1091,51 +938,139 @@ body {
的卢 [服务器]
查询指定服务器的卢马刷新与捕获记录。
-
+
- 剑
-
名剑功能
+ 市
+ 交易功能
- 3 条
-
- 需令牌 3
+ 4 条
+ 需令牌 4
-
+
- 战绩 角色名 [服务器] [模式]
- 查询角色名剑大会战绩,支持 22 / 33 模式。
+ 金价 [服务器]
+ 查询指定服务器金价行情。
-
+
- 名剑统计 [模式]
- 统计指定模式名剑大会数据。
+ 物价 外观名称 [服务器]
+ 查询指定外观在服务器内的物价行情。
-
+
- 排行 [数量] [模式]
- 查询名剑大会排名,支持 22 / 33 模式。
+ 交易行 物品名称 [服务器]
+ 查询指定物品交易行价格与挂单信息。
-
+
+
+
+ 贴吧物价 物品名称 [记录数量] [服务器]
+ 查询指定物品的贴吧交易记录。
+
+
+
+
+
+
+
+
+ 杂
+
杂项功能
+
+
+ 7 条
+ 免令牌 5
+ 需令牌 2
+
+
+
+
+
+
+ 科举 内容
+ 按题目关键字查询科举答案。
+
+
+
+
+ 花价 名称 [服务器] [家园地图]
+ 查询家园鲜花价格,支持服务器与家园地图筛选。
+
+
+
+
+ 装饰 名称
+ 查询家园装饰物名称、来源与相关信息。
+
+
+
+
+ 器物 地图名称
+ 查询指定地图可收集的器物图谱。
+
+
+
+
+ 八卦 类型
+ 查询 818 / 616 / 避雷等八卦记录。
+
+
+
+
+ 骗子 QQ号
+ 按 QQ 号查询骗子记录。
+
+
+
+
+ 骚话
+ 随机返回一句趣味骚话,用于群内互动。
+
+
@@ -1146,13 +1081,30 @@ body {
排行功能
- 19 条
-
- 需令牌 19
+ 21 条
+ 需令牌 21
-
+
+
+
+ 名剑统计 [模式]
+ 统计指定模式名剑大会数据。
+
+
+
+
+ 名剑排行 [数量] [模式]
+ 查询名剑大会排名,支持 22 / 33 模式。
+
+
资历排行
@@ -1170,7 +1122,7 @@ body {
试炼排行 心法 [服务器]
查询指定心法木桩试炼排行榜。
-
+
名士五十强
@@ -1179,7 +1131,7 @@ body {
名士五十强 [服务器]
查询风云录排行榜数据。
-
+
老江湖五十强
@@ -1188,7 +1140,7 @@ body {
老江湖五十强 [服务器]
查询风云录排行榜数据。
-
+
兵甲藏家五十强
@@ -1197,7 +1149,7 @@ body {
兵甲藏家五十强 [服务器]
查询风云录排行榜数据。
-
+
名师五十强
@@ -1206,7 +1158,7 @@ body {
名师五十强 [服务器]
查询风云录排行榜数据。
-
+
阵营英雄五十强
@@ -1215,7 +1167,7 @@ body {
阵营英雄五十强 [服务器]
查询风云录排行榜数据。
-
+
薪火相传五十强
@@ -1224,7 +1176,7 @@ body {
薪火相传五十强 [服务器]
查询风云录排行榜数据。
-
+
庐园广记一百强
@@ -1233,7 +1185,7 @@ body {
庐园广记一百强 [服务器]
查询风云录排行榜数据。
-
+
浩气神兵宝甲五十强
@@ -1242,7 +1194,7 @@ body {
浩气神兵宝甲五十强 [服务器]
查询风云录排行榜数据。
-
+
恶人神兵宝甲五十强
@@ -1251,7 +1203,7 @@ body {
恶人神兵宝甲五十强 [服务器]
查询风云录排行榜数据。
-
+
浩气爱心帮会五十强
@@ -1260,7 +1212,7 @@ body {
浩气爱心帮会五十强 [服务器]
查询风云录排行榜数据。
-
+
恶人爱心帮会五十强
@@ -1269,7 +1221,7 @@ body {
恶人爱心帮会五十强 [服务器]
查询风云录排行榜数据。
-
+
赛季恶人五十强
@@ -1278,7 +1230,7 @@ body {
赛季恶人五十强 [服务器]
查询风云录排行榜数据。
-
+
赛季浩气五十强
@@ -1287,7 +1239,7 @@ body {
赛季浩气五十强 [服务器]
查询风云录排行榜数据。
-
+
上周恶人五十强
@@ -1296,7 +1248,7 @@ body {
上周恶人五十强 [服务器]
查询风云录排行榜数据。
-
+
上周浩气五十强
@@ -1305,7 +1257,7 @@ body {
上周浩气五十强 [服务器]
查询风云录排行榜数据。
-
+
本周恶人五十强
@@ -1314,7 +1266,7 @@ body {
本周恶人五十强 [服务器]
查询风云录排行榜数据。
-
+
本周浩气五十强
@@ -1323,7 +1275,7 @@ body {
本周浩气五十强 [服务器]
查询风云录排行榜数据。
-
+
@@ -1336,11 +1288,10 @@ body {
4 条
免令牌 4
-
-
+
开服推送
@@ -1349,7 +1300,7 @@ body {
开服推送
订阅或管理服务器开服状态推送。
-
+
新闻推送
@@ -1358,7 +1309,7 @@ body {
新闻推送
订阅或管理官方新闻公告推送。
-
+
刷马推送
@@ -1367,7 +1318,7 @@ body {
刷马推送
订阅或管理刷马刷新推送。
-
+
赤兔推送
@@ -1376,7 +1327,7 @@ body {
赤兔推送
订阅或管理赤兔马刷新推送。
-
+
@@ -1389,11 +1340,10 @@ body {
5 条
免令牌 5
-
-
+
避雷查看
@@ -1402,7 +1352,7 @@ body {
避雷查看
查看当前群内避雷记录列表。
-
+
避雷添加
@@ -1411,7 +1361,7 @@ body {
避雷添加 名称 备注
新增一条避雷记录。
-
+
避雷删除
@@ -1420,7 +1370,7 @@ body {
避雷删除 ID
按 ID 删除避雷记录。
-
+
避雷修改
@@ -1429,7 +1379,7 @@ body {
避雷修改 ID 名称 备注
按 ID 修改避雷名称与备注。
-
+
避雷查询
@@ -1438,7 +1388,7 @@ body {
避雷查询 名称
按名称关键字查询避雷记录。
-
+
diff --git a/templates/zili.html b/templates/zili.html
new file mode 100644
index 0000000..309b086
--- /dev/null
+++ b/templates/zili.html
@@ -0,0 +1,206 @@
+
+
+
+
+资历查询
+
+
+
+
+
+
+
+
+
+
+
{{ summary.name }}
+
{{ summary.percent_text }}
+
+
+ {{ summary.completed_points }} / {{ summary.total_points }} 点
+ · {{ summary.completed_count }} / {{ summary.achievement_count }} 项
+
+
+
+
+
+ {% for item in items %}
+
+
+
{{ item.name }}
+
{{ item.percent_text }}
+
+
+ {{ item.completed_points }} / {{ item.total_points }} 点
+ · {{ item.completed_count }} / {{ item.achievement_count }} 项
+
+
+
+ {% endfor %}
+
+
+
+
+