This commit is contained in:
qsc
2026-02-18 21:31:49 +08:00
parent 8767ed8f98
commit 152e20ea8d
11 changed files with 841 additions and 802 deletions
+10 -8
View File
@@ -2,17 +2,19 @@
## 简介
仿照剑网三主流的机器人写了个插件,主要是自用。
仿照剑网三主流的机器人写了个插件,主要是自用,没有群管理相关的功能,在任何群聊都是使用的一套数据
插件功能绝大部分都是用AI写的,进行了调试。
插件功能绝大部分都是用AI写的,自己进行了调试。
目前此插件能够完成部分的功能查询,其他功能有空再说
目前此插件查询功能还没做完,后续会继续完善
此插件的所有数据几乎全部依赖jx3api提供的API接口,所以进阶功能需要向其购买token才可使用。普通功能是免token的。
部分进阶功能除了购买token以外还需要自己去抓包推栏app,获得推栏app的token才可正常使用。
此插件大部分数据依赖jx3api提供的接口,只有进阶功能需要向其购买token才可使用。其他功能是免token的。
部分进阶功能除了购买token以外还需要自己去抓包推栏app,获得推栏app的ticket才可正常使用。
## 更新记录
version: 1.1.0:部分代码功能重写。
version: 1.0.0:大部分重要功能已经实现
## 功能特点
@@ -35,10 +37,10 @@ version: 1.0.0:大部分重要功能已经实现
使用进阶的功能必须配置,购买在https://www.jx3api.com。
**推栏标识**
**推栏ticket**
在进阶功能中,有部分功能依赖推栏APP的数据,所以需要自己抓包推栏的token
大致操作下载一个抓包工具,打开推栏APP,做一些查询操作。去抓包工具看看发送的请求,参数里面就有token
在进阶功能中,有部分功能依赖推栏APP的数据,所以需要自己抓包推栏的ticket
大致操作下载一个抓包工具,打开推栏APP,做一些查询操作。去抓包工具看看发送的请求,参数里面就有ticket
**推送功能**
+4 -4
View File
@@ -35,7 +35,7 @@
"default": "",
"hint": "通过抓包推栏APP账号登录信息获取推栏标识"
},
"kfjk": {
"kfts": {
"description": "开服监控配置",
"type": "object",
"items": {
@@ -63,7 +63,7 @@
}
}
},
"xwzx": {
"xwts": {
"description": "新闻资讯推送",
"type": "object",
"items": {
@@ -91,7 +91,7 @@
}
}
},
"smxx": {
"smts": {
"description": "刷马消息推送",
"type": "object",
"items": {
@@ -119,7 +119,7 @@
}
}
},
"ctxx": {
"ctts": {
"description": "赤兔消息推送",
"type": "object",
"items": {
+39 -39
View File
@@ -11,70 +11,67 @@ from astrbot.api.star import Context, Star, register, StarTools
from astrbot.api import logger
from astrbot.api import AstrBotConfig
from .jx3_data import JX3Service
from .jx3_data import JX3Service
from .sqlite import AsyncSQLiteDB
class AsyncTask:
"""
基于 APScheduler 的后台异步监控任务管理类
"""
def __init__(self, context: Context, config: AstrBotConfig, jx3fun: JX3Service):
def __init__(self, context: Context, config: AstrBotConfig, jx3api: JX3Service, sqlite: AsyncSQLiteDB):
self.context = context
self.conf = config
self.jx3fun = jx3fun
self.jx3fun = jx3api
self.sql = sqlite
self.server = self.conf.get("server", "梦江南")
self.file_path = StarTools.get_data_dir("astrbot_plugin_jx3") / "local_async.json"
self._file_lock = asyncio.Lock()
self.scheduler = AsyncIOScheduler()
self.tasks = {} # 存储 task_id 对应的状态信息
self.tasks = {}
logger.info(f"获取后台数据缓存文件路径成功:{self.file_path}")
logger.info(f"初始化推送功能成功")
"""===================== 本地读写 ====================="""
async def set_local_data(self, key: str, value):
async with self._file_lock:
try:
self.file_path.parent.mkdir(parents=True, exist_ok=True)
allowed = {"kfts", "xwts", "smts", "ctts"}
if key not in allowed:
raise ValueError("非法字段")
if not self.file_path.exists():
local_data = {}
else:
async with aiofiles.open(self.file_path, "r", encoding="utf-8") as f:
content = await f.read()
local_data = json.loads(content) if content else {}
local_data[key] = value
async with aiofiles.open(self.file_path, "w", encoding="utf-8") as f:
await f.write(
json.dumps(local_data, ensure_ascii=False, indent=4)
await self.sql.update(
"tuishong",
{
key: value,
},
"id=?",
(1,)
)
except Exception as e:
logger.error(f"数据写入失败:{e}")
except (OSError, json.JSONDecodeError) as e:
logger.error(f"数据写入文件失败:{e}")
async def get_local_data(self, key: str, default=None):
async with self._file_lock:
async def get_local_data(self, key: str, default: int=0):
try:
if not self.file_path.exists():
allowed = {"kfts", "xwts", "smts", "ctts"}
if key not in allowed:
return default
async with aiofiles.open(self.file_path, "r", encoding="utf-8") as f:
content = await f.read()
if not content:
data = await self.sql.select_one(
"tuishong",
"id=?",
(1,)
)
if data:
return data.get(key, default)
else:
return default
local_data = json.loads(content)
except Exception as e:
logger.error(f"数据读取失败:{e}")
return local_data.get(key, default)
except (OSError, json.JSONDecodeError) as e:
logger.error(f"读取数据文件失败:{e}")
return default
"""===================== 通用后台任务 ====================="""
@@ -112,10 +109,10 @@ class AsyncTask:
async def init_tasks(self):
settings = [
("kfjk", "开服监控", lambda: self.jx3fun.kaifu(self.server)),
("xwzx", "新闻资讯", lambda: self.jx3fun.xinwen(1)),
("smxx", "刷马消息", lambda: self.jx3fun.shuamamsg(self.server,type="horse",subtype="foreshow")),
("ctxx", "赤兔消息", lambda: self.jx3fun.shuamamsg(self.server,type="chitu-horse",subtype="share_msg")),
("kfts", "开服监控", lambda: self.jx3fun.kaifu(self.server)),
("xwts", "新闻资讯", lambda: self.jx3fun.xinwen(1)),
("smts", "刷马消息", lambda: self.jx3fun.shuamamsg(self.server,type="horse",subtype="foreshow")),
("ctts", "赤兔消息", lambda: self.jx3fun.shuamamsg(self.server,type="chitu-horse",subtype="share_msg")),
]
for key, name, fetch in settings:
@@ -131,7 +128,10 @@ class AsyncTask:
}
if self.tasks[key]["enable"]:
if self.tasks[key]["umos"]:
self._add_scheduler(key, name, fetch)
else:
logger.warning(f"{name} 推送对象为空,任务未启动")
if not self.scheduler.running:
self.scheduler.start()
+52 -44
View File
@@ -1,9 +1,4 @@
# pyright: reportArgumentType=false
# pyright: reportAttributeAccessIssue=false
# pyright: reportIndexIssue=false
# pyright: reportOptionalMemberAccess=false
import json
from datetime import datetime
from typing import Dict, Any, Optional, List, Union
@@ -15,10 +10,16 @@ from .sqlite import AsyncSQLiteDB
from .fun_basic import load_template,gold_to_string,week_to_num,compare_date_str
class JX3Service:
def __init__(self, api_config, config:AstrBotConfig, sqlite:AsyncSQLiteDB):
self._api = APIClient()
# 引用API配置文件
self._api_config = api_config
def __init__(self, api_data_path: str, config: AstrBotConfig, sqlite: AsyncSQLiteDB):
# 加载API配置文件
try:
with open(api_data_path, 'r', encoding='utf-8') as f:
self._api_config = json.load(f)
except FileNotFoundError as e:
logger.error(f"加载API配置文件失败: {e}")
self._api_config = {}
# 实例化 API Client
self._api: APIClient = APIClient()
# 引用插件配置文件
self._config = config
# 引用sqlite
@@ -27,13 +28,13 @@ class JX3Service:
# 获取配置中的 Token
self.token = self._config.get("jx3api_token", "")
if self.token == "":
logger.info("获取配置token失败,请正确填写token,否则部分功能无法正常使用")
logger.warning("获取配置token失败,请正确填写token,否则部分功能无法正常使用")
else:
logger.debug(f"获取配置token成功。{self.token}")
# 获取配置中的 ticket
self.ticket = self._config.get("jx3api_ticket", "")
if self.ticket == "":
logger.info("获取配置ticket失败,请正确填写ticket,否则部分功能无法正常使用")
logger.warning("获取配置ticket失败,请正确填写ticket,否则部分功能无法正常使用")
else:
logger.debug(f"获取配置ticket成功。{self.ticket}")
@@ -42,7 +43,6 @@ class JX3Service:
"""释放底层 APIClient 资源"""
if self._api:
await self._api.close()
self._api = None
def _init_return_data(self) -> Dict[str, Any]:
@@ -72,12 +72,15 @@ class JX3Service:
:return: 成功时返回提取后的数据,失败时返回 None。
"""
try:
if not self._api:
logger.error("API client is not initialized")
return None
api_config = self._api_config.get(config_key)
if not api_config:
logger.error(f"配置文件中未找到 key: {config_key}")
return None
# 复制 params,避免修改原始配置模板
request_params = api_config.get("params", {}).copy()
if params:
request_params.update(params)
@@ -185,7 +188,7 @@ class JX3Service:
# 3. 处理返回数据
try:
items = []
num_richang = week_to_num(data["data"][0]["week"])
num_richang = week_to_num(data["data"][0]["week"]) or 0
# 空白数据
for _ in range(num_richang):
items.append({
@@ -271,7 +274,7 @@ class JX3Service:
params = {"subject": subject, "limit": limit}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[List[Dict[str, Any]]] = await self._base_request(
"jx3_keju", "GET", params=params
)
if not data:
@@ -511,7 +514,7 @@ class JX3Service:
return_data = self._init_return_data()
data: Optional[Dict[str, Any]] = await self._base_request("jx3_zhuangtai", "GET")
data: Optional[List[Dict[str, Any]]] = await self._base_request("jx3_zhuangtai", "GET")
if not data:
return_data["msg"] = "获取接口信息失败"
@@ -621,8 +624,8 @@ class JX3Service:
return_data = self._init_return_data()
params = {"server": server, "type": type, "subtype": subtype}
# 提取字段可能返回列表
data: Optional[List[Dict[str, Any]]] = await self._base_request(
# 提取字段可能返回字典
data: Optional[Dict[str, Any]] = await self._base_request(
"jx3box_shuamamsg", "GET", params=params)
if not data:
@@ -631,7 +634,7 @@ class JX3Service:
try:
#
new_msg = data.get("list")[0]
new_msg = data.get("list",[])[0]
return_data["status"] = new_msg.get('id')
result_msg = f"{server}\n"
@@ -653,18 +656,14 @@ class JX3Service:
"""区服金价"""
return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
params = {"server": server, "limit": limit, "token": token}
params = {"server": server, "limit": limit, "token": self.token}
data_list: Optional[List[Dict[str, Any]]] = await self._base_request("jx3_jinjia", "GET", params=params)
if not data_list or not isinstance(data_list, list):
return_data["msg"] = "获取接口信息失败或数据格式错误"
return return_data
# 加载模板
try:
return_data["temp"] = await load_template("jinjia.html")
@@ -772,7 +771,7 @@ class JX3Service:
params = {"server": server, "name": name,"token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[List[Dict[str, Any]]] = await self._base_request(
"jx3_jiaoyihang", "GET", params=params
)
@@ -785,6 +784,7 @@ class JX3Service:
try:
for item in data:
if isinstance(item, dict):
inner_list = item.get("data", [])
first = inner_list[0] if inner_list else {}
new_item = {
@@ -793,7 +793,7 @@ class JX3Service:
"sever": first.get("server"),
"count": len(inner_list),
"unit_price": gold_to_string(first.get("unit_price")),
"created": datetime.fromtimestamp(first.get("created")).strftime("%Y-%m-%d %H:%M:%S"),
"created": datetime.fromtimestamp(first.get("created", "")).strftime("%Y-%m-%d %H:%M:%S"),
}
result.append(new_item)
return_data["data"]["list"] = result
@@ -868,7 +868,7 @@ class JX3Service:
params = {"server": server, "name": name,"token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[List[Dict[str, Any]]] = await self._base_request(
"jx3_yanhuachaxun", "GET", params=params
)
@@ -879,12 +879,12 @@ class JX3Service:
# 3. 处理返回数据
try:
for item in data:
if isinstance(item, dict):
timestamp = item.get("time")
if timestamp and isinstance(timestamp, (int, float)):
# 修复时间戳:原代码显示这里是毫秒级,除以 1000
item["time"] = datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
else:
item["time"] = "未知时间" # 确保即使 time 字段缺失也不会报错
item["time"] = "未知时间"
return_data["data"]["list"] = data
except Exception as e:
@@ -913,7 +913,7 @@ class JX3Service:
params = {"server": server, "token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[List[Dict[str, Any]]] = await self._base_request(
"jx3_dilujilu", "GET", params=params
)
@@ -1034,7 +1034,7 @@ class JX3Service:
params = {"server": server, "name": name, "token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[List[Dict[str, Any]]] = await self._base_request(
"jx3_qiyu", "GET", params=params
)
@@ -1082,7 +1082,7 @@ class JX3Service:
params = {"server": server, "name": name, "token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[List[Dict[str, Any]]] = await self._base_request(
"jx3_zhengyingpaimai", "GET", params=params
)
@@ -1122,7 +1122,7 @@ class JX3Service:
params = {"server": server, "token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[list[Dict[str, Any]]] = await self._base_request(
"jx3_fuyaojiutian", "GET", params=params
)
@@ -1240,7 +1240,7 @@ class JX3Service:
params = {"class": type, "limit": "5", "token": self.token}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[list[Dict[str, Any]]] = await self._base_request(
"jx3_bagua", "GET", params=params
)
@@ -1277,7 +1277,7 @@ class JX3Service:
params = {"name": name}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[list[Dict[str, Any]]] = await self._base_request(
"jx3box_qiyugonglue", "GET", params=params, out_key="list"
)
@@ -1290,11 +1290,10 @@ class JX3Service:
url = f"https://node.jx3box.com/serendipity/{dwID}/achievement"
logger.debug(f"获取ID接口地址:{url}")
# 3. 获取奇遇攻略
# 获取achievement_id
data1 = await self._api.get(url)
url1 = f"https://cms.jx3box.com/api/cms/wiki/post/type/achievement/source/{data1['achievement_id']}"
logger.debug(f"获取攻略接口地址:{url1}")
# 获取奇遇攻略
data2 = await self._api.get(url1, out_key="data")
if not data2:
@@ -1327,8 +1326,12 @@ class JX3Service:
(name, name, name, name, name, name)
)
kungfu = result.get("name",None)
if kungfu == None:
if result is None:
return_data["msg"] = "未找到该心法"
return return_data
kungfu = result.get("name", None)
if kungfu is None:
return_data["msg"] = "未找到该心法"
return return_data
@@ -1338,7 +1341,7 @@ class JX3Service:
params = {"kungfu": kungfu}
# 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request(
data: Optional[list[Dict[str, Any]]] = await self._base_request(
"jx3box_hong", "GET", params=params, out_key=""
)
logger.debug(data)
@@ -1377,6 +1380,7 @@ class JX3Service:
# 发起请求
url = f"https://cms.jx3box.com/api/cms/post/{pid}"
logger.debug(f"获取宏接口地址:{url}")
data = await self._api.get(url, out_key="data")
# 验证数据
if not data:
@@ -1414,9 +1418,13 @@ class JX3Service:
"name=? OR name1=? OR name2=? OR name3=? OR name4=? OR name5=?",
(name, name, name, name, name, name)
)
logger.debug(result)
if result is None:
return_data["msg"] = "未找到该心法"
return return_data
mount = result.get("pzid",None)
if mount == None:
mount = result.get("pzid", None)
if not mount:
return_data["msg"] = "未找到该心法"
return return_data
+379
View File
@@ -0,0 +1,379 @@
from astrbot.core import html_renderer
from astrbot.api import logger
from astrbot.api.event import AstrMessageEvent, MessageChain
from astrbot.core.utils.session_waiter import (
SessionController,
session_waiter,
)
from .jx3_data import JX3Service
from .async_task import AsyncTask
from .bilei_data import BiLeidata
class MessageBuilder:
"""回复消息构建"""
def __init__(self, server: str, jx3api: JX3Service, bilei: BiLeidata, jx3at: AsyncTask):
self.server = server
self.jx3api = jx3api
self.bilei = bilei
self.jx3at = jx3at
async def html_render(
self,
tmpl: str,
data: dict,
return_url=True,
options: dict | None = None,
) -> str:
"""渲染 HTML"""
return await html_renderer.render_custom_template(
tmpl,
data,
return_url=return_url,
options=options,
)
def serverdefault(self,server) -> str:
"""加载配置默认服务器"""
if server == "":
return self.server
return server
async def plain_msg(self, event: AstrMessageEvent, action):
"""最终将数据整理成文本发送"""
data= await action()
try:
if data["code"] == 200:
await event.send( event.plain_result(data["data"]))
else:
await event.send(event.plain_result(data["msg"]))
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await event.send(event.plain_result("猪脑过载,请稍后再试"))
async def T2I_image_msg(self, event: AstrMessageEvent, action):
"""最终将数据渲染成图片发送"""
data = await action()
try:
if data["code"] == 200:
url = await self.html_render(data["temp"], data["data"], options={})
await event.send(event.image_result(url))
else:
await event.send(event.plain_result(data["msg"]))
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await event.send(event.plain_result("猪脑过载,请稍后再试"))
async def image_msg(self, event: AstrMessageEvent, action):
"""最终将数据整理成图片发送"""
data = await action()
try:
if data["code"] == 200:
await event.send(event.image_result(data["data"]))
else:
await event.send(event.plain_result(data["msg"]))
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await event.send(event.plain_result("猪脑过载,请稍后再试"))
async def handler_plain_image_msg(self, event: AstrMessageEvent, action1, action2):
"""两轮会话消息发送通用,先文本列表等反馈序号在发送图片"""
# 会话触发
try:
# 获取一轮数据
data = await action1()
if data["code"] == 200:
# 发送一轮消息
await event.send(event.plain_result(data["msg"]))
# 获取触发用户ID
user_id = event.get_sender_id()
# 二轮会话流程
@session_waiter(timeout=30)
async def macro_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
# 判断数字是否在有效值内
num = int(msg)
if num < 1 or num > data["data"]["num"]:
await new_event.send(
MessageChain().message("无效序号,结束会话")
)
controller.stop()
return
# 获取二轮数据
try:
data1 = await action2(data["data"]["list"][num])
if data1["code"] != 200:
await new_event.send(
MessageChain().message("获取详细数据失败")
)
controller.stop()
return
# 消息拼接发送
chain = MessageChain()
msg_text = data1["data"]
chain.message(msg_text)
if data1["temp"] != "":
url = await self.html_render(data1["temp"], {}, options={})
chain.url_image(url)
await new_event.send(chain)
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await new_event.send(
MessageChain().message("猪脑过载,请稍后再试")
)
controller.stop()
# 二轮会话激活
try:
await macro_select_waiter(event)
except TimeoutError:
await event.send(event.plain_result("选择超时,已结束会话"))
except Exception:
logger.error("宏选择发生异常", exc_info=True)
else:
await event.send(event.plain_result(f"未搜索到相关内容"))
return
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)
async def jx3_richang(self, event: AstrMessageEvent,server: str = "" ,num: int = 0):
"""剑三 日常 服务器 天数"""
return await self.plain_msg(event, lambda: self.jx3api.richang(self.serverdefault(server),num))
async def jx3_richangyuche(self, event: AstrMessageEvent):
"""剑三 日常预测"""
return await self.T2I_image_msg(event, self.jx3api.richangyuche)
async def jx3_xingxiashijian(self, event: AstrMessageEvent,name: str = "穹野卫"):
"""剑三 名望"""
return await self.T2I_image_msg(event, lambda: self.jx3api.xingxiashijian(name))
async def jx3_kaifu(self, event: AstrMessageEvent,server: str = ""):
"""剑三 开服 服务器"""
return await self.plain_msg(event, lambda: self.jx3api.kaifu(self.serverdefault(server)))
async def jx3_zhuangtai(self, event: AstrMessageEvent):
"""剑三 状态"""
return await self.T2I_image_msg(event, self.jx3api.zhuangtai)
async def jx3_shaohua(self, event: AstrMessageEvent,):
"""剑三 骚话"""
return await self.plain_msg(event, self.jx3api.shaohua)
async def jx3_jigai(self, event: AstrMessageEvent,):
"""剑三 技改"""
return await self.plain_msg(event, self.jx3api.jigai)
async def jx3_xinwen(self, event: AstrMessageEvent,num:int = 5):
"""剑三 新闻"""
return await self.plain_msg(event, lambda: self.jx3api.xinwen(num))
async def jx3_keju(self, event: AstrMessageEvent,subject: str, limit: int = 5):
"""剑三 科举"""
return await self.plain_msg(event, lambda: self.jx3api.keju(subject,limit))
async def jx3_huajia(self, event: AstrMessageEvent, name: str= "", server: str = "", map: str= ""):
"""剑三 花价 名称 服务器 地图"""
return await self.T2I_image_msg(event, lambda: self.jx3api.huajia(self.serverdefault(server),name,map))
async def jx3_zhuangshi(self, event: AstrMessageEvent, name: str):
"""剑三 装饰 名称"""
return await self.T2I_image_msg(event, lambda: self.jx3api.zhuangshi(name))
async def jx3_qiwu(self, event: AstrMessageEvent, name: str):
"""剑三 器物 地图名称"""
return await self.T2I_image_msg(event, lambda: self.jx3api.qiwu(name))
async def jx3_shapan(self, event: AstrMessageEvent,server: str = ""):
"""剑三 沙盘 服务器"""
return await self.image_msg(event, lambda: self.jx3api.shapan(self.serverdefault(server)))
async def jx3_qufuqiyu(self, event: AstrMessageEvent,adventureName: str = "阴阳两界", server: str = ""):
"""剑三 奇遇统计 奇遇名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.qiyu(adventureName,self.serverdefault(server)))
async def jx3_qiyugonglue(self, event: AstrMessageEvent,name: str):
"""剑三 奇遇攻略 奇遇名称"""
return await self.T2I_image_msg(event, lambda: self.jx3api.qiyugonglue(name))
async def jx3_hong(self, event: AstrMessageEvent,name: str = "易筋经"):
"""剑三 宏 心法"""
return await self.handler_plain_image_msg(event, lambda: self.jx3api.hong1(name), self.jx3api.hong2)
async def jx3_peizhuang(self, event: AstrMessageEvent,name: str = "易筋经", tags: str = ""):
"""剑三 配装 心法"""
return await self.plain_msg(event, lambda: self.jx3api.peizhuang( name,tags))
async def jx3_jinjia(self, event: AstrMessageEvent,server: str = "", limit:str = "15"):
"""剑三 金价 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.jinjia( self.serverdefault(server),limit))
async def jx3_wujia(self, event: AstrMessageEvent,Name: str = "秃盒", server: str = ""):
"""剑三 物价 外观名称"""
return await self.T2I_image_msg(event, lambda: self.jx3api.wujia(Name, self.serverdefault(server)))
async def jx3_jiaoyihang(self, event: AstrMessageEvent,Name: str = "守缺式",server: str = ""):
"""剑三 交易行 物品名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.jiaoyihang(Name, self.serverdefault(server)))
async def jx3_jueshemingpian(self, event: AstrMessageEvent, name: str = "飞翔大野猪", server: str = ""):
"""剑三 名片 角色 服务器"""
return await self.image_msg(event, lambda: self.jx3api.jueshemingpian( self.serverdefault(server),name))
async def jx3_shuijimingpian(self, event: AstrMessageEvent,force: str = "万花", body: str = "萝莉", server: str = ""):
"""剑三 随机名片 职业 体型 服务器"""
return await self.image_msg(event, lambda: self.jx3api.shuijimingpian(force,body, self.serverdefault(server)))
async def jx3_yanhuachaxun(self, event: AstrMessageEvent,name: str = "飞翔大野猪", server: str = ""):
"""剑三 烟花 角色 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.yanhuachaxun( self.serverdefault(server),name))
async def jx3_dilujilu(self, event: AstrMessageEvent,server: str = ""):
"""剑三 的卢 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.dilujilu( self.serverdefault(server)))
async def jx3_tuanduizhaomu(self, event: AstrMessageEvent,keyword: str = "25人普通会战弓月城", server: str = ""):
"""剑三 招募 副本 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.tuanduizhaomu( self.serverdefault(server),keyword))
async def jx3_zhanji(self, event: AstrMessageEvent,name: str = "飞翔大野猪", server: str = "", mode:str = "33"):
"""剑三 战绩 角色 服务器 类型"""
return await self.T2I_image_msg(event, lambda: self.jx3api.zhanji(name, self.serverdefault(server),mode))
async def jx3_qiyu(self, event: AstrMessageEvent,name: str = "飞翔大野猪", server: str = ""):
"""剑三 奇遇 角色名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.juesheqiyu(name, self.serverdefault(server)))
async def jx3_zhengyingpaimai(self, event: AstrMessageEvent,name: str = "玄晶", server: str = ""):
"""剑三 阵营拍卖 物品名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3api.zhengyingpaimai( self.serverdefault(server), name))
async def jx3_fuyaojjiutian(self, event: AstrMessageEvent,server: str = ""):
"""剑三 扶摇九天 服务器"""
return await self.plain_msg(event, lambda: self.jx3api.fuyaojjiutian( self.serverdefault(server)))
async def jx3_shuma(self, event: AstrMessageEvent,server: str = ""):
"""剑三 刷马 服务器"""
return await self.plain_msg(event, lambda: self.jx3api.shuma( self.serverdefault(server)))
async def jx3_pianzhi(self, event: AstrMessageEvent,qq: str):
"""剑三 骗子 QQ"""
return await self.plain_msg(event, lambda: self.jx3api.pianzhi(qq))
async def jx3_bagua(self, event: AstrMessageEvent,name: str = "818"):
"""剑三 八卦 类型"""
return await self.plain_msg(event, lambda: self.jx3api.bagua(name))
async def bilei_add(self, event: AstrMessageEvent,name: str, text: str):
"""避雷添加 名称 备注"""
return await self.plain_msg(event, lambda: self.bilei.add(name,text,event.get_sender_name()))
async def bilei_all(self, event: AstrMessageEvent):
"""避雷查看"""
return await self.T2I_image_msg(event, self.bilei.all)
async def bilei_select(self, event: AstrMessageEvent, name:str):
"""避雷查询"""
return await self.T2I_image_msg(event, lambda: self.bilei.select(name))
async def bilei_update(self, event: AstrMessageEvent, id:int, name: str, text: str):
"""避雷修改 ID 名称 备注"""
return await self.plain_msg(event, lambda: self.bilei.update(id,name,text,event.get_sender_name()))
async def bilei_delete(self, event: AstrMessageEvent, id:int):
"""避雷删除 ID"""
return await self.plain_msg(event, lambda: self.bilei.delete(id))
async def jx3_kaifhujiank(self, event: AstrMessageEvent):
"""剑三 开服监控"""
return_msg = await self.jx3at.get_task_info("kfts")
await event.send(event.plain_result(return_msg))
async def jx3_xinwenzhixun(self, event: AstrMessageEvent):
"""剑三 新闻推送"""
return_msg = await self.jx3at.get_task_info("xwts")
await event.send(event.plain_result(return_msg))
async def jx3_shuamamsg(self, event: AstrMessageEvent):
"""剑三 刷马推送"""
return_msg = await self.jx3at.get_task_info("smts")
await event.send(event.plain_result(return_msg))
async def jx3_chitusg(self, event: AstrMessageEvent):
"""剑三 赤兔推送"""
return_msg = await self.jx3at.get_task_info("ctts")
await event.send(event.plain_result(return_msg))
+8
View File
@@ -9,10 +9,18 @@ class AsyncSQLiteDB:
self.db_path = db_path
self.conn: Optional[aiosqlite.Connection] = None
# ======================
# 生命周期
# ======================
async def __aenter__(self):
await self.connect()
return self
async def __aexit__(self, exc_type, exc, tb):
await self.close()
async def connect(self):
self.conn = await aiosqlite.connect(self.db_path)
self.conn.row_factory = aiosqlite.Row
-6
View File
@@ -1,6 +0,0 @@
{
"kfjk": true,
"xwzx": 3174,
"smxx": 0,
"ctxx": 0
}
Binary file not shown.
+152 -507
View File
@@ -1,73 +1,45 @@
# pyright: reportOptionalMemberAccess=false
import json
import shutil
import pathlib
import asyncio
import inspect
from pathlib import Path
from typing import Union
from astrbot.api.event import filter, AstrMessageEvent, MessageEventResult, MessageChain
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.api.star import Context, Star, register, StarTools
from astrbot.api import logger
from astrbot.api import AstrBotConfig
from astrbot.core.utils.session_waiter import (
SessionController,
session_waiter,
)
from .core.sqlite import AsyncSQLiteDB
from .core.jx3_data import JX3Service
from .core.async_task import AsyncTask
from .core.bilei_data import BiLeidata
from .core.message import MessageBuilder
@register("astrbot_plugin_jx3",
"fxdyz",
"通过接口调用剑网三API接口获取游戏数据,理发送。",
"1.0.0",
"https://github.com/qsc20001102/astrbot_plugin_jx3api.git"
"通过调用剑网三API接口获取游戏数据,理发送。",
"1.1.0",
"https://github.com/qsc20001102/astrbot_plugin_jx3api"
)
class Jx3ApiPlugin(Star):
def __init__(self, context: Context, config: AstrBotConfig):
super().__init__(context)
#获取配置
# 获取插件配置
self.conf = config
# 本地数据存储路径
self.local_data_dir = StarTools.get_data_dir("astrbot_plugin_jx3")
# 插件数据存储路径
self.data_file_path = Path(__file__).parent / "data"
# SQLite本地路径
self.sqlite_path = Path(self.local_data_dir) /"sqlite.db"
logger.info(f"本地数据文件路径:{self.sqlite_path}")
# SQLite插件路径
self.sqlite_plugin = Path(self.data_file_path) /"sqlite.db"
logger.info(f"插件数据文件路径:{self.sqlite_plugin}")
# 读取API配置文件
self.api_file_path = self.data_file_path / "api_config.json"
with open(self.api_file_path, 'r', encoding='utf-8') as f:
self.api_config = json.load(f)
# 初始化数据
# 指令前缀功能
self.prefix_en = self.conf.get("prefix").get("enable")
self.prefix_text = self.conf.get("prefix").get("text")
if not self.prefix_text:
self.prefix_text = "剑三"
if self.prefix_en:
logger.info(f"已启用指令前缀功能,前缀为:{self.prefix_text}")
# 指令前缀
self.prefix = self.conf.get("prefix",{})
if self.prefix.get("enable"):
logger.info(f"已启用指令前缀功能,前缀为:{self.prefix.get('text')}")
else:
logger.info(f"未启用指令前缀功能。")
# 默认服务器
self.server = self.conf.get("server", "梦江南")
self.server = self.conf.get("server","梦江南")
logger.info(f"配置加载默认服务器:{self.server}")
# 获取数据文件路径
self.get_data_path()
# 构造所有类
self.create_all()
# 声明指令集
self.command_map = {}
@@ -76,50 +48,21 @@ class Jx3ApiPlugin(Star):
async def initialize(self):
"""可选择实现异步的插件初始化方法,当实例化该插件类之后会自动调用该方法。"""
# --- 调用函数完成检查和复制 ---
try:
loop = asyncio.get_running_loop()
self.file_local_data = await loop.run_in_executor(
None,
self.check_and_copy_db,
self.local_data_dir,
"local_async.json",
self.data_file_path
)
except FileNotFoundError as e:
logger.critical(f"插件初始化失败:{e}")
raise
# 数据库初始化
await self.init_bilei_data()
await self.init_tuishong_data()
try:
# sqlite 实例化
self.sql_db = AsyncSQLiteDB(self.sqlite_path) # pyright: ignore[reportArgumentType]
await self.sql_db.connect()
await self.sql_db.execute("""
CREATE TABLE IF NOT EXISTS bilei(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
text TEXT,
time TEXT,
user TEXT
)
""")
self.sql_db_plugin = AsyncSQLiteDB(self.sqlite_plugin) # pyright: ignore[reportArgumentType]
await self.sql_db_plugin.connect()
# 连接插件数据
await self.plugin_sql_db.connect()
# 避雷功能 实例化
self.bilei = BiLeidata(self.sql_db)
# 剑三功能 实例化
self.jx3fun = JX3Service(self.api_config, self.conf, self.sql_db_plugin)
# 后台推送 实例化
self.at = AsyncTask(self.context, self.conf, self.jx3fun)
await self.at.init_tasks()
# 开启后台推送
await self.jx3at.init_tasks()
except Exception as e:
if hasattr(self, "at"):
await self.at.destroy()
logger.error(f"功能模块初始化失败: {e}")
if self.jx3at is not None:
await self.jx3at.destroy()
logger.exception("功能模块初始化失败")
raise
# 指令集
@@ -130,49 +73,135 @@ class Jx3ApiPlugin(Star):
async def terminate(self):
"""可选择实现异步的插件销毁方法,当插件被卸载/停用时会调用。"""
if self.at:
await self.at.destroy()
self.at = None
if self.jx3fun:
await self.jx3fun.close()
self.jx3fun = None
if self.jx3at:
await self.jx3at.destroy()
if self.sql_db:
await self.sql_db.close()
self.sql_db = None
if self.jx3api:
await self.jx3api.close()
if self.sql_db_plugin:
await self.sql_db_plugin.close()
self.sql_db_plugin = None
if self.local_sql_db:
await self.local_sql_db.close()
if self.plugin_sql_db:
await self.plugin_sql_db.close()
logger.info("jx3api插件已卸载/停用")
def check_and_copy_db(self, local_data_dir: Union[str, Path], db_filename: str, default_db_dir: Union[str, Path]) -> pathlib.Path:
"""
检查本地数据目录中是否存在指定的数据库文件。
如果不存在,则从默认目录复制该文件。
"""
# 目标路径
target_dir = pathlib.Path(local_data_dir)
target_file_path = target_dir / db_filename
# 源文件路径
source_file_path = pathlib.Path(default_db_dir) / db_filename
# 假设默认文件名为 local_data.db
if not target_file_path.exists():
logger.warning(f"本地数据库文件 {target_file_path.name} 不存在,正在从默认位置复制...")
# 1. 确保目标文件夹存在
target_dir.mkdir(parents=True, exist_ok=True)
# 2. 检查源文件是否存在
if not source_file_path.exists():
raise FileNotFoundError(f"默认数据库源文件未找到!请检查路径: {source_file_path}")
# 3. 复制文件
shutil.copy(source_file_path, target_file_path)
logger.info(f"数据库文件已成功复制到: {target_file_path}")
else:
logger.info(f"本地数据库文件 {target_file_path} 已存在,跳过复制。")
return target_file_path
def get_data_path(self):
"""获取数据文件路径"""
# 本地数据存储路径
self.local_data_dir = StarTools.get_data_dir("astrbot_plugin_jx3")
# 插件数据存储路径
self.plugin_data_dir = Path(__file__).parent / "data"
# SQLite本地路径
self.local_data_path = self.local_data_dir / "local_data.db"
# SQLite插件路径
self.plugin_data_path = self.plugin_data_dir /"plugin_data.db"
# API配置文件路径
self.api_data_path = self.plugin_data_dir / "api_config.json"
# 数据路径打印
logger.debug(f"本地数据路径: {self.local_data_path}")
logger.debug(f"插件数据路径: {self.plugin_data_path}")
logger.debug(f"API配置文件路径: {self.api_data_path}")
def create_all(self):
"""构造所有类"""
# 数据库实例化
self.local_sql_db = AsyncSQLiteDB(str(self.local_data_path))
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.jx3at = AsyncTask(self.context, self.conf, self.jx3api, self.local_sql_db)
self.jx3cmd = MessageBuilder(self.server, self.jx3api, self.bilei, self.jx3at)
async def init_bilei_data(self):
"""初始化避雷数据表"""
# 连接本地数据
await self.local_sql_db.connect()
# 创建bilei表
await self.local_sql_db.execute("""
CREATE TABLE IF NOT EXISTS bilei(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
text TEXT,
time TEXT,
user TEXT
)
""")
async def init_tuishong_data(self):
"""初始化推送数据表"""
# 创建tuishong表
await self.local_sql_db.execute("""
CREATE TABLE IF NOT EXISTS tuishong (
id INTEGER PRIMARY KEY CHECK (id = 1),
kfts INTEGER DEFAULT 1,
xwts INTEGER DEFAULT 0,
smts INTEGER DEFAULT 0,
ctts INTEGER DEFAULT 0
)
""")
await self.local_sql_db.execute("""
INSERT OR IGNORE INTO tuishong (id)
VALUES (1)
""")
def ini_command_map(self):
"""初始化指令集"""
self.command_map = {
"功能": self.jx3cmd.jx3_helps,
"日常": self.jx3cmd.jx3_richang,
"日常预测": self.jx3cmd.jx3_richangyuche,
"名望": self.jx3cmd.jx3_xingxiashijian,
"开服": self.jx3cmd.jx3_kaifu,
"全服状态": self.jx3cmd.jx3_zhuangtai,
"骚话": self.jx3cmd.jx3_shaohua,
"技改": self.jx3cmd.jx3_jigai,
"公告": self.jx3cmd.jx3_xinwen,
"科举": self.jx3cmd.jx3_keju,
"花价": self.jx3cmd.jx3_huajia,
"装饰": self.jx3cmd.jx3_zhuangshi,
"器物": self.jx3cmd.jx3_qiwu,
"沙盘": self.jx3cmd.jx3_shapan,
"统计": self.jx3cmd.jx3_qufuqiyu,
"攻略": self.jx3cmd.jx3_qiyugonglue,
"": self.jx3cmd.jx3_hong,
"配装": self.jx3cmd.jx3_peizhuang,
"金价": self.jx3cmd.jx3_jinjia,
"物价": self.jx3cmd.jx3_wujia,
"交易行": self.jx3cmd.jx3_jiaoyihang,
"名片": self.jx3cmd.jx3_jueshemingpian,
"随机名片": self.jx3cmd.jx3_shuijimingpian,
"烟花": self.jx3cmd.jx3_yanhuachaxun,
"的卢": self.jx3cmd.jx3_dilujilu,
"招募": self.jx3cmd.jx3_tuanduizhaomu,
"战绩": self.jx3cmd.jx3_zhanji,
"奇遇": self.jx3cmd.jx3_qiyu,
"拍卖": self.jx3cmd.jx3_zhengyingpaimai,
"扶摇九天": self.jx3cmd.jx3_fuyaojjiutian,
"刷马": self.jx3cmd.jx3_shuma,
"骗子": self.jx3cmd.jx3_pianzhi,
"八卦": self.jx3cmd.jx3_bagua,
"开服推送": self.jx3cmd.jx3_kaifhujiank,
"新闻推送": self.jx3cmd.jx3_xinwenzhixun,
"刷马推送": self.jx3cmd.jx3_shuamamsg,
"赤兔推送": self.jx3cmd.jx3_chitusg,
"避雷添加": self.jx3cmd.bilei_add,
"避雷查看": self.jx3cmd.bilei_all,
"避雷查询": self.jx3cmd.bilei_select,
"避雷修改": self.jx3cmd.bilei_update,
"避雷删除": self.jx3cmd.bilei_delete,
}
def parse_message(self, text: str) -> list[str] | None:
@@ -182,8 +211,8 @@ class Jx3ApiPlugin(Star):
return None
# 前缀模式
if self.prefix_en:
prefix = self.prefix_text
if self.prefix.get("enable"):
prefix = self.prefix.get("text")
if text.startswith(prefix):
text = text[len(prefix):].strip()
else:
@@ -237,6 +266,8 @@ class Jx3ApiPlugin(Star):
if not self.command_map:
logger.debug("插件尚未初始化完成,忽略消息")
return
# 获取消息
parts = self.parse_message(event.message_str)
if not parts:
logger.debug("未触发指令,忽略消息")
@@ -258,394 +289,8 @@ class Jx3ApiPlugin(Star):
yield event.plain_result("参数错误或执行失败")
def ini_command_map(self):
"""初始化指令集"""
self.command_map = {
"功能": self.jx3_helps,
"日常": self.jx3_richang,
"日常预测": self.jx3_richangyuche,
"名望": self.jx3_xingxiashijian,
"开服": self.jx3_kaifu,
"全服状态": self.jx3_zhuangtai,
"骚话": self.jx3_shaohua,
"技改": self.jx3_jigai,
"公告": self.jx3_xinwen,
"科举": self.jx3_keju,
"花价": self.jx3_huajia,
"装饰": self.jx3_zhuangshi,
"器物": self.jx3_qiwu,
"沙盘": self.jx3_shapan,
"奇遇统计": self.jx3_qufuqiyu,
"奇遇攻略": self.jx3_qiyugonglue,
"": self.jx3_hong,
"配装": self.jx3_peizhuang,
"金价": self.jx3_jinjia,
"物价": self.jx3_wujia,
"交易行": self.jx3_jiaoyihang,
"名片": self.jx3_jueshemingpian,
"随机名片": self.jx3_shuijimingpian,
"烟花": self.jx3_yanhuachaxun,
"的卢": self.jx3_dilujilu,
"招募": self.jx3_tuanduizhaomu,
"战绩": self.jx3_zhanji,
"奇遇": self.jx3_qiyu,
"阵营拍卖": self.jx3_zhengyingpaimai,
"扶摇九天": self.jx3_fuyaojjiutian,
"刷马": self.jx3_shuma,
"骗子": self.jx3_pianzhi,
"八卦": self.jx3_bagua,
"避雷添加": self.bilei_add,
"避雷查看": self.bilei_all,
"避雷查询": self.bilei_select,
"避雷修改": self.bilei_update,
"避雷删除": self.bilei_delete,
"开服监控": self.jx3_kaifhujiank,
"新闻推送": self.jx3_xinwenzhixun,
"刷马推送": self.jx3_shuamamsg,
"赤兔推送": self.jx3_chitusg,
}
def serverdefault(self,server):
"""加载配置默认服务器"""
if server == "":
return self.server
return server
async def plain_msg(self, event: AstrMessageEvent, action):
"""最终将数据整理成文本发送"""
data= await action()
try:
if data["code"] == 200:
await event.send( event.plain_result(data["data"]))
else:
await event.send(event.plain_result(data["msg"]))
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await event.send(event.plain_result("猪脑过载,请稍后再试"))
async def T2I_image_msg(self, event: AstrMessageEvent, action):
"""最终将数据渲染成图片发送"""
data = await action()
try:
if data["code"] == 200:
url = await self.html_render(data["temp"], data["data"], options={})
await event.send(event.image_result(url))
else:
await event.send(event.plain_result(data["msg"]))
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await event.send(event.plain_result("猪脑过载,请稍后再试"))
async def image_msg(self, event: AstrMessageEvent, action):
"""最终将数据整理成图片发送"""
data = await action()
try:
if data["code"] == 200:
await event.send(event.image_result(data["data"]))
else:
await event.send(event.plain_result(data["msg"]))
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await event.send(event.plain_result("猪脑过载,请稍后再试"))
async def handler_plain_image_msg(self, event: AstrMessageEvent, action1, action2):
"""两轮会话消息发送通用,先文本列表等反馈序号在发送图片"""
# 会话触发
try:
# 获取一轮数据
data = await action1()
if data["code"] == 200:
# 发送一轮消息
await event.send(event.plain_result(data["msg"]))
# 获取触发用户ID
user_id = event.get_sender_id()
# 二轮会话流程
@session_waiter(timeout=30)
async def macro_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
# 判断数字是否在有效值内
num = int(msg)
if num < 1 or num > data["data"]["num"]:
await new_event.send(
MessageChain().message("无效序号,结束会话")
)
controller.stop()
return
# 获取二轮数据
try:
data1 = await action2(data["data"]["list"][num])
if data1["code"] != 200:
await new_event.send(
MessageChain().message("获取详细数据失败")
)
controller.stop()
return
# 消息拼接发送
chain = MessageChain()
msg_text = data1["data"]
chain.message(msg_text)
if data1["temp"] != "":
url = await self.html_render(data1["temp"], {}, options={})
chain.url_image(url)
await new_event.send(chain)
except Exception as e:
logger.error(f"功能函数执行错误: {e}")
await new_event.send(
MessageChain().message("猪脑过载,请稍后再试")
)
controller.stop()
# 二轮会话激活
try:
await macro_select_waiter(event)
except TimeoutError:
await event.send(event.plain_result("选择超时,已结束会话"))
except Exception:
logger.error("宏选择发生异常", exc_info=True)
else:
await event.send(event.plain_result(f"未搜索到相关内容"))
return
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.jx3fun.helps)
async def jx3_richang(self, event: AstrMessageEvent,server: str = "" ,num: int = 0):
"""剑三 日常 服务器 天数"""
return await self.plain_msg(event, lambda: self.jx3fun.richang(self.serverdefault(server),num))
async def jx3_richangyuche(self, event: AstrMessageEvent):
"""剑三 日常预测"""
return await self.T2I_image_msg(event, self.jx3fun.richangyuche)
async def jx3_xingxiashijian(self, event: AstrMessageEvent,name: str = "穹野卫"):
"""剑三 名望"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.xingxiashijian(name))
async def jx3_kaifu(self, event: AstrMessageEvent,server: str = ""):
"""剑三 开服 服务器"""
return await self.plain_msg(event, lambda: self.jx3fun.kaifu(self.serverdefault(server)))
async def jx3_zhuangtai(self, event: AstrMessageEvent):
"""剑三 状态"""
return await self.T2I_image_msg(event, self.jx3fun.zhuangtai)
async def jx3_shaohua(self, event: AstrMessageEvent,):
"""剑三 骚话"""
return await self.plain_msg(event, self.jx3fun.shaohua)
async def jx3_jigai(self, event: AstrMessageEvent,):
"""剑三 技改"""
return await self.plain_msg(event, self.jx3fun.jigai)
async def jx3_xinwen(self, event: AstrMessageEvent,num:int = 5):
"""剑三 新闻"""
return await self.plain_msg(event, lambda: self.jx3fun.xinwen(num))
async def jx3_keju(self, event: AstrMessageEvent,subject: str, limit: int = 5):
"""剑三 科举"""
return await self.plain_msg(event, lambda: self.jx3fun.keju(subject,limit))
async def jx3_huajia(self, event: AstrMessageEvent, name: str= "", server: str = "", map: str= ""):
"""剑三 花价 名称 服务器 地图"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.huajia(self.serverdefault(server),name,map))
async def jx3_zhuangshi(self, event: AstrMessageEvent, name: str):
"""剑三 装饰 名称"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.zhuangshi(name))
async def jx3_qiwu(self, event: AstrMessageEvent, name: str):
"""剑三 器物 地图名称"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.qiwu(name))
async def jx3_shapan(self, event: AstrMessageEvent,server: str = ""):
"""剑三 沙盘 服务器"""
return await self.image_msg(event, lambda: self.jx3fun.shapan(self.serverdefault(server)))
async def jx3_qufuqiyu(self, event: AstrMessageEvent,adventureName: str = "阴阳两界", server: str = ""):
"""剑三 奇遇统计 奇遇名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.qiyu(adventureName,self.serverdefault(server)))
async def jx3_qiyugonglue(self, event: AstrMessageEvent,name: str):
"""剑三 奇遇攻略 奇遇名称"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.qiyugonglue(name))
async def jx3_hong(self, event: AstrMessageEvent,name: str = "易筋经"):
"""剑三 宏 心法"""
return await self.handler_plain_image_msg(event, lambda: self.jx3fun.hong1(name), self.jx3fun.hong2)
async def jx3_peizhuang(self, event: AstrMessageEvent,name: str = "易筋经", tags: str = ""):
"""剑三 配装 心法"""
return await self.plain_msg(event, lambda: self.jx3fun.peizhuang( name,tags))
async def jx3_jinjia(self, event: AstrMessageEvent,server: str = "", limit:str = "15"):
"""剑三 金价 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.jinjia( self.serverdefault(server),limit))
async def jx3_wujia(self, event: AstrMessageEvent,Name: str = "秃盒", server: str = ""):
"""剑三 物价 外观名称"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.wujia(Name, self.serverdefault(server)))
async def jx3_jiaoyihang(self, event: AstrMessageEvent,Name: str = "守缺式",server: str = ""):
"""剑三 交易行 物品名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.jiaoyihang(Name, self.serverdefault(server)))
async def jx3_jueshemingpian(self, event: AstrMessageEvent, name: str = "飞翔大野猪", server: str = ""):
"""剑三 名片 角色 服务器"""
return await self.image_msg(event, lambda: self.jx3fun.jueshemingpian( self.serverdefault(server),name))
async def jx3_shuijimingpian(self, event: AstrMessageEvent,force: str = "万花", body: str = "萝莉", server: str = ""):
"""剑三 随机名片 职业 体型 服务器"""
return await self.image_msg(event, lambda: self.jx3fun.shuijimingpian(force,body, self.serverdefault(server)))
async def jx3_yanhuachaxun(self, event: AstrMessageEvent,name: str = "飞翔大野猪", server: str = ""):
"""剑三 烟花 角色 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.yanhuachaxun( self.serverdefault(server),name))
async def jx3_dilujilu(self, event: AstrMessageEvent,server: str = ""):
"""剑三 的卢 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.dilujilu( self.serverdefault(server)))
async def jx3_tuanduizhaomu(self, event: AstrMessageEvent,keyword: str = "25人普通会战弓月城", server: str = ""):
"""剑三 招募 副本 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.tuanduizhaomu( self.serverdefault(server),keyword))
async def jx3_zhanji(self, event: AstrMessageEvent,name: str = "飞翔大野猪", server: str = "", mode:str = "33"):
"""剑三 战绩 角色 服务器 类型"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.zhanji(name, self.serverdefault(server),mode))
async def jx3_qiyu(self, event: AstrMessageEvent,name: str = "飞翔大野猪", server: str = ""):
"""剑三 奇遇 角色名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.juesheqiyu(name, self.serverdefault(server)))
async def jx3_zhengyingpaimai(self, event: AstrMessageEvent,name: str = "玄晶", server: str = ""):
"""剑三 阵营拍卖 物品名称 服务器"""
return await self.T2I_image_msg(event, lambda: self.jx3fun.zhengyingpaimai( self.serverdefault(server), name))
async def jx3_fuyaojjiutian(self, event: AstrMessageEvent,server: str = ""):
"""剑三 扶摇九天 服务器"""
return await self.plain_msg(event, lambda: self.jx3fun.fuyaojjiutian( self.serverdefault(server)))
async def jx3_shuma(self, event: AstrMessageEvent,server: str = ""):
"""剑三 刷马 服务器"""
return await self.plain_msg(event, lambda: self.jx3fun.shuma( self.serverdefault(server)))
async def jx3_pianzhi(self, event: AstrMessageEvent,qq: str):
"""剑三 骗子 QQ"""
return await self.plain_msg(event, lambda: self.jx3fun.pianzhi(qq))
async def jx3_bagua(self, event: AstrMessageEvent,name: str = "818"):
"""剑三 八卦 类型"""
return await self.plain_msg(event, lambda: self.jx3fun.bagua(name))
async def bilei_add(self, event: AstrMessageEvent,name: str, text: str):
"""避雷添加 名称 备注"""
return await self.plain_msg(event, lambda: self.bilei.add(name,text,event.get_sender_name()))
async def bilei_all(self, event: AstrMessageEvent):
"""避雷查看"""
return await self.T2I_image_msg(event, self.bilei.all)
async def bilei_select(self, event: AstrMessageEvent, name:str):
"""避雷查询"""
return await self.T2I_image_msg(event, lambda: self.bilei.select(name))
async def bilei_update(self, event: AstrMessageEvent, id:int, name: str, text: str):
"""避雷修改 ID 名称 备注"""
return await self.plain_msg(event, lambda: self.bilei.update(id,name,text,event.get_sender_name()))
async def bilei_delete(self, event: AstrMessageEvent, id:int):
"""避雷删除 ID"""
return await self.plain_msg(event, lambda: self.bilei.delete(id))
async def jx3_kaifhujiank(self, event: AstrMessageEvent):
"""剑三 开服监控"""
return_msg = await self.at.get_task_info("kfjk")
await event.send(event.plain_result(return_msg))
async def jx3_xinwenzhixun(self, event: AstrMessageEvent):
"""剑三 新闻推送"""
return_msg = await self.at.get_task_info("xwzx")
await event.send(event.plain_result(return_msg))
async def jx3_shuamamsg(self, event: AstrMessageEvent):
"""剑三 刷马推送"""
return_msg = await self.at.get_task_info("smxx")
await event.send(event.plain_result(return_msg))
async def jx3_chitusg(self, event: AstrMessageEvent):
"""剑三 赤兔推送"""
return_msg = await self.at.get_task_info("ctxx")
await event.send(event.plain_result(return_msg))
+2 -2
View File
@@ -1,6 +1,6 @@
name: astrbot_plugin_jx3
display_name: 剑网三游戏数据查询工具
desc: 通过接口调用剑网三API接口获取游戏数据
version: v1.0.0
desc: 通过接口调用剑网三API接口获取游戏数据,处理发送。
version: v1.1.0
author: 飞翔大野猪
repo: https://github.com/qsc20001102/astrbot_plugin_jx3
+140 -137
View File
@@ -1,127 +1,118 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>剑三插件功能</title>
<style>
body {
<meta charset="UTF-8">
<title>剑三插件功能</title>
<style>
body {
margin: 0;
padding: 40px 20px;
background: linear-gradient(180deg, #f5f7fb 0%, #eef1f7 100%);
color: #2c2c33;
font-family: "Microsoft YaHei", Arial, sans-serif;
}
}
/* 页面主体宽度控制 */
.container {
max-width: 980px;
.container {
max-width: 1100px;
margin: 0 auto;
}
}
/* 顶部标题 */
.header {
margin-bottom: 36px;
}
.header {
margin-bottom: 40px;
}
.header h1 {
font-size: 42px;
margin: 0 0 10px;
.header h1 {
font-size: 44px;
margin: 0 0 12px;
color: #1f2a44;
}
}
.header p {
font-size: 20px;
.header p {
font-size: 22px;
color: #5a627a;
margin: 0;
}
}
/* 分组 */
.group {
margin-bottom: 42px;
}
.group {
margin-bottom: 50px;
}
.group-title {
font-size: 30px;
.group-title {
font-size: 32px;
font-weight: bold;
margin-bottom: 18px;
padding-left: 14px;
margin-bottom: 20px;
padding-left: 16px;
border-left: 6px solid #4f7cff;
color: #1f2a44;
}
}
/* 单列 */
.command-grid {
.command-grid {
display: grid;
grid-template-columns: 1fr;
gap: 14px;
}
gap: 16px;
}
/* 指令行 */
.command {
.command {
background: #ffffff;
border-radius: 12px;
padding: 14px 18px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
border-radius: 14px;
padding: 16px 22px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
position: relative;
overflow: hidden;
display: inline-flex;
display: grid;
grid-template-columns: 180px 300px 1fr;
align-items: center;
gap: 18px;
}
gap: 22px;
}
.command::before {
.command::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 4px;
width: 5px;
height: 100%;
background: #4f7cff;
}
background: linear-gradient(180deg, #4f7cff, #3d5edb);
}
.cmd-name {
font-size: 24px;
font-weight: bold;
color: #2b3a67;
white-space: nowrap;
min-width: 140px;
}
.cmd-usage {
font-size: 22px;
.cmd-name {
font-size: 26px;
font-weight: 700;
color: #1f2a44;
background: #f0f3ff;
padding: 6px 12px;
border-radius: 6px;
font-family: Consolas, "Courier New", monospace;
white-space: nowrap;
}
}
/* 提示 */
.tip {
margin-top: 40px;
font-size: 16px;
.cmd-usage {
font-size: 22px;
color: #2b3a67;
background: #eef2ff;
padding: 8px 14px;
border-radius: 8px;
font-family: Consolas, "Courier New", monospace;
}
.cmd-desc {
font-size: 20px;
color: #5a627a;
line-height: 1.6;
}
.tip {
margin-top: 50px;
font-size: 18px;
color: #5a5f73;
background: #fffbe6;
padding: 16px 20px;
padding: 18px 24px;
border-left: 6px solid #ffcc00;
border-radius: 10px;
line-height: 1.6;
}
/* 小屏适配 */
@media (max-width: 640px) {
.cmd-name {
min-width: auto;
}
border-radius: 12px;
line-height: 1.8;
}
@media (max-width: 900px) {
.command {
flex-wrap: wrap;
grid-template-columns: 1fr;
gap: 10px;
}
}
</style>
}
</style>
</head>
<body>
@@ -132,76 +123,88 @@
<p>astrbot_plugin_jx3 指令说明与使用示例</p>
</div>
<!-- 基础功能 -->
<div class="group">
<div class="group-title">基础功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">日常活动</div><div class="cmd-usage">日常 [服务器] [天数]</div></div>
<div class="command"><div class="cmd-name">日常预测</div><div class="cmd-usage">日常预测</div></div>
<div class="command"><div class="cmd-name">名望事件</div><div class="cmd-usage">名望 [穹野卫]</div></div>
<div class="command"><div class="cmd-name">开服查询</div><div class="cmd-usage">开服 [服务器]</div></div>
<div class="command"><div class="cmd-name">全服状态</div><div class="cmd-usage">全服状态 [服务器]</div></div>
<div class="command"><div class="cmd-name">随机骚话</div><div class="cmd-usage">骚话</div></div>
<div class="command"><div class="cmd-name">最新技改</div><div class="cmd-usage">技改</div></div>
<div class="command"><div class="cmd-name">官方公告</div><div class="cmd-usage">公告 [数量]</div></div>
<div class="command"><div class="cmd-name">科举答题</div><div class="cmd-usage">科举 内容</div></div>
<div class="command"><div class="cmd-name">家园鲜花</div><div class="cmd-usage">花价 名称 [服务器] [家园地图]</div></div>
<div class="command"><div class="cmd-name">家园装饰</div><div class="cmd-usage">装饰 名称</div></div>
<div class="command"><div class="cmd-name">器物图谱</div><div class="cmd-usage">器物 地图名称</div></div>
<div class="command"><div class="cmd-name">阵营沙盘</div><div class="cmd-usage">沙盘 [服务器]</div></div>
<div class="command"><div class="cmd-name">奇遇统计</div><div class="cmd-usage">奇遇统计 奇遇名称 [服务器]</div></div>
<div class="command"><div class="cmd-name">奇遇攻略</div><div class="cmd-usage">奇遇攻略 奇遇名称</div></div>
<div class="command"><div class="cmd-name">魔盒宏</div><div class="cmd-usage">宏 心法</div></div>
<div class="command"><div class="cmd-name">魔盒配装</div><div class="cmd-usage">配装 心法 筛选</div></div>
</div>
<div class="group-title">基础功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">日常活动</div><div class="cmd-usage">日常 [服务器] [天数]</div><div class="cmd-desc">天数:0今天 1明天 2后天</div></div>
<div class="command"><div class="cmd-name">日常预测</div><div class="cmd-usage">日常预测</div><div class="cmd-desc">当前日期前后15天日常</div></div>
<div class="command"><div class="cmd-name">名望事件</div><div class="cmd-usage">名望 [穹野卫]</div><div class="cmd-desc">楚天社 云从社 披风会 穹野卫</div></div>
<div class="command"><div class="cmd-name">开服查询</div><div class="cmd-usage">开服 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">全服状态</div><div class="cmd-usage">全服状态 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">随机骚话</div><div class="cmd-usage">骚话</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">最新技改</div><div class="cmd-usage">技改</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">官方公告</div><div class="cmd-usage">公告 [数量]</div><div class="cmd-desc">获取最新官方公告,数量默认为5条</div></div>
<div class="command"><div class="cmd-name">科举答题</div><div class="cmd-usage">科举 内容</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">家园鲜花</div><div class="cmd-usage">花价 名称 [服务器] [家园地图]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">家园装饰</div><div class="cmd-usage">装饰 名称</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">器物图谱</div><div class="cmd-usage">器物 地图名称</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">阵营沙盘</div><div class="cmd-usage">沙盘 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">奇遇统计</div><div class="cmd-usage">统计 奇遇名称 [服务器]</div><div class="cmd-desc">统计指定奇遇触发次数</div></div>
<div class="command"><div class="cmd-name">奇遇攻略</div><div class="cmd-usage">攻略 奇遇名称</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">魔盒</div><div class="cmd-usage"> 心法</div><div class="cmd-desc">查询指定心法推荐宏设置</div></div>
<div class="command"><div class="cmd-name">魔盒配装</div><div class="cmd-usage">配装 心法 [筛选]</div><div class="cmd-desc">PvP PvE</div></div>
</div>
</div>
<!-- 进阶功能 -->
<div class="group">
<div class="group-title">进阶功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">金价查询</div><div class="cmd-usage">金价 [服务器]</div></div>
<div class="command"><div class="cmd-name">外观物价</div><div class="cmd-usage">物价 外观名称 [服务器]</div></div>
<div class="command"><div class="cmd-name">交易行</div><div class="cmd-usage">交易行 物品名称 [服务器]</div></div>
<div class="command"><div class="cmd-name">角色名片</div><div class="cmd-usage">名片 角色名 [服务器]</div></div>
<div class="command"><div class="cmd-name">随机名片</div><div class="cmd-usage">随机名片 职业 体型 [服务器]</div></div>
<div class="command"><div class="cmd-name">烟花记录</div><div class="cmd-usage">烟花 角色名 [服务器]</div></div>
<div class="command"><div class="cmd-name">的卢记录</div><div class="cmd-usage">的卢 [服务器]</div></div>
<div class="command"><div class="cmd-name">副本招募</div><div class="cmd-usage">招募 副本名称 [服务器]</div></div>
<div class="command"><div class="cmd-name">角色战绩</div><div class="cmd-usage">战绩 角色名 [服务器]</div></div>
<div class="command"><div class="cmd-name">角色奇遇</div><div class="cmd-usage">奇遇 角色名 [服务器]</div></div>
<div class="command"><div class="cmd-name">阵营拍卖</div><div class="cmd-usage">阵营拍卖 物品名称 [服务器]</div></div>
<div class="command"><div class="cmd-name">扶摇九天</div><div class="cmd-usage">扶摇九天 [服务器]</div></div>
<div class="command"><div class="cmd-name">刷马</div><div class="cmd-usage">刷马 [服务器]</div></div>
<div class="command"><div class="cmd-name">骗子查询</div><div class="cmd-usage">骗子 QQ号</div></div>
<div class="command"><div class="cmd-name">八卦记录</div><div class="cmd-usage">八卦 类型</div></div>
</div>
<div class="group-title">进阶功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">金价查询</div><div class="cmd-usage">金价 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">外观物价</div><div class="cmd-usage">物价 外观名称 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">交易行</div><div class="cmd-usage">交易行 物品名称 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">角色名片</div><div class="cmd-usage">名片 角色名 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">随机名片</div><div class="cmd-usage">随机名片 职业 体型 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">烟花记录</div><div class="cmd-usage">烟花 角色名 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">的卢记录</div><div class="cmd-usage">的卢 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">副本招募</div><div class="cmd-usage">招募 副本名称 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">角色战绩</div><div class="cmd-usage">战绩 角色名 [服务器]</div><div class="cmd-desc">33</div></div>
<div class="command"><div class="cmd-name">角色奇遇</div><div class="cmd-usage">奇遇 角色名 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">阵营拍卖</div><div class="cmd-usage">拍卖 物品名称 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">扶摇九天</div><div class="cmd-usage">扶摇九天 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">刷马</div><div class="cmd-usage">刷马 [服务器]</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">骗子查询</div><div class="cmd-usage">骗子 QQ号</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">八卦记录</div><div class="cmd-usage">八卦 类型</div><div class="cmd-desc">818 616 避雷</div></div>
</div>
</div>
<!-- 推送功能 -->
<div class="group">
<div class="group-title">推送功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">开服监控</div><div class="cmd-usage">开服监控</div></div>
<div class="command"><div class="cmd-name">新闻推送</div><div class="cmd-usage">新闻推送</div></div>
<div class="command"><div class="cmd-name">刷马推送</div><div class="cmd-usage">刷马推送</div></div>
<div class="command"><div class="cmd-name">赤兔推送</div><div class="cmd-usage">赤兔推送</div></div>
</div>
<div class="group-title">推送功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">开服推送</div><div class="cmd-usage">开服推送</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">新闻推送</div><div class="cmd-usage">新闻推送</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">刷马推送</div><div class="cmd-usage">刷马推送</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">赤兔推送</div><div class="cmd-usage">赤兔推送</div><div class="cmd-desc"></div></div>
</div>
</div>
<!-- 避雷功能 -->
<div class="group">
<div class="group-title">避雷功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">避雷查看</div><div class="cmd-usage">避雷查看</div></div>
<div class="command"><div class="cmd-name">避雷添加</div><div class="cmd-usage">避雷添加 名称 备注</div></div>
<div class="command"><div class="cmd-name">避雷删除</div><div class="cmd-usage">避雷删除 ID</div></div>
<div class="command"><div class="cmd-name">避雷修改</div><div class="cmd-usage">避雷修改 ID 名称 备注</div></div>
<div class="command"><div class="cmd-name">避雷查询</div><div class="cmd-usage">避雷查询 名称</div></div>
</div>
<div class="group-title">避雷功能</div>
<div class="command-grid">
<div class="command"><div class="cmd-name">避雷查看</div><div class="cmd-usage">避雷查看</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">避雷添加</div><div class="cmd-usage">避雷添加 名称 备注</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">避雷删除</div><div class="cmd-usage">避雷删除 ID</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">避雷修改</div><div class="cmd-usage">避雷修改 ID 名称 备注</div><div class="cmd-desc"></div></div>
<div class="command"><div class="cmd-name">避雷查询</div><div class="cmd-usage">避雷查询 名称</div><div class="cmd-desc"></div></div>
</div>
</div>
<div class="tip">
<strong>使用提示:</strong><br>
1. 中括号参数为可选内容,不填写则使用程序默认值<br>
2. 未填写服务器时将使用配置中的默认服务器<br>
3. 基础指令无需 token 可直接使用
<strong>使用提示:</strong><br>
1. 中括号参数为可选内容,不填写则使用程序默认值<br>
2. 未填写服务器时将使用配置中的默认服务器<br>
3. 基础指令无需 token 可直接使用
</div>
</div>