o'kok
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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))
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"kfjk": true,
|
||||
"xwzx": 3174,
|
||||
"smxx": 0,
|
||||
"ctxx": 0
|
||||
}
|
||||
Binary file not shown.
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user