mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-09-29 00:32:06 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2a54a8164 | ||
|
|
4dbab21853 | ||
|
|
3063c5bc02 |
@@ -145,4 +145,3 @@ Yu-Gi-Oh/
|
||||
search_image/
|
||||
black_word/
|
||||
csgo/
|
||||
fantasy_card/
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
## 声明
|
||||
此项目仅用于学习交流,请勿用于非法用途
|
||||
|
||||
## Gitee
|
||||
|
||||
# [Gitee](https://gitee.com/two_Dimension/zhenxun_bot)
|
||||
|
||||
## 未完成的文档
|
||||
|
||||
# [传送门](https://hibikier.github.io/zhenxun_bot/)
|
||||
@@ -29,19 +25,20 @@
|
||||
## 真寻的帮助
|
||||
请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令'
|
||||
|
||||
## 普通帮助图片
|
||||

|
||||
|
||||
## 提供符合真寻标准的插件仓库
|
||||
|
||||
[AkashiCoin/nonebot_plugins_zhenxun_bot](https://github.com/AkashiCoin/nonebot_plugins_zhenxun_bot)
|
||||
|
||||
## 来点优点?
|
||||
|
||||
一.作为bot:
|
||||
* 实现了许多功能,且提供了大量功能管理命令
|
||||
* __..... 更多详细请通过`传送门`查看文档!__
|
||||
|
||||
二.作为框架?:
|
||||
* 通过Config配置项将所有插件配置统计保存至config.yaml,利于统一用户修改
|
||||
* 方便增删插件,原生nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
|
||||
* 提供了cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`__plugin_cd_limit__`
|
||||
* 基本完善的权限管理
|
||||
* __..... 更多详细请通过`传送门`查看文档!__
|
||||
|
||||
|
||||
@@ -71,8 +68,6 @@
|
||||
- [x] 原神资源查询 (借鉴[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件)
|
||||
- [x] 原神便笺查询
|
||||
- [x] 原神玩家查询
|
||||
- [x] 原神树脂提醒
|
||||
- [x] 原神签到/自动签到
|
||||
- [x] 金币红包
|
||||
- [x] 微博热搜
|
||||
- [x] B站主播/UP/番剧订阅
|
||||
@@ -153,7 +148,6 @@
|
||||
- [x] 清理临时数据
|
||||
- [x] 增删群认证
|
||||
- [x] 同意/拒绝好友/群聊请求
|
||||
- [x] 配置重载
|
||||
|
||||
#### 超级用户的被动技能
|
||||
- [x] 邀请入群提醒(别人邀请真寻入群)
|
||||
@@ -178,7 +172,6 @@
|
||||
- [x] 群管理员监控,自动为新晋管理员增加权限,为失去群管理员的用户删除权限
|
||||
- [x] 群权限系统
|
||||
- [x] 定时更新权限
|
||||
- [x] 自动配置重载
|
||||
</details>
|
||||
|
||||
## 详细配置请前往文档,以下为最简部署和配置,如果你有基础并学习过nonebot2的话
|
||||
@@ -200,14 +193,12 @@ git clone https://github.com/HibiKier/zhenxun_bot.git
|
||||
cd zhenxun_bot
|
||||
|
||||
# 安装依赖
|
||||
pip install poetry # 安装 poetry
|
||||
poetry install # 安装依赖
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 进行基础配置
|
||||
####请查看 配置 部分####
|
||||
|
||||
# 开始运行
|
||||
poetry shell # 进入虚拟环境
|
||||
python bot.py
|
||||
```
|
||||
|
||||
@@ -227,83 +218,11 @@ python bot.py
|
||||
```
|
||||
|
||||
|
||||
## 使用Docker
|
||||
__Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
||||
#### GitHub:[Sakuracio/zxenv](https://github.com/Sakuracio/zxenv)
|
||||
#### DockerHub:[hibikier/zhenxun_bot](https://hub.docker.com/r/hibikier/zhenxun_bot)
|
||||
|
||||
|
||||
|
||||
## 更新
|
||||
|
||||
### 2022/2/20 \[v0.1.3.1]
|
||||
|
||||
* 修复pix下载临时文件目录错误
|
||||
* 修复AI,天气,发送图片ignore导致无法使用
|
||||
* 修复纯文本被动技能提醒有时无法删除控制文本
|
||||
|
||||
### 2022/2/19 \[v0.1.3] (nonebot beta2!)
|
||||
|
||||
* 由于nonebot升级版本,提供更新建议(__该次升级将会导致nonebot.beta1以下的插件无法使用__
|
||||
* 保证services,utils,configs,plugins,basic_plugins,文件夹均为最新
|
||||
* 根目录有pyproject.toml与poetry.lock
|
||||
* 执行命令:
|
||||
* pip3 install poetry
|
||||
* poetry install
|
||||
* poetry shell
|
||||
* playwright install chromium
|
||||
* python3 bot.py
|
||||
|
||||
|
||||
* 适配nonebot.beta2
|
||||
* 删除图片搜索 nonebot_plugin_picsearcher
|
||||
* 新增图片搜索 search_image
|
||||
* 替换cos api
|
||||
* 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid
|
||||
* 修改update_info.json
|
||||
* 修复原神资源查询下载数据失败时导致报错
|
||||
* 优化BuildImage.circle()锯齿问题 [@pull/109](https://github.com/HibiKier/zhenxun_bot/pull/109)
|
||||
* epic restful 替换 [@pull/119](https://github.com/HibiKier/zhenxun_bot/pull/119)
|
||||
* fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122)
|
||||
|
||||
### 2021/2/11
|
||||
|
||||
* 修复pix不使用反代无法下载图片
|
||||
|
||||
### 2021/2/10 \[v0.1.1]
|
||||
|
||||
* 修复购买道具出错
|
||||
|
||||
### 2021/2/9 \[v0.1]
|
||||
|
||||
* 新增原神自动签到和手动签到
|
||||
* 新增原神树脂提醒
|
||||
* 新增手动重载Config.yaml命令以及重载配置定时任务(极少部分帮助或配置可能需要重启
|
||||
* 修改了发送本地图库的matcher,改为on_message
|
||||
* register_use可以通过返回值发送消息
|
||||
* 修复修改商品时限制时间出错
|
||||
* 修复超时商品依旧可以被购买
|
||||
|
||||
### 2021/1/16 \[v0.0.9.0]
|
||||
|
||||
* Ai提供文本敏感词过滤器
|
||||
* 疫情插件适配新版腾讯API
|
||||
* 修复/t回复带空格切分
|
||||
* 修复原神玩家查询缺少渊下宫和稻妻家园以及角色不完全
|
||||
* 修复方法 text2image 中 padding 和 font 无法对纯文本生效
|
||||
* 修复签到图片中信息并未使用配置文件中的色图概率
|
||||
* 修改原神大地图合成方式,改为先压缩再合成
|
||||
* bag_user弃用字段props(该字段会在下次更新删除),使用新字段property
|
||||
* 数据库中所有belonging_group统一修改为group_id
|
||||
* 商店将registered_use和register_goods更名为register_use何register_goods
|
||||
* 商品注册提供了kwargs参数提供:
|
||||
* bot
|
||||
* event
|
||||
* 特殊字段
|
||||
* “send_success_msg”(发送成功的交互信息->即:使用道具 {name} {num} 次成功)
|
||||
* “_max_num_limit”(该道具单次使用的最多个数,默认1)
|
||||
|
||||
### 2021/1/5 \[v0.0.8.2]
|
||||
### 2021/1/5 \[v0.0.8.0]
|
||||
|
||||
* 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币
|
||||
* 商店插件将作为内置插件移动至basic_plugins
|
||||
@@ -359,6 +278,7 @@ __..... 更多更新信息请查看文档__
|
||||
|
||||
|
||||
## Todo
|
||||
- [ ] docker容器
|
||||
- [ ] web管理
|
||||
|
||||
## 感谢
|
||||
@@ -373,5 +293,5 @@ __..... 更多更新信息请查看文档__
|
||||
[H-K-Y / Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot) :原神bot,这是一个基于nonebot和HoshinoBot的原神娱乐及信息查询插件
|
||||
[NothAmor / nonebot2_luxun_says](https://github.com/NothAmor/nonebot2_luxun_says) :基于nonebot2机器人框架的鲁迅说插件
|
||||
[Kyomotoi / AnimeThesaurus](https://github.com/Kyomotoi/AnimeThesaurus) :一个~~特二刺螈~~(文爱)的适用于任何bot的词库
|
||||
[Ailitonia / omega-miya](https://github.com/Ailitonia/omega-miya) :基于nonebot2的qq机器人
|
||||
[Ailitonia / omega-miya](https://github.com/Ailitonia/omega-miya) :基于nonebot2的qq机器人
|
||||
[KimigaiiWuyi / GenshinUID]("https://github.com/KimigaiiWuyi/GenshinUID") :一个基于HoshinoBot/NoneBot2的原神UID查询插件
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
__version__: v0.1.3.1
|
||||
__version__: v0.0.8.0
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from nonebot import on_notice
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import GroupAdminNoticeEvent
|
||||
from nonebot.adapters.cqhttp import Bot, GroupAdminNoticeEvent
|
||||
from nonebot.typing import T_State
|
||||
from models.level_user import LevelUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from configs.config import Config
|
||||
@@ -15,7 +16,7 @@ admin_notice = on_notice(priority=5)
|
||||
|
||||
|
||||
@admin_notice.handle()
|
||||
async def _(event: GroupAdminNoticeEvent):
|
||||
async def _(bot: Bot, event: GroupAdminNoticeEvent, state: T_State):
|
||||
try:
|
||||
nickname = (
|
||||
await GroupInfoUser.get_member_info(event.user_id, event.group_id)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from nonebot import on_command
|
||||
from utils.utils import get_message_img
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
from ._data_source import custom_group_welcome
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from .data_source import custom_group_welcome
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from configs.config import Config
|
||||
from services.log import logger
|
||||
|
||||
@@ -35,14 +35,14 @@ custom_welcome = on_command(
|
||||
|
||||
|
||||
@custom_welcome.handle()
|
||||
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
try:
|
||||
msg = arg.extract_plain_text().strip()
|
||||
img = get_message_img(event.json())
|
||||
if not msg and not img:
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
if not msg and not imgs:
|
||||
await custom_welcome.finish(__plugin_usage__)
|
||||
await custom_welcome.send(
|
||||
await custom_group_welcome(msg, img, event.user_id, event.group_id),
|
||||
await custom_group_welcome(msg, imgs, event.user_id, event.group_id),
|
||||
at_sender=True,
|
||||
)
|
||||
logger.info(f"USER {event.user_id} GROUP {event.group_id} 自定义群欢迎消息:{msg}")
|
||||
|
||||
Regular → Executable
+319
-319
@@ -1,319 +1,319 @@
|
||||
from typing import List
|
||||
from nonebot.adapters.onebot.v11.message import MessageSegment
|
||||
from services.log import logger
|
||||
from configs.path_config import DATA_PATH
|
||||
from utils.message_builder import image
|
||||
from utils.utils import get_bot
|
||||
from pathlib import Path
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from datetime import datetime
|
||||
from services.db_context import db
|
||||
from models.level_user import LevelUser
|
||||
from configs.config import Config
|
||||
from utils.manager import group_manager, plugins2settings_manager, plugins_manager
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.http_utils import AsyncHttpx
|
||||
import asyncio
|
||||
import time
|
||||
import os
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
|
||||
async def group_current_status(group_id: int) -> str:
|
||||
"""
|
||||
获取当前所有通知的开关
|
||||
:param group_id: 群号
|
||||
"""
|
||||
rst = "[被动技能 状态]\n"
|
||||
_data = group_manager.get_task_data()
|
||||
for task in _data.keys():
|
||||
rst += f'{_data[task]}: {"√" if await group_manager.check_group_task_status(group_id, task) else "×"}\n'
|
||||
return rst.strip()
|
||||
|
||||
|
||||
custom_welcome_msg_json = (
|
||||
Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json"
|
||||
)
|
||||
|
||||
|
||||
async def custom_group_welcome(
|
||||
msg: str, imgs: List[str], user_id: int, group_id: int
|
||||
) -> str:
|
||||
"""
|
||||
替换群欢迎消息
|
||||
:param msg: 欢迎消息文本
|
||||
:param imgs: 欢迎消息图片,只取第一张
|
||||
:param user_id: 用户id,用于log记录
|
||||
:param group_id: 群号
|
||||
"""
|
||||
img_result = ""
|
||||
img = imgs[0] if imgs else ""
|
||||
result = ""
|
||||
if (DATA_PATH / f"custom_welcome_msg/{group_id}.jpg").exists():
|
||||
(DATA_PATH / f"custom_welcome_msg/{group_id}.jpg").unlink()
|
||||
if not custom_welcome_msg_json.exists():
|
||||
custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True)
|
||||
data = {}
|
||||
else:
|
||||
try:
|
||||
data = json.load(open(custom_welcome_msg_json, "r"))
|
||||
except FileNotFoundError:
|
||||
data = {}
|
||||
try:
|
||||
if msg:
|
||||
data[str(group_id)] = str(msg)
|
||||
json.dump(
|
||||
data, open(custom_welcome_msg_json, "w"), indent=4, ensure_ascii=False
|
||||
)
|
||||
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}")
|
||||
result += msg
|
||||
if img:
|
||||
await AsyncHttpx.download_file(
|
||||
img, DATA_PATH / "custom_welcome_msg" / f"{group_id}.jpg"
|
||||
)
|
||||
img_result = image(abspath=DATA_PATH / "custom_welcome_msg" / f"{group_id}.jpg")
|
||||
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
|
||||
except Exception as e:
|
||||
logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}")
|
||||
return "替换群消息失败.."
|
||||
return f"替换群欢迎消息成功:\n{result}" + img_result
|
||||
|
||||
|
||||
task_data = None
|
||||
|
||||
|
||||
async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
|
||||
global task_data
|
||||
"""
|
||||
修改群功能状态
|
||||
:param cmd: 功能名称
|
||||
:param group_id: 群号
|
||||
:param is_super: 是否位超级用户,超级用户用于私聊开关功能状态
|
||||
"""
|
||||
if not task_data:
|
||||
task_data = group_manager.get_task_data()
|
||||
group_help_file = DATA_PATH / "group_help" / f"{group_id}.png"
|
||||
status = cmd[:2]
|
||||
cmd = cmd[2:]
|
||||
type_ = "plugin"
|
||||
modules = plugins2settings_manager.get_plugin_module(cmd, True)
|
||||
if cmd == "全部被动":
|
||||
for task in task_data:
|
||||
if status == "开启":
|
||||
if not await group_manager.check_group_task_status(group_id, task):
|
||||
await group_manager.open_group_task(group_id, task)
|
||||
else:
|
||||
if await group_manager.check_group_task_status(group_id, task):
|
||||
await group_manager.close_group_task(group_id, task)
|
||||
if group_help_file.exists():
|
||||
group_help_file.unlink()
|
||||
return f"已 {status} 全部被动技能!"
|
||||
if cmd == "全部功能":
|
||||
for f in plugins2settings_manager.get_data():
|
||||
if status == "开启":
|
||||
group_manager.unblock_plugin(f, group_id)
|
||||
else:
|
||||
group_manager.block_plugin(f, group_id)
|
||||
return f"已 {status} 全部功能!"
|
||||
if cmd in [task_data[x] for x in task_data.keys()]:
|
||||
type_ = "task"
|
||||
modules = [x for x in task_data.keys() if task_data[x] == cmd]
|
||||
for module in modules:
|
||||
if is_super:
|
||||
module = f"{module}:super"
|
||||
if status == "开启":
|
||||
if type_ == "task":
|
||||
if await group_manager.check_group_task_status(group_id, module):
|
||||
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
|
||||
await group_manager.open_group_task(group_id, module)
|
||||
else:
|
||||
if group_manager.get_plugin_status(module, group_id):
|
||||
return f"功能 {cmd} 正处于开启状态!不要重复开启."
|
||||
group_manager.unblock_plugin(module, group_id)
|
||||
else:
|
||||
if type_ == "task":
|
||||
if not await group_manager.check_group_task_status(group_id, module):
|
||||
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
|
||||
await group_manager.close_group_task(group_id, module)
|
||||
else:
|
||||
if not group_manager.get_plugin_status(module, group_id):
|
||||
return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
|
||||
group_manager.block_plugin(module, group_id)
|
||||
if group_help_file.exists():
|
||||
group_help_file.unlink()
|
||||
if is_super:
|
||||
for file in os.listdir(DATA_PATH / "group_help"):
|
||||
file = DATA_PATH / "group_help" / file
|
||||
file.unlink()
|
||||
else:
|
||||
_help_image = DATA_PATH / "group_help" / f"{group_id}.png"
|
||||
if _help_image.exists():
|
||||
_help_image.unlink()
|
||||
return f"{status} {cmd} 功能!"
|
||||
|
||||
|
||||
def set_plugin_status(cmd: str, block_type: str = "all"):
|
||||
"""
|
||||
设置插件功能状态(超级用户使用)
|
||||
:param cmd: 功能名称
|
||||
:param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊
|
||||
"""
|
||||
status = cmd[:2]
|
||||
cmd = cmd[2:]
|
||||
module = plugins2settings_manager.get_plugin_module(cmd)
|
||||
if status == "开启":
|
||||
plugins_manager.unblock_plugin(module)
|
||||
else:
|
||||
plugins_manager.block_plugin(module, block_type=block_type)
|
||||
for file in os.listdir(DATA_PATH / "group_help"):
|
||||
file = DATA_PATH / "group_help" / file
|
||||
file.unlink()
|
||||
|
||||
|
||||
async def get_plugin_status():
|
||||
"""
|
||||
获取功能状态
|
||||
"""
|
||||
return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status)
|
||||
|
||||
|
||||
def _get_plugin_status() -> MessageSegment:
|
||||
"""
|
||||
合成功能状态图片
|
||||
"""
|
||||
rst = "\t功能\n"
|
||||
flag_str = "状态".rjust(4) + "\n"
|
||||
for module in plugins_manager.get_data():
|
||||
flag = plugins_manager.get_plugin_block_type(module)
|
||||
flag = flag.upper() + " CLOSE" if flag else "OPEN"
|
||||
try:
|
||||
plugin_name = plugins_manager.get(module)["plugin_name"]
|
||||
if (
|
||||
"[Hidden]" in plugin_name
|
||||
or "[Admin]" in plugin_name
|
||||
or "[Superuser]" in plugin_name
|
||||
):
|
||||
continue
|
||||
rst += f"{plugin_name}"
|
||||
except KeyError:
|
||||
rst += f"{module}"
|
||||
if plugins_manager.get(module)["error"]:
|
||||
rst += "[ERROR]"
|
||||
rst += "\n"
|
||||
flag_str += f"{flag}\n"
|
||||
height = len(rst.split("\n")) * 24
|
||||
a = BuildImage(250, height, font_size=20)
|
||||
a.text((10, 10), rst)
|
||||
b = BuildImage(200, height, font_size=20)
|
||||
b.text((10, 10), flag_str)
|
||||
A = BuildImage(500, height)
|
||||
A.paste(a)
|
||||
A.paste(b, (270, 0))
|
||||
return image(b64=A.pic2bs4())
|
||||
|
||||
|
||||
async def update_member_info(group_id: int, remind_superuser: bool = False) -> bool:
|
||||
"""
|
||||
更新群成员信息
|
||||
:param group_id: 群号
|
||||
:param remind_superuser: 失败信息提醒超级用户
|
||||
"""
|
||||
bot = get_bot()
|
||||
_group_user_list = await bot.get_group_member_list(group_id=group_id)
|
||||
_error_member_list = []
|
||||
_exist_member_list = []
|
||||
# try:
|
||||
for user_info in _group_user_list:
|
||||
if user_info["card"] == "":
|
||||
nickname = user_info["nickname"]
|
||||
else:
|
||||
nickname = user_info["card"]
|
||||
async with db.transaction():
|
||||
# 更新权限
|
||||
if (
|
||||
user_info["role"]
|
||||
in [
|
||||
"owner",
|
||||
"admin",
|
||||
]
|
||||
and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
|
||||
):
|
||||
await LevelUser.set_level(
|
||||
user_info["user_id"],
|
||||
user_info["group_id"],
|
||||
Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"),
|
||||
)
|
||||
if str(user_info["user_id"]) in bot.config.superusers:
|
||||
await LevelUser.set_level(
|
||||
user_info["user_id"], user_info["group_id"], 9
|
||||
)
|
||||
user = await GroupInfoUser.get_member_info(
|
||||
user_info["user_id"], user_info["group_id"]
|
||||
)
|
||||
if user:
|
||||
if user.user_name != nickname:
|
||||
await user.update(user_name=nickname).apply()
|
||||
logger.info(
|
||||
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功"
|
||||
)
|
||||
_exist_member_list.append(int(user_info["user_id"]))
|
||||
continue
|
||||
join_time = datetime.strptime(
|
||||
time.strftime(
|
||||
"%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])
|
||||
),
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
)
|
||||
if await GroupInfoUser.add_member_info(
|
||||
user_info["user_id"],
|
||||
user_info["group_id"],
|
||||
nickname,
|
||||
join_time,
|
||||
):
|
||||
_exist_member_list.append(int(user_info["user_id"]))
|
||||
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
||||
else:
|
||||
_error_member_list.append(
|
||||
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n"
|
||||
)
|
||||
_del_member_list = list(
|
||||
set(_exist_member_list).difference(
|
||||
set(await GroupInfoUser.get_group_member_id_list(group_id))
|
||||
)
|
||||
)
|
||||
if _del_member_list:
|
||||
for del_user in _del_member_list:
|
||||
if await GroupInfoUser.delete_member_info(del_user, group_id):
|
||||
logger.info(f"退群用户{del_user} 所属{group_id} 已删除")
|
||||
else:
|
||||
logger.info(f"退群用户{del_user} 所属{group_id} 删除失败")
|
||||
if _error_member_list and remind_superuser:
|
||||
result = ""
|
||||
for error_user in _error_member_list:
|
||||
result += error_user
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
def set_group_bot_status(group_id: int, status: bool) -> str:
|
||||
"""
|
||||
设置群聊bot开关状态
|
||||
:param group_id: 群号
|
||||
:param status: 状态
|
||||
"""
|
||||
if status:
|
||||
if group_manager.check_group_bot_status(group_id):
|
||||
return "我还醒着呢!"
|
||||
group_manager.turn_on_group_bot_status(group_id)
|
||||
return "呜..醒来了..."
|
||||
else:
|
||||
group_manager.shutdown_group_bot_status(group_id)
|
||||
# for x in group_manager.get_task_data():
|
||||
# group_manager.close_group_task(group_id, x)
|
||||
return "那我先睡觉了..."
|
||||
from typing import List
|
||||
from nonebot.adapters.cqhttp.message import MessageSegment
|
||||
from services.log import logger
|
||||
from configs.path_config import DATA_PATH
|
||||
from utils.message_builder import image
|
||||
from utils.utils import get_local_proxy, get_bot
|
||||
from pathlib import Path
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from datetime import datetime
|
||||
from services.db_context import db
|
||||
from models.level_user import LevelUser
|
||||
from configs.config import Config
|
||||
from utils.manager import group_manager, plugins2settings_manager, plugins_manager
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.http_utils import AsyncHttpx
|
||||
import asyncio
|
||||
import time
|
||||
import os
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
|
||||
async def group_current_status(group_id: int) -> str:
|
||||
"""
|
||||
获取当前所有通知的开关
|
||||
:param group_id: 群号
|
||||
"""
|
||||
rst = "[被动技能 状态]\n"
|
||||
_data = group_manager.get_task_data()
|
||||
for task in _data.keys():
|
||||
rst += f'{_data[task]}: {"√" if await group_manager.check_group_task_status(group_id, task) else "×"}\n'
|
||||
return rst.strip()
|
||||
|
||||
|
||||
custom_welcome_msg_json = (
|
||||
Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json"
|
||||
)
|
||||
|
||||
|
||||
async def custom_group_welcome(
|
||||
msg: str, imgs: List[str], user_id: int, group_id: int
|
||||
) -> str:
|
||||
"""
|
||||
替换群欢迎消息
|
||||
:param msg: 欢迎消息文本
|
||||
:param imgs: 欢迎消息图片,只取第一张
|
||||
:param user_id: 用户id,用于log记录
|
||||
:param group_id: 群号
|
||||
"""
|
||||
img_result = ""
|
||||
img = imgs[0] if imgs else ""
|
||||
result = ""
|
||||
if os.path.exists(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg"):
|
||||
os.remove(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
|
||||
if not custom_welcome_msg_json.exists():
|
||||
custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True)
|
||||
data = {}
|
||||
else:
|
||||
try:
|
||||
data = json.load(open(custom_welcome_msg_json, "r"))
|
||||
except FileNotFoundError:
|
||||
data = {}
|
||||
try:
|
||||
if msg:
|
||||
data[str(group_id)] = str(msg)
|
||||
json.dump(
|
||||
data, open(custom_welcome_msg_json, "w"), indent=4, ensure_ascii=False
|
||||
)
|
||||
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}")
|
||||
result += msg
|
||||
if img:
|
||||
await AsyncHttpx.download_file(
|
||||
img, DATA_PATH + f"custom_welcome_msg/{group_id}.jpg"
|
||||
)
|
||||
img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
|
||||
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
|
||||
except Exception as e:
|
||||
logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}")
|
||||
return "替换群消息失败.."
|
||||
return f"替换群欢迎消息成功:\n{result}" + img_result
|
||||
|
||||
|
||||
task_data = None
|
||||
|
||||
|
||||
async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
|
||||
global task_data
|
||||
"""
|
||||
修改群功能状态
|
||||
:param cmd: 功能名称
|
||||
:param group_id: 群号
|
||||
:param is_super: 是否位超级用户,超级用户用于私聊开关功能状态
|
||||
"""
|
||||
if not task_data:
|
||||
task_data = group_manager.get_task_data()
|
||||
group_help_file = Path(DATA_PATH) / "group_help" / f"{group_id}.png"
|
||||
status = cmd[:2]
|
||||
cmd = cmd[2:]
|
||||
type_ = "plugin"
|
||||
modules = plugins2settings_manager.get_plugin_module(cmd, True)
|
||||
if cmd == "全部被动":
|
||||
for task in task_data:
|
||||
if status == "开启":
|
||||
if not await group_manager.check_group_task_status(group_id, task):
|
||||
await group_manager.open_group_task(group_id, task)
|
||||
else:
|
||||
if await group_manager.check_group_task_status(group_id, task):
|
||||
await group_manager.close_group_task(group_id, task)
|
||||
if group_help_file.exists():
|
||||
group_help_file.unlink()
|
||||
return f"已 {status} 全部被动技能!"
|
||||
if cmd == "全部功能":
|
||||
for f in plugins2settings_manager.get_data():
|
||||
if status == "开启":
|
||||
group_manager.unblock_plugin(f, group_id)
|
||||
else:
|
||||
group_manager.block_plugin(f, group_id)
|
||||
return f"已 {status} 全部功能!"
|
||||
if cmd in [task_data[x] for x in task_data.keys()]:
|
||||
type_ = "task"
|
||||
modules = [x for x in task_data.keys() if task_data[x] == cmd]
|
||||
for module in modules:
|
||||
if is_super:
|
||||
module = f"{module}:super"
|
||||
if status == "开启":
|
||||
if type_ == "task":
|
||||
if await group_manager.check_group_task_status(group_id, module):
|
||||
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
|
||||
await group_manager.open_group_task(group_id, module)
|
||||
else:
|
||||
if group_manager.get_plugin_status(module, group_id):
|
||||
return f"功能 {cmd} 正处于开启状态!不要重复开启."
|
||||
group_manager.unblock_plugin(module, group_id)
|
||||
else:
|
||||
if type_ == "task":
|
||||
if not await group_manager.check_group_task_status(group_id, module):
|
||||
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
|
||||
await group_manager.close_group_task(group_id, module)
|
||||
else:
|
||||
if not group_manager.get_plugin_status(module, group_id):
|
||||
return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
|
||||
group_manager.block_plugin(module, group_id)
|
||||
if group_help_file.exists():
|
||||
group_help_file.unlink()
|
||||
if is_super:
|
||||
for file in os.listdir(Path(DATA_PATH) / "group_help"):
|
||||
file = Path(DATA_PATH) / "group_help" / file
|
||||
file.unlink()
|
||||
else:
|
||||
_help_image = Path(DATA_PATH) / "group_help" / f"{group_id}.png"
|
||||
if _help_image.exists():
|
||||
_help_image.unlink()
|
||||
return f"{status} {cmd} 功能!"
|
||||
|
||||
|
||||
def set_plugin_status(cmd: str, block_type: str = "all"):
|
||||
"""
|
||||
设置插件功能状态(超级用户使用)
|
||||
:param cmd: 功能名称
|
||||
:param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊
|
||||
"""
|
||||
status = cmd[:2]
|
||||
cmd = cmd[2:]
|
||||
module = plugins2settings_manager.get_plugin_module(cmd)
|
||||
if status == "开启":
|
||||
plugins_manager.unblock_plugin(module)
|
||||
else:
|
||||
plugins_manager.block_plugin(module, block_type=block_type)
|
||||
for file in os.listdir(Path(DATA_PATH) / "group_help"):
|
||||
file = Path(DATA_PATH) / "group_help" / file
|
||||
file.unlink()
|
||||
|
||||
|
||||
async def get_plugin_status():
|
||||
"""
|
||||
获取功能状态
|
||||
"""
|
||||
return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status)
|
||||
|
||||
|
||||
def _get_plugin_status() -> MessageSegment:
|
||||
"""
|
||||
合成功能状态图片
|
||||
"""
|
||||
rst = "\t功能\n"
|
||||
flag_str = "状态".rjust(4) + "\n"
|
||||
for module in plugins_manager.get_data():
|
||||
flag = plugins_manager.get_plugin_block_type(module)
|
||||
flag = flag.upper() + " CLOSE" if flag else "OPEN"
|
||||
try:
|
||||
plugin_name = plugins_manager.get(module)["plugin_name"]
|
||||
if (
|
||||
"[Hidden]" in plugin_name
|
||||
or "[Admin]" in plugin_name
|
||||
or "[Superuser]" in plugin_name
|
||||
):
|
||||
continue
|
||||
rst += f"{plugin_name}"
|
||||
except KeyError:
|
||||
rst += f"{module}"
|
||||
if plugins_manager.get(module)["error"]:
|
||||
rst += "[ERROR]"
|
||||
rst += "\n"
|
||||
flag_str += f"{flag}\n"
|
||||
height = len(rst.split("\n")) * 24
|
||||
a = BuildImage(250, height, font_size=20)
|
||||
a.text((10, 10), rst)
|
||||
b = BuildImage(200, height, font_size=20)
|
||||
b.text((10, 10), flag_str)
|
||||
A = BuildImage(500, height)
|
||||
A.paste(a)
|
||||
A.paste(b, (270, 0))
|
||||
return image(b64=A.pic2bs4())
|
||||
|
||||
|
||||
async def update_member_info(group_id: int, remind_superuser: bool = False) -> bool:
|
||||
"""
|
||||
更新群成员信息
|
||||
:param group_id: 群号
|
||||
:param remind_superuser: 失败信息提醒超级用户
|
||||
"""
|
||||
bot = get_bot()
|
||||
_group_user_list = await bot.get_group_member_list(group_id=group_id)
|
||||
_error_member_list = []
|
||||
_exist_member_list = []
|
||||
# try:
|
||||
for user_info in _group_user_list:
|
||||
if user_info["card"] == "":
|
||||
nickname = user_info["nickname"]
|
||||
else:
|
||||
nickname = user_info["card"]
|
||||
async with db.transaction():
|
||||
# 更新权限
|
||||
if (
|
||||
user_info["role"]
|
||||
in [
|
||||
"owner",
|
||||
"admin",
|
||||
]
|
||||
and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
|
||||
):
|
||||
await LevelUser.set_level(
|
||||
user_info["user_id"],
|
||||
user_info["group_id"],
|
||||
Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"),
|
||||
)
|
||||
if str(user_info["user_id"]) in bot.config.superusers:
|
||||
await LevelUser.set_level(
|
||||
user_info["user_id"], user_info["group_id"], 9
|
||||
)
|
||||
user = await GroupInfoUser.get_member_info(
|
||||
user_info["user_id"], user_info["group_id"]
|
||||
)
|
||||
if user:
|
||||
if user.user_name != nickname:
|
||||
await user.update(user_name=nickname).apply()
|
||||
logger.info(
|
||||
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功"
|
||||
)
|
||||
_exist_member_list.append(int(user_info["user_id"]))
|
||||
continue
|
||||
join_time = datetime.strptime(
|
||||
time.strftime(
|
||||
"%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])
|
||||
),
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
)
|
||||
if await GroupInfoUser.add_member_info(
|
||||
user_info["user_id"],
|
||||
user_info["group_id"],
|
||||
nickname,
|
||||
join_time,
|
||||
):
|
||||
_exist_member_list.append(int(user_info["user_id"]))
|
||||
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
||||
else:
|
||||
_error_member_list.append(
|
||||
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n"
|
||||
)
|
||||
_del_member_list = list(
|
||||
set(_exist_member_list).difference(
|
||||
set(await GroupInfoUser.get_group_member_id_list(group_id))
|
||||
)
|
||||
)
|
||||
if _del_member_list:
|
||||
for del_user in _del_member_list:
|
||||
if await GroupInfoUser.delete_member_info(del_user, group_id):
|
||||
logger.info(f"退群用户{del_user} 所属{group_id} 已删除")
|
||||
else:
|
||||
logger.info(f"退群用户{del_user} 所属{group_id} 删除失败")
|
||||
if _error_member_list and remind_superuser:
|
||||
result = ""
|
||||
for error_user in _error_member_list:
|
||||
result += error_user
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
def set_group_bot_status(group_id: int, status: bool) -> str:
|
||||
"""
|
||||
设置群聊bot开关状态
|
||||
:param group_id: 群号
|
||||
:param status: 状态
|
||||
"""
|
||||
if status:
|
||||
if group_manager.check_group_bot_status(group_id):
|
||||
return "我还醒着呢!"
|
||||
group_manager.turn_on_group_bot_status(group_id)
|
||||
return "呜..醒来了..."
|
||||
else:
|
||||
group_manager.shutdown_group_bot_status(group_id)
|
||||
# for x in group_manager.get_task_data():
|
||||
# group_manager.close_group_task(group_id, x)
|
||||
return "那我先睡觉了..."
|
||||
@@ -1,4 +1,5 @@
|
||||
from nonebot.adapters.onebot.v11 import Event
|
||||
from nonebot.adapters.cqhttp import Bot, Event
|
||||
from nonebot.typing import T_State
|
||||
from utils.manager import group_manager, plugins2settings_manager
|
||||
from utils.utils import get_message_text
|
||||
from services.log import logger
|
||||
@@ -6,10 +7,12 @@ from services.log import logger
|
||||
cmd = []
|
||||
|
||||
|
||||
def switch_rule(event: Event) -> bool:
|
||||
def switch_rule(bot: Bot, event: Event, state: T_State) -> bool:
|
||||
"""
|
||||
检测文本是否是关闭功能命令
|
||||
:param bot: pass
|
||||
:param event: pass
|
||||
:param state: pass
|
||||
"""
|
||||
global cmd
|
||||
try:
|
||||
@@ -31,7 +34,7 @@ def switch_rule(event: Event) -> bool:
|
||||
cmd.append(f"关闭 {x}")
|
||||
except KeyError:
|
||||
pass
|
||||
msg = get_message_text(event.json())
|
||||
msg = get_message_text(event.json()).split()
|
||||
msg = msg[0] if msg else ""
|
||||
return msg in cmd
|
||||
except Exception as e:
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent, GROUP, Message
|
||||
from nonebot import on_command, on_message, on_regex
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.params import CommandArg
|
||||
from ._data_source import (
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent, GROUP
|
||||
from .data_source import (
|
||||
change_group_switch,
|
||||
set_plugin_status,
|
||||
get_plugin_status,
|
||||
@@ -14,6 +13,7 @@ from configs.config import NICKNAME, Config
|
||||
from utils.utils import get_message_text, is_number
|
||||
from nonebot.permission import SUPERUSER
|
||||
from .rule import switch_rule
|
||||
import re
|
||||
|
||||
|
||||
__zx_plugin_name__ = "群功能开关 [Admin]"
|
||||
@@ -65,19 +65,19 @@ group_status = on_regex("^(休息吧|醒来)$", permission=GROUP, priority=5, bl
|
||||
|
||||
|
||||
@switch_rule_matcher.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
_cmd = arg.extract_plain_text().strip().split()[0]
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
_cmd = get_message_text(event.json()).split()[0]
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
await switch_rule_matcher.send(await change_group_switch(_cmd, event.group_id))
|
||||
logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {_cmd}")
|
||||
else:
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
block_type = " ".join(arg.extract_plain_text().strip().split()[1:])
|
||||
block_type = " ".join(get_message_text(event.json()).split()[1:])
|
||||
block_type = block_type if block_type else "a"
|
||||
if is_number(block_type):
|
||||
if not int(block_type) in [
|
||||
g["group_id"]
|
||||
for g in await bot.get_group_list()
|
||||
for g in await bot.get_group_list(self_id=int(bot.self_id))
|
||||
]:
|
||||
await switch_rule_matcher.finish(f"{NICKNAME}未加入群聊:{block_type}")
|
||||
await change_group_switch(_cmd, int(block_type), True)
|
||||
@@ -104,21 +104,22 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@plugins_status.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await plugins_status.send(await get_plugin_status())
|
||||
|
||||
|
||||
@group_task_status.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await group_task_status.send(await group_current_status(event.group_id))
|
||||
|
||||
|
||||
@group_status.handle()
|
||||
async def _(event: GroupMessageEvent, state: T_State):
|
||||
cmd = state["_matched_groups"][0]
|
||||
if cmd == "休息吧":
|
||||
msg = set_group_bot_status(event.group_id, False)
|
||||
else:
|
||||
msg = set_group_bot_status(event.group_id, True)
|
||||
await group_status.send(msg)
|
||||
logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用总开关命令:{cmd}")
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
r = re.search("^(休息吧|醒来)$", get_message_text(event.json()))
|
||||
if r:
|
||||
if r.group(1) == "休息吧":
|
||||
msg = set_group_bot_status(event.group_id, False)
|
||||
else:
|
||||
msg = set_group_bot_status(event.group_id, True)
|
||||
await group_status.send(msg)
|
||||
logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用总开关命令:{r.group(1)}")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from utils.utils import scheduler, get_bot
|
||||
from ._data_source import update_member_info
|
||||
from .data_source import update_member_info
|
||||
from services.log import logger
|
||||
from models.group_info import GroupInfo
|
||||
from asyncpg.exceptions import ConnectionDoesNotExistError, UndefinedColumnError
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from nonebot import on_command, on_notice
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, GROUP, GroupIncreaseNoticeEvent
|
||||
from ._data_source import update_member_info
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, GROUP, GroupIncreaseNoticeEvent
|
||||
from .data_source import update_member_info
|
||||
|
||||
__zx_plugin_name__ = "更新群组成员列表 [Admin]"
|
||||
__plugin_usage__ = """
|
||||
@@ -24,7 +25,7 @@ refresh_member_group = on_command(
|
||||
|
||||
|
||||
@refresh_member_group.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
if await update_member_info(event.group_id):
|
||||
await refresh_member_group.finish("更新群员信息成功!", at_sender=True)
|
||||
else:
|
||||
@@ -35,6 +36,6 @@ group_increase_handle = on_notice(priority=1, block=False)
|
||||
|
||||
|
||||
@group_increase_handle.handle()
|
||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
|
||||
if event.user_id == int(bot.self_id):
|
||||
await update_member_info(event.group_id)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from nonebot.adapters.cqhttp import GroupMessageEvent
|
||||
from utils.message_builder import image
|
||||
from .data_source import create_help_image, admin_help_image
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.utils import get_matchers
|
||||
from utils.manager import group_manager
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
from pathlib import Path
|
||||
from nonebot import Driver
|
||||
import asyncio
|
||||
import nonebot
|
||||
@@ -11,9 +12,9 @@ import nonebot
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
background = IMAGE_PATH / "background" / "0.png"
|
||||
background = Path(IMAGE_PATH) / "background" / "0.png"
|
||||
|
||||
admin_help_image = IMAGE_PATH / 'admin_help_img.png'
|
||||
admin_help_image = Path(IMAGE_PATH) / 'admin_help_img.png'
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
@@ -41,7 +42,7 @@ def _create_help_image():
|
||||
width = 0
|
||||
_plugin_level = {}
|
||||
for matcher in _matchers:
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
_module = _plugin.module
|
||||
try:
|
||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
||||
@@ -70,7 +71,7 @@ def _create_help_image():
|
||||
x = len(f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)) * 23
|
||||
width = width if width > x else x
|
||||
except AttributeError:
|
||||
logger.warning(f"获取管理插件 {matcher.plugin_name}: {plugin_name} 设置失败...")
|
||||
logger.warning(f"获取管理插件 {matcher.module}: {plugin_name} 设置失败...")
|
||||
help_str = "* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" \
|
||||
"[权限等级] 管理员帮助:\n\n"
|
||||
x = list(_plugin_level.keys())
|
||||
|
||||
@@ -4,7 +4,7 @@ from nonebot import on_message
|
||||
from services.log import logger
|
||||
from models.group_info import GroupInfo
|
||||
from models.friend_user import FriendUser
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from configs.config import NICKNAME, Config
|
||||
from utils.manager import group_manager
|
||||
from pathlib import Path
|
||||
@@ -57,11 +57,12 @@ async def _():
|
||||
gl = await bot.get_group_list()
|
||||
gl = [g["group_id"] for g in gl]
|
||||
for g in gl:
|
||||
result = image("zao.jpg", "zhenxun")
|
||||
try:
|
||||
await bot.send_group_msg(group_id=g, message="[[_task|zwa]]早上好" + result)
|
||||
except ActionFailed:
|
||||
logger.warning(f"{g} 群被禁言中,无法发送早安")
|
||||
if await group_manager.check_group_task_status(g, 'zwa'):
|
||||
result = image("zao.jpg", "zhenxun")
|
||||
try:
|
||||
await bot.send_group_msg(group_id=g, message="早上好" + result)
|
||||
except ActionFailed:
|
||||
logger.warning(f"{g} 群被禁言中,无法发送早安")
|
||||
except Exception as e:
|
||||
logger.error(f"早晚安错误 e:{e}")
|
||||
|
||||
@@ -78,13 +79,14 @@ async def _():
|
||||
gl = await bot.get_group_list()
|
||||
gl = [g["group_id"] for g in gl]
|
||||
for g in gl:
|
||||
result = image("sleep.jpg", "zhenxun")
|
||||
try:
|
||||
await bot.send_group_msg(
|
||||
group_id=g, message=f"[[_task|zwa]]{NICKNAME}要睡觉了,你们也要早点睡呀" + result
|
||||
)
|
||||
except ActionFailed:
|
||||
logger.warning(f"{g} 群被禁言中,无法发送晚安")
|
||||
if await group_manager.check_group_task_status(g, 'zwa'):
|
||||
result = image("sleep.jpg", "zhenxun")
|
||||
try:
|
||||
await bot.send_group_msg(
|
||||
group_id=g, message=f"{NICKNAME}要睡觉了,你们也要早点睡呀" + result
|
||||
)
|
||||
except ActionFailed:
|
||||
logger.warning(f"{g} 群被禁言中,无法发送晚安")
|
||||
except Exception as e:
|
||||
logger.error(f"早晚安错误 e:{e}")
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent, MessageEvent, Message, Bot
|
||||
from nonebot.params import CommandArg, Command
|
||||
from nonebot import on_command
|
||||
from models.ban_user import BanUser
|
||||
from models.level_user import LevelUser
|
||||
from typing import Tuple
|
||||
from utils.utils import get_message_at, is_number
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent, MessageEvent
|
||||
from utils.utils import get_message_at, get_message_text, is_number
|
||||
from configs.config import NICKNAME, Config
|
||||
from nonebot.permission import SUPERUSER
|
||||
from .data_source import parse_ban_time, a_ban
|
||||
from services.log import logger
|
||||
|
||||
|
||||
@@ -62,35 +61,62 @@ super_ban = on_command('b了', permission=SUPERUSER, priority=5, block=True)
|
||||
|
||||
|
||||
@ban.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
result = ""
|
||||
qq = get_message_at(event.json())
|
||||
if qq:
|
||||
qq = qq[0]
|
||||
user_name = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
|
||||
user_name = user_name['card'] or user_name['nickname']
|
||||
msg = arg.extract_plain_text().strip()
|
||||
time = parse_ban_time(msg)
|
||||
if isinstance(time, str):
|
||||
await ban.finish(time, at_sender=True)
|
||||
if cmd in [".ban", "/ban"]:
|
||||
user_name = user_name['card'] if user_name['card'] else user_name['nickname']
|
||||
msg = get_message_text(event.json())
|
||||
if msg:
|
||||
msg = msg.split()
|
||||
if len(msg) == 2:
|
||||
if not is_number(msg[0].strip()) or not is_number(msg[1].strip()):
|
||||
await ban.finish("参数必须是数字!", at_sender=True)
|
||||
time = int(msg[0]) * 60 * 60 + int(msg[1]) * 60
|
||||
else:
|
||||
if not is_number(msg[0].strip()):
|
||||
await ban.finish("参数必须是数字!", at_sender=True)
|
||||
time = int(msg[0]) * 60 * 60
|
||||
else:
|
||||
time = -1
|
||||
if state["_prefix"]["raw_command"] in [".ban", "/ban"]:
|
||||
if (
|
||||
await LevelUser.get_user_level(event.user_id, event.group_id)
|
||||
<= await LevelUser.get_user_level(qq, event.group_id)
|
||||
and str(event.user_id) not in bot.config.superusers
|
||||
await LevelUser.get_user_level(event.user_id, event.group_id)
|
||||
<= await LevelUser.get_user_level(qq, event.group_id)
|
||||
and str(event.user_id) not in bot.config.superusers
|
||||
):
|
||||
await ban.finish(
|
||||
f"您的权限等级比对方低或相等, {NICKNAME}不能为您使用此功能!",
|
||||
at_sender=True,
|
||||
)
|
||||
result = await a_ban(qq, time, user_name, event)
|
||||
if await BanUser.ban(
|
||||
qq, await LevelUser.get_user_level(event.user_id, event.group_id), time
|
||||
):
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
|
||||
)
|
||||
result = f"已经将 {user_name} 加入{NICKNAME}的黑名单了!"
|
||||
if time != -1:
|
||||
result += f"将在 {time/60} 分钟后解封"
|
||||
else:
|
||||
time = await BanUser.check_ban_time(qq)
|
||||
if is_number(time):
|
||||
time = abs(int(time))
|
||||
if time < 60:
|
||||
time = str(time) + " 秒"
|
||||
else:
|
||||
time = str(int(time / 60)) + " 分钟"
|
||||
else:
|
||||
time += " 分钟"
|
||||
result = f"{user_name} 已在黑名单!预计 {time}后解封"
|
||||
else:
|
||||
if (
|
||||
await BanUser.check_ban_level(
|
||||
qq, await LevelUser.get_user_level(event.user_id, event.group_id)
|
||||
)
|
||||
and str(event.user_id) not in bot.config.superusers
|
||||
await BanUser.check_ban_level(
|
||||
qq, await LevelUser.get_user_level(event.user_id, event.group_id)
|
||||
)
|
||||
and str(event.user_id) not in bot.config.superusers
|
||||
):
|
||||
await ban.finish(
|
||||
f"ban掉 {user_name} 的管理员权限比您高,无法进行unban", at_sender=True
|
||||
@@ -104,53 +130,78 @@ async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command()
|
||||
result = f"{user_name} 不在黑名单!"
|
||||
else:
|
||||
await ban.finish("艾特人了吗??", at_sender=True)
|
||||
await ban.send(result, at_sender=True)
|
||||
await ban.finish(result, at_sender=True)
|
||||
|
||||
|
||||
@ban.handle()
|
||||
async def _(bot: Bot, event: PrivateMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
msg = arg.extract_plain_text().strip()
|
||||
if msg:
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
if is_number(arg.extract_plain_text().strip().split()[0]):
|
||||
qq = int(msg[0])
|
||||
msg = msg[1:]
|
||||
if cmd in [".ban", "/ban"]:
|
||||
time = parse_ban_time(msg)
|
||||
if isinstance(time, str):
|
||||
await ban.finish(time)
|
||||
result = await a_ban(qq, time, str(qq), event, 9)
|
||||
else:
|
||||
if await BanUser.unban(qq):
|
||||
logger.info(
|
||||
f"USER {event.user_id} 将 USER {qq} 解禁"
|
||||
)
|
||||
result = f"已经把 {qq} 从黑名单中删除了!"
|
||||
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
msg = get_message_text(event.json())
|
||||
msg = msg.split()
|
||||
if is_number(msg[0]):
|
||||
qq = int(msg[0])
|
||||
if state["_prefix"]["raw_command"] in [".ban", "/ban"]:
|
||||
hour = 0
|
||||
minute = 0
|
||||
if len(msg) > 1 and is_number(msg[1]):
|
||||
hour = int(msg[1])
|
||||
if len(msg) > 2 and is_number(msg[2]):
|
||||
minute = int(msg[2])
|
||||
time = hour * 60 * 60 + minute * 60
|
||||
time = time if time else -1
|
||||
if await BanUser.ban(
|
||||
qq, 9, time
|
||||
):
|
||||
logger.info(
|
||||
f"USER {event.user_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
|
||||
)
|
||||
result = f"已经将 {qq} 加入{NICKNAME}的黑名单了!"
|
||||
if time != -1:
|
||||
result += f"将在 {time/60} 分钟后解封"
|
||||
else:
|
||||
result = f"{qq} 不在黑名单!"
|
||||
await ban.send(result)
|
||||
result += f"将在 ∞ 分钟后解封"
|
||||
await ban.send(result)
|
||||
else:
|
||||
time = await BanUser.check_ban_time(qq)
|
||||
if is_number(time):
|
||||
time = abs(int(time))
|
||||
if time < 60:
|
||||
time = str(time) + " 秒"
|
||||
else:
|
||||
time = str(int(time / 60)) + " 分钟"
|
||||
else:
|
||||
time += " 分钟"
|
||||
await ban.send(f"{qq} 已在黑名单!预计 {time}后解封")
|
||||
else:
|
||||
await ban.finish('qq号必须是数字!\n格式:.ban [qq] [hour]? [minute]?', at_sender=True)
|
||||
if await BanUser.unban(qq):
|
||||
logger.info(
|
||||
f"USER {event.user_id} 将 USER {qq} 解禁"
|
||||
)
|
||||
result = f"已经把 {qq} 从黑名单中删除了!"
|
||||
else:
|
||||
result = f"{qq} 不在黑名单!"
|
||||
await ban.send(result)
|
||||
else:
|
||||
await ban.finish('qq号必须是数字!\n格式:.ban [qq] [hour]? [minute]?', at_sender=True)
|
||||
|
||||
|
||||
@super_ban.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
qq = get_message_at(event.json())
|
||||
else:
|
||||
qq = arg.extract_plain_text().strip()
|
||||
qq = get_message_text(event.json())
|
||||
if not is_number(qq):
|
||||
await super_ban.finish("对象qq必须为纯数字...")
|
||||
qq = [qq]
|
||||
if qq:
|
||||
qq = qq[0]
|
||||
user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
|
||||
user_name = user['card'] or user['nickname']
|
||||
user_name = user['card'] if user['card'] else user['nickname']
|
||||
if not await BanUser.ban(qq, 10, 99999999):
|
||||
await BanUser.unban(qq)
|
||||
await BanUser.ban(qq, 10, 99999999)
|
||||
await ban.send(f"已将 {user_name} 拉入黑名单!")
|
||||
else:
|
||||
await super_ban.send('需要添加被super ban的对象,可以使用at或者指定qq..')
|
||||
await super_ban.send('需要艾特被super ban的对象..')
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from configs.config import NICKNAME
|
||||
from models.level_user import LevelUser
|
||||
from utils.utils import is_number
|
||||
from models.ban_user import BanUser
|
||||
from services.log import logger
|
||||
from typing import Union
|
||||
|
||||
|
||||
def parse_ban_time(msg: str) -> Union[int, str]:
|
||||
"""
|
||||
解析ban时长
|
||||
:param msg: 文本消息
|
||||
"""
|
||||
if not msg:
|
||||
return -1
|
||||
msg = msg.split()
|
||||
if len(msg) == 1:
|
||||
if not is_number(msg[0].strip()):
|
||||
return "参数必须是数字!"
|
||||
return int(msg[0]) * 60 * 60
|
||||
else:
|
||||
if not is_number(msg[0].strip()) or not is_number(msg[1].strip()):
|
||||
return "参数必须是数字!"
|
||||
return int(msg[0]) * 60 * 60 + int(msg[1]) * 60
|
||||
|
||||
|
||||
async def a_ban(qq: int, time: int, user_name: str, event: MessageEvent, ban_level: int = None) -> str:
|
||||
"""
|
||||
ban
|
||||
:param qq: qq
|
||||
:param time: ban时长
|
||||
:param user_name: ban用户昵称
|
||||
:param event: event
|
||||
:param ban_level: ban级别
|
||||
"""
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
ban_level = await LevelUser.get_user_level(event.user_id, event.group_id)
|
||||
if await BanUser.ban(qq, ban_level, time):
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time / 60} 分钟"
|
||||
)
|
||||
result = f"已经将 {user_name} 加入{NICKNAME}的黑名单了!"
|
||||
if time != -1:
|
||||
result += f"将在 {time / 60} 分钟后解封"
|
||||
else:
|
||||
result += f"将在 ∞ 分钟后解封"
|
||||
else:
|
||||
time = await BanUser.check_ban_time(qq)
|
||||
if is_number(time):
|
||||
time = abs(int(time))
|
||||
if time < 60:
|
||||
time = str(time) + " 秒"
|
||||
else:
|
||||
time = str(int(time / 60)) + " 分钟"
|
||||
else:
|
||||
time += " 分钟"
|
||||
result = f"{user_name} 已在黑名单!预计 {time}后解封"
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent
|
||||
from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.params import CommandArg
|
||||
from utils.utils import get_message_img
|
||||
import asyncio
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from services.log import logger
|
||||
from utils.message_builder import image
|
||||
from utils.manager import group_manager
|
||||
from configs.config import Config
|
||||
import asyncio
|
||||
|
||||
|
||||
__zx_plugin_name__ = "广播 [Superuser]"
|
||||
__plugin_usage__ = """
|
||||
@@ -34,13 +33,14 @@ broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True)
|
||||
|
||||
|
||||
@broadcast.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
img_list = get_message_img(event.json())
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
rst = ""
|
||||
for img in img_list:
|
||||
for img in imgs:
|
||||
rst += image(img)
|
||||
gl = await bot.get_group_list()
|
||||
sid = bot.self_id
|
||||
gl = await bot.get_group_list(self_id=sid)
|
||||
gl = [
|
||||
g["group_id"]
|
||||
for g in gl
|
||||
@@ -56,7 +56,7 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
await broadcast.send(f"已播报至 {int(cnt / g_cnt * 100)}% 的群聊")
|
||||
x += 0.25
|
||||
try:
|
||||
await bot.send_group_msg(group_id=g, message=msg + rst)
|
||||
await bot.send_group_msg(self_id=sid, group_id=g, message=msg + rst)
|
||||
logger.info(f"GROUP {g} 投递广播成功")
|
||||
except Exception as e:
|
||||
logger.error(f"GROUP {g} 投递广播失败:{type(e)}")
|
||||
|
||||
@@ -4,12 +4,12 @@ from utils.message_builder import image
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from datetime import datetime
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
GroupIncreaseNoticeEvent,
|
||||
GroupDecreaseNoticeEvent,
|
||||
)
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from utils.manager import group_manager, plugins2settings_manager, requests_manager
|
||||
from configs.config import NICKNAME
|
||||
from models.group_info import GroupInfo
|
||||
@@ -66,7 +66,7 @@ add_group = on_request(priority=1, block=False)
|
||||
|
||||
|
||||
@group_increase_handle.handle()
|
||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
|
||||
if event.user_id == int(bot.self_id):
|
||||
group = await GroupInfo.get_group_info(event.group_id)
|
||||
# 群聊不存在或被强制拉群,退出该群
|
||||
@@ -112,7 +112,9 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
||||
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败")
|
||||
|
||||
# 群欢迎消息
|
||||
if _flmt.check(event.group_id):
|
||||
if await group_manager.check_group_task_status(
|
||||
event.group_id, "group_welcome"
|
||||
) and _flmt.check(event.group_id):
|
||||
_flmt.start_cd(event.group_id)
|
||||
msg = ""
|
||||
img = ""
|
||||
@@ -127,25 +129,23 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
||||
if msg.find("[at]") != -1:
|
||||
msg = msg.replace("[at]", "")
|
||||
at_flag = True
|
||||
if (DATA_PATH / "custom_welcome_msg" / f"{event.group_id}.jpg").exists():
|
||||
if os.path.exists(DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"):
|
||||
img = image(
|
||||
abspath=DATA_PATH / "custom_welcome_msg" / f"{event.group_id}.jpg"
|
||||
abspath=DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"
|
||||
)
|
||||
if msg or img:
|
||||
msg = msg.strip() + img
|
||||
msg = "\n" + msg if at_flag else msg
|
||||
await group_increase_handle.send(
|
||||
"[[_task|group_welcome]]" + msg, at_sender=at_flag
|
||||
"\n" + msg.strip() + img, at_sender=at_flag
|
||||
)
|
||||
else:
|
||||
await group_increase_handle.send(
|
||||
"[[_task|group_welcome]]新人快跑啊!!本群现状↓(快使用自定义!)"
|
||||
+ image(random.choice(os.listdir(IMAGE_PATH / "qxz")), "qxz")
|
||||
"新人快跑啊!!本群现状↓(快使用自定义!)"
|
||||
+ image(random.choice(os.listdir(IMAGE_PATH + "qxz/")), "qxz")
|
||||
)
|
||||
|
||||
|
||||
@group_decrease_handle.handle()
|
||||
async def _(bot: Bot, event: GroupDecreaseNoticeEvent):
|
||||
async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict):
|
||||
# 被踢出群
|
||||
if event.sub_type == "kick_me":
|
||||
group_id = event.group_id
|
||||
@@ -180,16 +180,21 @@ async def _(bot: Bot, event: GroupDecreaseNoticeEvent):
|
||||
logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除成功")
|
||||
else:
|
||||
logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除失败")
|
||||
rst = ""
|
||||
if event.sub_type == "leave":
|
||||
rst = f"{user_name}离开了我们..."
|
||||
if event.sub_type == "kick":
|
||||
operator = await bot.get_group_member_info(
|
||||
user_id=event.operator_id, group_id=event.group_id
|
||||
)
|
||||
operator_name = operator["card"] if operator["card"] else operator["nickname"]
|
||||
rst = f"{user_name} 被 {operator_name} 送走了."
|
||||
try:
|
||||
await group_decrease_handle.send(f"[[_task|refund_group_remind]]{rst}")
|
||||
except ActionFailed:
|
||||
return
|
||||
if await group_manager.check_group_task_status(
|
||||
event.group_id, "refund_group_remind"
|
||||
):
|
||||
rst = ""
|
||||
if event.sub_type == "leave":
|
||||
rst = f"{user_name}离开了我们..."
|
||||
if event.sub_type == "kick":
|
||||
operator = await bot.get_group_member_info(
|
||||
user_id=event.operator_id, group_id=event.group_id
|
||||
)
|
||||
operator_name = (
|
||||
operator["card"] if operator["card"] else operator["nickname"]
|
||||
)
|
||||
rst = f"{user_name} 被 {operator_name} 送走了."
|
||||
try:
|
||||
await group_decrease_handle.send(f"{rst}")
|
||||
except ActionFailed:
|
||||
return
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
Message
|
||||
GroupMessageEvent
|
||||
)
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.rule import to_me
|
||||
from configs.path_config import IMAGE_PATH, DATA_PATH
|
||||
from utils.message_builder import image
|
||||
from .data_source import create_help_img, get_plugin_help
|
||||
from utils.utils import get_message_text
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
|
||||
__zx_plugin_name__ = "帮助"
|
||||
|
||||
group_help_path = DATA_PATH / "group_help"
|
||||
help_image = IMAGE_PATH / "help.png"
|
||||
simple_help_image = IMAGE_PATH / "simple_help.png"
|
||||
group_help_path = Path(DATA_PATH) / "group_help"
|
||||
help_image = Path(IMAGE_PATH) / "help.png"
|
||||
simple_help_image = Path(IMAGE_PATH) / "simple_help.png"
|
||||
if help_image.exists():
|
||||
help_image.unlink()
|
||||
if simple_help_image.exists():
|
||||
@@ -44,8 +44,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
|
||||
|
||||
@simple_help.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
is_super = False
|
||||
if msg:
|
||||
if '-super' in msg:
|
||||
|
||||
@@ -16,9 +16,9 @@ import nonebot
|
||||
import os
|
||||
|
||||
|
||||
random_bk_path = IMAGE_PATH / "background" / "help" / "simple_help"
|
||||
random_bk_path = Path(IMAGE_PATH) / "background" / "help" / "simple_help"
|
||||
|
||||
background = IMAGE_PATH / "background" / "0.png"
|
||||
background = Path(IMAGE_PATH) / "background" / "0.png"
|
||||
|
||||
|
||||
async def create_help_img(
|
||||
@@ -55,7 +55,7 @@ def _create_help_img(
|
||||
# 插件分类
|
||||
for matcher in _matchers:
|
||||
plugin_name = None
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
_module = _plugin.module
|
||||
try:
|
||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
||||
@@ -74,10 +74,10 @@ def _create_help_img(
|
||||
plugin_type = ("normal",)
|
||||
text_type = 0
|
||||
if plugins2settings_manager.get(
|
||||
matcher.plugin_name
|
||||
) and plugins2settings_manager[matcher.plugin_name].get("plugin_type"):
|
||||
matcher.module
|
||||
) and plugins2settings_manager[matcher.module].get("plugin_type"):
|
||||
plugin_type = tuple(
|
||||
plugins2settings_manager.get_plugin_data(matcher.plugin_name)[
|
||||
plugins2settings_manager.get_plugin_data(matcher.module)[
|
||||
"plugin_type"
|
||||
]
|
||||
)
|
||||
@@ -111,7 +111,7 @@ def _create_help_img(
|
||||
logger.warning(f"{type(e)}: {e}")
|
||||
else:
|
||||
matchers_data[plugin_type][plugin_name] = {
|
||||
"modules": matcher.plugin_name,
|
||||
"module": matcher.module,
|
||||
"des": plugin_des,
|
||||
"cmd": plugin_cmd,
|
||||
"text_type": text_type,
|
||||
@@ -129,7 +129,7 @@ def _create_help_img(
|
||||
_des_tmp[plugin_des] = plugin_name
|
||||
except AttributeError as e:
|
||||
if plugin_name not in _plugin_name_tmp:
|
||||
logger.warning(f"获取功能 {matcher.plugin_name}: {plugin_name} 设置失败...e:{e}")
|
||||
logger.warning(f"获取功能 {matcher.module}: {plugin_name} 设置失败...e:{e}")
|
||||
if plugin_name not in _plugin_name_tmp:
|
||||
_plugin_name_tmp.append(plugin_name)
|
||||
help_img_list = []
|
||||
@@ -147,16 +147,16 @@ def _create_help_img(
|
||||
# 禁用flag
|
||||
flag = True
|
||||
if plugins_manager.get_plugin_status(
|
||||
matchers_data[type_][k]["modules"], "all"
|
||||
matchers_data[type_][k]["module"], "all"
|
||||
):
|
||||
flag = False
|
||||
if group_id:
|
||||
flag = flag and plugins_manager.get_plugin_status(
|
||||
matchers_data[type_][k]["modules"], "group"
|
||||
matchers_data[type_][k]["module"], "group"
|
||||
)
|
||||
simple_help_str += (
|
||||
f"{i+1}.{k}<|_|~|>"
|
||||
f"{group_manager.get_plugin_status(matchers_data[type_][k]['modules'], group_id) if group_id else '_'}|"
|
||||
f"{group_manager.get_plugin_status(matchers_data[type_][k]['module'], group_id) if group_id else '_'}|"
|
||||
f"{flag}\n"
|
||||
)
|
||||
if matchers_data[type_][k]["text_type"] == 1:
|
||||
@@ -357,7 +357,7 @@ def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]:
|
||||
bk = BuildImage(
|
||||
width,
|
||||
height,
|
||||
background=IMAGE_PATH / "background" / "1.png",
|
||||
background=Path(IMAGE_PATH) / "background" / "1.png",
|
||||
)
|
||||
A.paste(bk, alpha=True)
|
||||
A.text((int(width * 0.048), int(height * 0.21)), result)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from models.friend_user import FriendUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from models.bag_user import BagUser
|
||||
@@ -13,10 +13,10 @@ from utils.manager import (
|
||||
plugins2block_manager,
|
||||
plugins2count_manager
|
||||
)
|
||||
from ._utils import set_block_limit_false, status_message_manager
|
||||
from .utils import set_block_limit_false, status_message_manager
|
||||
from nonebot.typing import T_State
|
||||
from typing import Optional
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
@@ -43,7 +43,7 @@ ignore_rst_module = ["ai", "poke", "dialogue"]
|
||||
# 权限检测
|
||||
@run_preprocessor
|
||||
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
module = matcher.plugin_name
|
||||
module = matcher.module
|
||||
plugins2info_dict = plugins2settings_manager.get_data()
|
||||
# 功能的金币检测 #######################################
|
||||
# 功能的金币检测 #######################################
|
||||
@@ -83,7 +83,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
except AttributeError:
|
||||
pass
|
||||
# 群黑名单检测 群总开关检测
|
||||
if isinstance(event, GroupMessageEvent) or matcher.plugin_name == "poke":
|
||||
if isinstance(event, GroupMessageEvent) or matcher.module == "poke":
|
||||
try:
|
||||
if group_manager.get_group_level(event.group_id) < 0:
|
||||
raise IgnoredException("群黑名单")
|
||||
@@ -260,6 +260,34 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
# 以下为限制检测 #######################################################
|
||||
# 以下为限制检测 #######################################################
|
||||
# 以下为限制检测 #######################################################
|
||||
|
||||
# Cd
|
||||
if plugins2cd_manager.check_plugin_cd_status(module):
|
||||
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
|
||||
check_type = plugin_cd_data["check_type"]
|
||||
limit_type = plugin_cd_data["limit_type"]
|
||||
rst = plugin_cd_data["rst"]
|
||||
if (
|
||||
(isinstance(event, PrivateMessageEvent) and check_type == "private")
|
||||
or (isinstance(event, GroupMessageEvent) and check_type == "group")
|
||||
or plugins2cd_manager.get_plugin_data(module).get("check_type") == "all"
|
||||
):
|
||||
cd_type_ = event.user_id
|
||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||
cd_type_ = event.group_id
|
||||
if not plugins2cd_manager.check(module, cd_type_):
|
||||
if rst:
|
||||
rst = await init_rst(rst, event)
|
||||
await send_msg(rst, bot, event)
|
||||
raise IgnoredException(f"{module} 正在cd中...")
|
||||
else:
|
||||
plugins2cd_manager.start_cd(module, cd_type_)
|
||||
module = matcher.module
|
||||
if (
|
||||
isinstance(event, GroupMessageEvent)
|
||||
and status_message_manager.get(event.group_id) is None
|
||||
):
|
||||
status_message_manager.delete(event.group_id)
|
||||
# Cd
|
||||
if plugins2cd_manager.check_plugin_cd_status(module):
|
||||
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
|
||||
@@ -354,15 +382,15 @@ async def _(
|
||||
event: Event,
|
||||
state: T_State,
|
||||
):
|
||||
if not isinstance(event, MessageEvent) and matcher.plugin_name != "poke":
|
||||
if not isinstance(event, MessageEvent) and matcher.module != "poke":
|
||||
return
|
||||
module = matcher.plugin_name
|
||||
module = matcher.module
|
||||
set_block_limit_false(event, module)
|
||||
|
||||
|
||||
async def init_rst(rst: str, event: MessageEvent):
|
||||
if "[uname]" in rst:
|
||||
uname = event.sender.card or event.sender.nickname
|
||||
uname = event.sender.card if event.sender.card else event.sender.nickname
|
||||
rst = rst.replace("[uname]", uname)
|
||||
if "[nickname]" in rst:
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_preprocessor, IgnoredException
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
@@ -83,4 +83,4 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
)
|
||||
except ActionFailed:
|
||||
pass
|
||||
raise IgnoredException("用户处于黑名单中")
|
||||
raise IgnoredException("用户处于黑名单中")
|
||||
@@ -1,8 +1,8 @@
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_preprocessor, IgnoredException
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_preprocessor, IgnoredException
|
||||
from nonebot.typing import T_State
|
||||
from ._utils import status_message_manager
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from .utils import status_message_manager
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
MessageEvent,
|
||||
PrivateMessageEvent,
|
||||
@@ -24,7 +24,7 @@ async def _(matcher: Matcher, bot: Bot, event: PrivateMessageEvent, state: T_Sta
|
||||
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
if not isinstance(event, MessageEvent):
|
||||
return
|
||||
if matcher.type == "message" and matcher.plugin_name == "ai":
|
||||
if matcher.type == "message" and matcher.module == "ai":
|
||||
if (
|
||||
isinstance(event, GroupMessageEvent)
|
||||
and not status_message_manager.check(event.group_id)
|
||||
@@ -35,6 +35,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
isinstance(event, PrivateMessageEvent)
|
||||
and not status_message_manager.check(event.user_id)
|
||||
):
|
||||
print(status_message_manager)
|
||||
status_message_manager.delete(event.user_id)
|
||||
raise IgnoredException("有命令就别说话了")
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
from nonebot.exception import MockApiException
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageSegment
|
||||
from utils.manager import group_manager
|
||||
from utils.utils import get_message_text
|
||||
from typing import Dict, Any
|
||||
import re
|
||||
|
||||
|
||||
@Bot.on_calling_api
|
||||
async def handle_api_call(bot: Bot, api: str, data: Dict[str, Any]):
|
||||
r = None
|
||||
if (
|
||||
(api == "send_msg" and data["message"] == "group_id" or api == "send_group_msg")
|
||||
and (
|
||||
r := re.search(
|
||||
"^\[\[_task\|(.*)]]",
|
||||
data["message"]
|
||||
if isinstance(data["message"], str)
|
||||
else get_message_text(data["message"]),
|
||||
)
|
||||
)
|
||||
and r.group(1) in group_manager.get_task_data().keys()
|
||||
):
|
||||
task = r.group(1)
|
||||
group_id = data["group_id"]
|
||||
if not await group_manager.check_group_task_status(group_id, task):
|
||||
raise MockApiException(f"被动技能 {task} 处于关闭状态...")
|
||||
else:
|
||||
if isinstance(data["message"], str):
|
||||
msg = data["message"]
|
||||
msg = msg.replace(f"[[_task|{task}]]", "")
|
||||
data["message"] = msg
|
||||
else:
|
||||
msg = str(data["message"][0])
|
||||
msg = msg.replace(f"[[_task|{task}]]", "")
|
||||
data["message"][0] = MessageSegment.text(msg)
|
||||
Regular → Executable
+48
-48
@@ -1,48 +1,48 @@
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent
|
||||
from utils.manager import plugins2block_manager, StaticData
|
||||
import time
|
||||
|
||||
|
||||
class StatusMessageManager(StaticData):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(None)
|
||||
|
||||
def add(self, id_: int):
|
||||
self._data[id_] = time.time()
|
||||
|
||||
def delete(self, id_: int):
|
||||
if self._data.get(id_):
|
||||
del self._data[id_]
|
||||
|
||||
def check(self, id_: int, t: int = 30) -> bool:
|
||||
if self._data.get(id_):
|
||||
if time.time() - self._data[id_] > t:
|
||||
del self._data[id_]
|
||||
return True
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
status_message_manager = StatusMessageManager()
|
||||
|
||||
|
||||
def set_block_limit_false(event, module):
|
||||
"""
|
||||
设置用户block为false
|
||||
:param event: event
|
||||
:param module: 插件模块
|
||||
"""
|
||||
if plugins2block_manager.check_plugin_block_status(module):
|
||||
plugin_block_data = plugins2block_manager.get_plugin_block_data(module)
|
||||
check_type = plugin_block_data["check_type"]
|
||||
limit_type = plugin_block_data["limit_type"]
|
||||
if not (
|
||||
(isinstance(event, GroupMessageEvent) and check_type == "private")
|
||||
or (isinstance(event, PrivateMessageEvent) and check_type == "group")
|
||||
):
|
||||
block_type_ = event.user_id
|
||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||
block_type_ = event.group_id
|
||||
plugins2block_manager.set_false(block_type_, module)
|
||||
|
||||
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent
|
||||
from utils.manager import plugins2block_manager, StaticData
|
||||
import time
|
||||
|
||||
|
||||
class StatusMessageManager(StaticData):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(None)
|
||||
|
||||
def add(self, id_: int):
|
||||
self._data[id_] = time.time()
|
||||
|
||||
def delete(self, id_: int):
|
||||
if self._data.get(id_):
|
||||
del self._data[id_]
|
||||
|
||||
def check(self, id_: int, t: int = 30) -> bool:
|
||||
if self._data.get(id_):
|
||||
if time.time() - self._data[id_] > t:
|
||||
del self._data[id_]
|
||||
return True
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
status_message_manager = StatusMessageManager()
|
||||
|
||||
|
||||
def set_block_limit_false(event, module):
|
||||
"""
|
||||
设置用户block为false
|
||||
:param event: event
|
||||
:param module: 插件模块
|
||||
"""
|
||||
if plugins2block_manager.check_plugin_block_status(module):
|
||||
plugin_block_data = plugins2block_manager.get_plugin_block_data(module)
|
||||
check_type = plugin_block_data["check_type"]
|
||||
limit_type = plugin_block_data["limit_type"]
|
||||
if not (
|
||||
(isinstance(event, GroupMessageEvent) and check_type == "private")
|
||||
or (isinstance(event, PrivateMessageEvent) and check_type == "group")
|
||||
):
|
||||
block_type_ = event.user_id
|
||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||
block_type_ = event.group_id
|
||||
plugins2block_manager.set_false(block_type_, module)
|
||||
|
||||
@@ -2,7 +2,7 @@ from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_postprocessor
|
||||
from typing import Optional
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import Bot, Event
|
||||
from nonebot.adapters.cqhttp import Bot, Event
|
||||
from utils.manager import withdraw_message_manager
|
||||
import asyncio
|
||||
|
||||
@@ -25,4 +25,4 @@ async def _(
|
||||
|
||||
async def _withdraw_message(bot: Bot, id_: int, time: int):
|
||||
await asyncio.sleep(time)
|
||||
await bot.delete_msg(message_id=id_)
|
||||
await bot.delete_msg(message_id=id_, self_id=int(bot.self_id))
|
||||
|
||||
@@ -11,7 +11,8 @@ from .init_plugins_limit import (
|
||||
)
|
||||
from .init import init
|
||||
from .check_plugin_status import check_plugin_status
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from utils.manager import admin_manager
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
from configs.path_config import DATA_PATH
|
||||
from services.log import logger
|
||||
from pathlib import Path
|
||||
@@ -33,7 +34,7 @@ def _():
|
||||
初始化数据
|
||||
"""
|
||||
_flag = False
|
||||
config_file = DATA_PATH / "configs" / "plugins2config.yaml"
|
||||
config_file = Path(DATA_PATH) / "configs" / "plugins2config.yaml"
|
||||
if not config_file.exists():
|
||||
_flag = True
|
||||
init()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from utils.manager import plugins_manager
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
|
||||
|
||||
async def check_plugin_status(bot: Bot):
|
||||
|
||||
@@ -15,14 +15,14 @@ def init_plugins_config(data_path):
|
||||
"""
|
||||
初始化插件数据配置
|
||||
"""
|
||||
plugins2config_file = data_path / "configs" / "plugins2config.yaml"
|
||||
plugins2config_file = Path(data_path) / "configs" / "plugins2config.yaml"
|
||||
plugins2config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
_data = {}
|
||||
if plugins2config_file.exists():
|
||||
_data = _yaml.load(open(plugins2config_file, "r", encoding="utf8"))
|
||||
_matchers = get_matchers()
|
||||
for matcher in _matchers:
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
except AttributeError:
|
||||
@@ -39,16 +39,16 @@ def init_plugins_config(data_path):
|
||||
if (
|
||||
plugin_version is None
|
||||
or (
|
||||
_data.get(matcher.plugin_name)
|
||||
and _data[matcher.plugin_name].keys() != plugin_configs.keys()
|
||||
_data.get(matcher.module)
|
||||
and _data[matcher.module].keys() != plugin_configs.keys()
|
||||
)
|
||||
or plugin_version > plugins_manager.get(matcher.plugin_name)["version"]
|
||||
or matcher.plugin_name not in _data.keys()
|
||||
or plugin_version > plugins_manager.get(matcher.module)["version"]
|
||||
or matcher.module not in _data.keys()
|
||||
):
|
||||
for key in plugin_configs:
|
||||
if isinstance(plugin_configs[key], dict):
|
||||
Config.add_plugin_config(
|
||||
matcher.plugin_name,
|
||||
matcher.module,
|
||||
key,
|
||||
plugin_configs[key].get("value"),
|
||||
help_=plugin_configs[key].get("help"),
|
||||
@@ -56,12 +56,12 @@ def init_plugins_config(data_path):
|
||||
_override=True,
|
||||
)
|
||||
else:
|
||||
Config.add_plugin_config(matcher.plugin_name, key, plugin_configs[key])
|
||||
Config.add_plugin_config(matcher.module, key, plugin_configs[key])
|
||||
else:
|
||||
plugin_configs = _data[matcher.plugin_name]
|
||||
plugin_configs = _data[matcher.module]
|
||||
for key in plugin_configs:
|
||||
Config.add_plugin_config(
|
||||
matcher.plugin_name,
|
||||
matcher.module,
|
||||
key,
|
||||
plugin_configs[key]["value"],
|
||||
help_=plugin_configs[key]["help"],
|
||||
@@ -99,10 +99,7 @@ def init_plugins_config(data_path):
|
||||
if _data.get(plugin) and k in _data[plugin].keys():
|
||||
Config.set_config(plugin, k, _data[plugin][k])
|
||||
if level2module := Config.get_level2module(plugin, k):
|
||||
try:
|
||||
admin_manager.set_admin_level(level2module, _data[plugin][k])
|
||||
except KeyError:
|
||||
logger.warning(f"{level2module} 设置权限等级失败:{_data[plugin][k]}")
|
||||
admin_manager.set_admin_level(level2module, _data[plugin][k])
|
||||
_tmp_data[plugin][k] = Config.get_config(plugin, k)
|
||||
Config.save()
|
||||
temp_file = Path() / "configs" / "temp_config.yaml"
|
||||
|
||||
@@ -17,27 +17,27 @@ def init_plugins_data(data_path):
|
||||
"""
|
||||
初始化插件数据信息
|
||||
"""
|
||||
plugin2data_file = data_path / "manager" / "plugin_manager.json"
|
||||
plugin2data_file = Path(data_path) / "manager" / "plugin_manager.json"
|
||||
plugin2data_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
_data = {}
|
||||
if plugin2data_file.exists():
|
||||
_data = json.load(open(plugin2data_file, "r", encoding="utf8"))
|
||||
_matchers = get_matchers()
|
||||
for matcher in _matchers:
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
except AttributeError:
|
||||
if matcher.plugin_name not in _data.keys():
|
||||
if matcher.module not in _data.keys():
|
||||
plugins_manager.add_plugin_data(
|
||||
matcher.plugin_name, matcher.plugin_name, error=True
|
||||
matcher.module, matcher.module, error=True
|
||||
)
|
||||
else:
|
||||
plugins_manager.set_module_data(matcher.plugin_name, "error", True)
|
||||
plugin_data = plugins_manager.get(matcher.plugin_name)
|
||||
plugins_manager.set_module_data(matcher.module, "error", True)
|
||||
plugin_data = plugins_manager.get(matcher.module)
|
||||
if plugin_data:
|
||||
plugins_manager.set_module_data(
|
||||
matcher.plugin_name, "version", plugin_data.get("version")
|
||||
matcher.module, "version", plugin_data.get("version")
|
||||
)
|
||||
else:
|
||||
try:
|
||||
@@ -47,36 +47,36 @@ def init_plugins_data(data_path):
|
||||
try:
|
||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
||||
except AttributeError:
|
||||
plugin_name = matcher.plugin_name
|
||||
plugin_name = matcher.module
|
||||
try:
|
||||
plugin_author = _module.__getattribute__("__plugin_author__")
|
||||
except AttributeError:
|
||||
plugin_author = None
|
||||
if matcher.plugin_name in plugins_manager.keys():
|
||||
plugins_manager.set_module_data(matcher.plugin_name, "error", False)
|
||||
if matcher.plugin_name not in plugins_manager.keys():
|
||||
if matcher.module in plugins_manager.keys():
|
||||
plugins_manager.set_module_data(matcher.module, "error", False)
|
||||
if matcher.module not in plugins_manager.keys():
|
||||
plugins_manager.add_plugin_data(
|
||||
matcher.plugin_name,
|
||||
matcher.module,
|
||||
plugin_name=plugin_name,
|
||||
author=plugin_author,
|
||||
version=plugin_version,
|
||||
)
|
||||
elif plugins_manager[matcher.plugin_name]["version"] is None or (
|
||||
elif plugins_manager[matcher.module]["version"] is None or (
|
||||
plugin_version is not None
|
||||
and plugin_version > plugins_manager[matcher.plugin_name]["version"]
|
||||
and plugin_version > plugins_manager[matcher.module]["version"]
|
||||
):
|
||||
plugins_manager.set_module_data(
|
||||
matcher.plugin_name, "plugin_name", plugin_name
|
||||
matcher.module, "plugin_name", plugin_name
|
||||
)
|
||||
plugins_manager.set_module_data(matcher.plugin_name, "author", plugin_author)
|
||||
plugins_manager.set_module_data(matcher.module, "author", plugin_author)
|
||||
plugins_manager.set_module_data(
|
||||
matcher.plugin_name, "version", plugin_version
|
||||
matcher.module, "version", plugin_version
|
||||
)
|
||||
if matcher.plugin_name in _data.keys():
|
||||
if matcher.module in _data.keys():
|
||||
plugins_manager.set_module_data(
|
||||
matcher.plugin_name, "error", _data[matcher.plugin_name]["error"]
|
||||
matcher.module, "error", _data[matcher.module]["error"]
|
||||
)
|
||||
plugins_manager.set_module_data(
|
||||
matcher.plugin_name, "plugin_name", _data[matcher.plugin_name]["plugin_name"]
|
||||
matcher.module, "plugin_name", _data[matcher.module]["plugin_name"]
|
||||
)
|
||||
plugins_manager.save()
|
||||
|
||||
@@ -17,18 +17,18 @@ def init_plugins_cd_limit(data_path):
|
||||
"""
|
||||
加载 cd 限制
|
||||
"""
|
||||
plugins2cd_file = data_path / "configs" / "plugins2cd.yaml"
|
||||
plugins2cd_file = Path(data_path) / "configs" / "plugins2cd.yaml"
|
||||
plugins2cd_file.parent.mkdir(exist_ok=True, parents=True)
|
||||
_data = {}
|
||||
_matchers = get_matchers()
|
||||
for matcher in _matchers:
|
||||
if not plugins2cd_manager.get_plugin_cd_data(matcher.plugin_name):
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
if not plugins2cd_manager.get_plugin_cd_data(matcher.module):
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
plugin_cd_limit = _module.__getattribute__("__plugin_cd_limit__")
|
||||
plugins2cd_manager.add_cd_limit(
|
||||
matcher.plugin_name, data_dict=plugin_cd_limit
|
||||
matcher.module, data_dict=plugin_cd_limit
|
||||
)
|
||||
except AttributeError:
|
||||
pass
|
||||
@@ -65,18 +65,18 @@ def init_plugins_block_limit(data_path):
|
||||
"""
|
||||
加载阻塞限制
|
||||
"""
|
||||
plugins2block_file = data_path / "configs" / "plugins2block.yaml"
|
||||
plugins2block_file = Path(data_path) / "configs" / "plugins2block.yaml"
|
||||
plugins2block_file.parent.mkdir(exist_ok=True, parents=True)
|
||||
_data = {}
|
||||
_matchers = get_matchers()
|
||||
for matcher in _matchers:
|
||||
if not plugins2block_manager.get_plugin_block_data(matcher.plugin_name):
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
if not plugins2block_manager.get_plugin_block_data(matcher.module):
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
plugin_block_limit = _module.__getattribute__("__plugin_block_limit__")
|
||||
plugins2block_manager.add_block_limit(
|
||||
matcher.plugin_name, data_dict=plugin_block_limit
|
||||
matcher.module, data_dict=plugin_block_limit
|
||||
)
|
||||
except AttributeError:
|
||||
pass
|
||||
@@ -113,18 +113,18 @@ def init_plugins_count_limit(data_path):
|
||||
"""
|
||||
加载次数限制
|
||||
"""
|
||||
plugins2count_file = data_path / "configs" / "plugins2count.yaml"
|
||||
plugins2count_file = Path(data_path) / "configs" / "plugins2count.yaml"
|
||||
plugins2count_file.parent.mkdir(exist_ok=True, parents=True)
|
||||
_data = {}
|
||||
_matchers = get_matchers()
|
||||
for matcher in _matchers:
|
||||
if not plugins2count_manager.get_plugin_count_data(matcher.plugin_name):
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
if not plugins2count_manager.get_plugin_count_data(matcher.module):
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
plugin_count_limit = _module.__getattribute__("__plugin_count_limit__")
|
||||
plugins2count_manager.add_count_limit(
|
||||
matcher.plugin_name, data_dict=plugin_count_limit
|
||||
matcher.module, data_dict=plugin_count_limit
|
||||
)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
@@ -11,13 +11,13 @@ def init_plugins_resources():
|
||||
"""
|
||||
_tmp = []
|
||||
for matcher in get_matchers():
|
||||
if matcher.plugin_name not in _tmp:
|
||||
_tmp.append(matcher.plugin_name)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
if matcher.module not in _tmp:
|
||||
_tmp.append(matcher.module)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
except AttributeError:
|
||||
logger.warning(f"插件 {matcher.plugin_name} 加载失败...,资源控制未加载...")
|
||||
logger.warning(f"插件 {matcher.module} 加载失败...,资源控制未加载...")
|
||||
else:
|
||||
try:
|
||||
resources = _module.__getattribute__("__plugin_resources__")
|
||||
@@ -26,7 +26,7 @@ def init_plugins_resources():
|
||||
else:
|
||||
path = Path(_module.__getattribute__("__file__")).parent
|
||||
for resource in resources.keys():
|
||||
resources_manager.add_resource(matcher.plugin_name, path / resource, resources[resource])
|
||||
resources_manager.add_resource(matcher.module, (path / resource).absolute(), resources[resource])
|
||||
resources_manager.save()
|
||||
resources_manager.start_move()
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ def init_plugins_settings(data_path: str):
|
||||
"""
|
||||
初始化插件设置,从插件中获取 __zx_plugin_name__,__plugin_cmd__,__plugin_settings__
|
||||
"""
|
||||
plugins2settings_file = data_path / "configs" / "plugins2settings.yaml"
|
||||
plugins2settings_file = Path(data_path) / "configs" / "plugins2settings.yaml"
|
||||
plugins2settings_file.parent.mkdir(exist_ok=True, parents=True)
|
||||
_matchers = get_matchers()
|
||||
_tmp_module = {}
|
||||
@@ -29,12 +29,12 @@ def init_plugins_settings(data_path: str):
|
||||
logger.warning(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}")
|
||||
_tmp_module[x] = ""
|
||||
for matcher in _matchers:
|
||||
if matcher.plugin_name not in plugins2settings_manager.keys():
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
if matcher.module not in plugins2settings_manager.keys():
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
try:
|
||||
_module = _plugin.module
|
||||
except AttributeError:
|
||||
logger.warning(f"插件 {matcher.plugin_name} 加载失败...,插件控制未加载.")
|
||||
logger.warning(f"插件 {matcher.module} 加载失败...,插件控制未加载.")
|
||||
else:
|
||||
try:
|
||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
||||
@@ -51,23 +51,23 @@ def init_plugins_settings(data_path: str):
|
||||
if level is None:
|
||||
level = 5
|
||||
admin_manager.add_admin_plugin_settings(
|
||||
matcher.plugin_name, cmd, level
|
||||
matcher.module, cmd, level
|
||||
)
|
||||
if (
|
||||
"[hidden]" in plugin_name.lower()
|
||||
or "[admin]" in plugin_name.lower()
|
||||
or "[superuser]" in plugin_name.lower()
|
||||
or matcher.plugin_name in plugins2settings_manager.keys()
|
||||
or matcher.module in plugins2settings_manager.keys()
|
||||
):
|
||||
continue
|
||||
except AttributeError:
|
||||
if matcher.plugin_name not in _tmp:
|
||||
if matcher.module not in _tmp:
|
||||
logger.warning(
|
||||
f"获取插件 {matcher.plugin_name} __zx_plugin_name__ 失败...,插件控制未加载."
|
||||
f"获取插件 {matcher.module} __zx_plugin_name__ 失败...,插件控制未加载."
|
||||
)
|
||||
else:
|
||||
try:
|
||||
_tmp_module[matcher.plugin_name] = plugin_name
|
||||
_tmp_module[matcher.module] = plugin_name
|
||||
plugin_settings = _module.__getattribute__(
|
||||
"__plugin_settings__"
|
||||
)
|
||||
@@ -79,13 +79,13 @@ def init_plugins_settings(data_path: str):
|
||||
):
|
||||
plugin_settings["cmd"].append(plugin_name)
|
||||
if plugins2settings_manager.get(
|
||||
matcher.plugin_name
|
||||
) and plugins2settings_manager[matcher.plugin_name].get(
|
||||
matcher.module
|
||||
) and plugins2settings_manager[matcher.module].get(
|
||||
"plugin_type"
|
||||
):
|
||||
plugin_type = tuple(
|
||||
plugins2settings_manager.get_plugin_data(
|
||||
matcher.plugin_name
|
||||
matcher.module
|
||||
)["plugin_type"]
|
||||
)
|
||||
else:
|
||||
@@ -95,15 +95,15 @@ def init_plugins_settings(data_path: str):
|
||||
)
|
||||
except AttributeError:
|
||||
plugin_type = ("normal",)
|
||||
if plugin_settings and matcher.plugin_name:
|
||||
if plugin_settings and matcher.module:
|
||||
plugins2settings_manager.add_plugin_settings(
|
||||
matcher.plugin_name,
|
||||
matcher.module,
|
||||
plugin_type=plugin_type,
|
||||
**plugin_settings,
|
||||
)
|
||||
except AttributeError:
|
||||
pass
|
||||
_tmp.append(matcher.plugin_name)
|
||||
_tmp.append(matcher.module)
|
||||
_tmp_data = {"PluginSettings": plugins2settings_manager.get_data()}
|
||||
with open(plugins2settings_file, "w", encoding="utf8") as wf:
|
||||
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from nonebot import on_request, on_message
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
FriendRequestEvent,
|
||||
GroupRequestEvent,
|
||||
@@ -8,7 +8,7 @@ from nonebot.adapters.onebot.v11 import (
|
||||
from models.friend_user import FriendUser
|
||||
from datetime import datetime
|
||||
from configs.config import NICKNAME, Config
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from utils.manager import requests_manager
|
||||
from models.group_info import GroupInfo
|
||||
from utils.utils import scheduler
|
||||
@@ -31,7 +31,7 @@ exists_data = {"private": {}, "group": {}}
|
||||
|
||||
|
||||
@friend_req.handle()
|
||||
async def _(bot: Bot, event: FriendRequestEvent):
|
||||
async def _(bot: Bot, event: FriendRequestEvent, state: dict):
|
||||
global exists_data
|
||||
if exists_data["private"].get(event.user_id):
|
||||
if time.time() - exists_data["private"][event.user_id] < 60 * 5:
|
||||
@@ -66,7 +66,7 @@ async def _(bot: Bot, event: FriendRequestEvent):
|
||||
|
||||
|
||||
@group_req.handle()
|
||||
async def _(bot: Bot, event: GroupRequestEvent):
|
||||
async def _(bot: Bot, event: GroupRequestEvent, state: dict):
|
||||
global exists_data
|
||||
if event.sub_type == "invite":
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
@@ -125,7 +125,7 @@ async def _(bot: Bot, event: GroupRequestEvent):
|
||||
|
||||
|
||||
@x.handle()
|
||||
async def _(event: MessageEvent):
|
||||
async def _(bot: Bot, event: MessageEvent, state: dict):
|
||||
await asyncio.sleep(0.1)
|
||||
r = re.search(r'groupcode="(.*?)"', str(event.get_message()))
|
||||
if r:
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, PrivateMessageEvent, Message
|
||||
from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, PrivateMessageEvent
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import get_message_text
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from models.friend_user import FriendUser
|
||||
import random
|
||||
from models.ban_user import BanUser
|
||||
from services.log import logger
|
||||
from configs.config import NICKNAME, Config
|
||||
from nonebot.params import CommandArg
|
||||
import random
|
||||
|
||||
|
||||
__zx_plugin_name__ = "昵称系统"
|
||||
__plugin_usage__ = f"""
|
||||
@@ -47,8 +48,8 @@ cancel_nickname = on_command("取消昵称", rule=to_me(), priority=5, block=Tru
|
||||
|
||||
|
||||
@nickname.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if not msg:
|
||||
await nickname.finish("叫你空白?叫你虚空?叫你无名??", at_sender=True)
|
||||
if len(msg) > 10:
|
||||
@@ -102,7 +103,7 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@my_nickname.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
try:
|
||||
nickname_ = await GroupInfoUser.get_group_member_nickname(
|
||||
event.user_id, event.group_id
|
||||
@@ -123,7 +124,7 @@ async def _(event: GroupMessageEvent):
|
||||
)
|
||||
)
|
||||
else:
|
||||
nickname_ = event.sender.card or event.sender.nickname
|
||||
nickname_ = event.sender.card if event.sender.card else event.sender.nickname
|
||||
await my_nickname.send(
|
||||
random.choice(
|
||||
["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"]
|
||||
@@ -157,7 +158,7 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
|
||||
|
||||
@cancel_nickname.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
nickname_ = await GroupInfoUser.get_group_member_nickname(
|
||||
event.user_id, event.group_id
|
||||
)
|
||||
@@ -180,7 +181,7 @@ async def _(event: GroupMessageEvent):
|
||||
|
||||
|
||||
@cancel_nickname.handle()
|
||||
async def _(event: PrivateMessageEvent):
|
||||
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
nickname_ = await FriendUser.get_friend_nickname(event.user_id)
|
||||
if nickname_:
|
||||
await cancel_nickname.send(
|
||||
|
||||
+6
-102
@@ -1,19 +1,14 @@
|
||||
from asyncpg.exceptions import (
|
||||
DuplicateColumnError,
|
||||
UndefinedColumnError,
|
||||
PostgresSyntaxError,
|
||||
)
|
||||
from nonebot import Driver
|
||||
from services.db_context import db
|
||||
from asyncpg.exceptions import DuplicateColumnError
|
||||
from models.group_info import GroupInfo
|
||||
from models.bag_user import BagUser
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
from services.log import logger
|
||||
from configs.path_config import TEXT_PATH
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from typing import List
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.utils import scheduler
|
||||
from pathlib import Path
|
||||
import nonebot
|
||||
|
||||
try:
|
||||
@@ -31,7 +26,7 @@ async def update_city():
|
||||
部分插件需要中国省份城市
|
||||
这里直接更新,避免插件内代码重复
|
||||
"""
|
||||
china_city = TEXT_PATH / "china_city.json"
|
||||
china_city = Path(TEXT_PATH) / "china_city.json"
|
||||
data = {}
|
||||
if not china_city.exists():
|
||||
try:
|
||||
@@ -66,86 +61,15 @@ async def _():
|
||||
"""
|
||||
数据库表结构变换
|
||||
"""
|
||||
_flag = []
|
||||
sql_str = [
|
||||
(
|
||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;",
|
||||
"group_info",
|
||||
), # group_info表添加一个group_flag
|
||||
(
|
||||
"ALTER TABLE bag_users rename belonging_group To group_id;",
|
||||
"bag_users",
|
||||
), # 将 bag_users 的 belonging_group 改为 group_id
|
||||
(
|
||||
"ALTER TABLE group_info_users rename belonging_group To group_id;",
|
||||
"group_info_users",
|
||||
),
|
||||
(
|
||||
"ALTER TABLE sign_group_users rename belonging_group To group_id;",
|
||||
"sign_group_users",
|
||||
),
|
||||
(
|
||||
"ALTER TABLE open_cases_users rename belonging_group To group_id;",
|
||||
"open_cases_users",
|
||||
),
|
||||
(
|
||||
"ALTER TABLE bag_users ADD property json NOT NULL DEFAULT '{}';",
|
||||
"bag_users",
|
||||
), # bag_users 新增字段 property 替代 props
|
||||
(
|
||||
"ALTER TABLE genshin ADD auto_sign_time timestamp with time zone;",
|
||||
"genshin"
|
||||
), # 新增原神自动签到字段
|
||||
(
|
||||
"ALTER TABLE genshin ADD resin_remind boolean DEFAULT False;",
|
||||
"genshin"
|
||||
), # 新增原神自动签到字段
|
||||
(
|
||||
"ALTER TABLE genshin ADD resin_recovery_time timestamp with time zone;",
|
||||
"genshin"
|
||||
), # 新增原神自动签到字段
|
||||
(
|
||||
"ALTER TABLE genshin ADD bind_group Integer;",
|
||||
"genshin"
|
||||
), # 新增原神群号绑定字段
|
||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag
|
||||
]
|
||||
for sql in sql_str:
|
||||
try:
|
||||
flag = sql[1]
|
||||
sql = sql[0]
|
||||
query = db.text(sql)
|
||||
await db.first(query)
|
||||
logger.info(f"完成sql操作:{sql}")
|
||||
_flag.append(flag)
|
||||
except (DuplicateColumnError, UndefinedColumnError):
|
||||
except DuplicateColumnError:
|
||||
pass
|
||||
except PostgresSyntaxError:
|
||||
logger.error(f"语法错误:执行sql失败:{sql}")
|
||||
# bag_user 将文本转为字典格式
|
||||
await __database_script(_flag)
|
||||
|
||||
# 完成后
|
||||
end_sql_str = [
|
||||
# "ALTER TABLE bag_users DROP COLUMN props;" # 删除 bag_users 的 props 字段(还不到时候)
|
||||
]
|
||||
for sql in end_sql_str:
|
||||
try:
|
||||
query = db.text(sql)
|
||||
await db.first(query)
|
||||
logger.info(f"完成执行sql操作:{sql}")
|
||||
except (DuplicateColumnError, UndefinedColumnError):
|
||||
pass
|
||||
except PostgresSyntaxError:
|
||||
logger.error(f"语法错误:执行sql失败:{sql}")
|
||||
|
||||
# str2json_sql = ["alter table bag_users alter COLUMN props type json USING props::json;"] # 字段类型替换
|
||||
# rename_sql = 'alter table {} rename {} to {};' # 字段更名
|
||||
# for sql in str2json_sql:
|
||||
# try:
|
||||
# query = db.text(sql)
|
||||
# await db.first(query)
|
||||
# except DuplicateColumnError:
|
||||
# pass
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
@@ -181,26 +105,6 @@ async def _(bot: Bot):
|
||||
logger.info(f"移除不存在的群聊信息:{group_id}")
|
||||
|
||||
|
||||
async def __database_script(_flag: List[str]):
|
||||
# bag_user 将文本转为字典格式
|
||||
if "bag_users" in _flag:
|
||||
for x in await BagUser.get_all_users():
|
||||
props = {}
|
||||
if x.props:
|
||||
for prop in [p for p in x.props.split(",") if p]:
|
||||
if props.get(prop):
|
||||
props[prop] += 1
|
||||
else:
|
||||
props[prop] = 1
|
||||
logger.info(
|
||||
f"__database_script USER {x.user_qq} GROUP {x.group_id} 更新数据 {props}"
|
||||
)
|
||||
await x.update(
|
||||
property=props,
|
||||
props="",
|
||||
).apply()
|
||||
|
||||
|
||||
# 自动更新城市列表
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
|
||||
+18
-26
@@ -1,13 +1,12 @@
|
||||
from nonebot import on_command
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
from utils.utils import is_number
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from utils.utils import get_message_text, is_number
|
||||
from models.bag_user import BagUser
|
||||
from services.db_context import db
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from models.goods_info import GoodsInfo
|
||||
import time
|
||||
|
||||
|
||||
__zx_plugin_name__ = "商店 - 购买道具"
|
||||
@@ -21,7 +20,7 @@ usage:
|
||||
""".strip()
|
||||
__plugin_des__ = "商店 - 购买道具"
|
||||
__plugin_cmd__ = ["购买 [序号或名称] ?[数量=1]"]
|
||||
__plugin_type__ = ("商店",)
|
||||
__plugin_type__ = ('商店',)
|
||||
__plugin_version__ = 0.1
|
||||
__plugin_author__ = "HibiKier"
|
||||
__plugin_settings__ = {
|
||||
@@ -30,43 +29,36 @@ __plugin_settings__ = {
|
||||
"limit_superuser": False,
|
||||
"cmd": ["商店", "购买道具"],
|
||||
}
|
||||
__plugin_cd_limit__ = {"cd": 3}
|
||||
|
||||
|
||||
buy = on_command("购买", aliases={"购买道具"}, priority=5, block=True, permission=GROUP)
|
||||
|
||||
|
||||
@buy.handle()
|
||||
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
goods = None
|
||||
if arg.extract_plain_text().strip() in ["神秘药水"]:
|
||||
if get_message_text(event.json()) in ["神秘药水"]:
|
||||
await buy.finish("你们看看就好啦,这是不可能卖给你们的~", at_sender=True)
|
||||
goods_list = [
|
||||
x
|
||||
for x in await GoodsInfo.get_all_goods()
|
||||
if x.goods_limit_time > time.time() or x.goods_limit_time == 0
|
||||
]
|
||||
goods_name_list = [
|
||||
x.goods_name
|
||||
for x in goods_list
|
||||
]
|
||||
msg = arg.extract_plain_text().strip().split()
|
||||
goods_lst = await GoodsInfo.get_all_goods()
|
||||
goods_name_lst = [x.goods_name for x in goods_lst]
|
||||
msg = get_message_text(event.json()).split()
|
||||
num = 1
|
||||
if len(msg) > 1:
|
||||
if is_number(msg[1]) and int(msg[1]) > 0:
|
||||
num = int(msg[1])
|
||||
else:
|
||||
await buy.finish("购买的数量要是数字且大于0!", at_sender=True)
|
||||
# print(msg, num)
|
||||
if is_number(msg[0]):
|
||||
msg = int(msg[0])
|
||||
if msg > len(goods_name_list) or msg < 1:
|
||||
if msg > len(goods_lst) or msg < 1:
|
||||
await buy.finish("请输入正确的商品id!", at_sender=True)
|
||||
goods = goods_list[msg - 1]
|
||||
goods = goods_lst[msg - 1]
|
||||
else:
|
||||
if msg[0] in goods_name_list:
|
||||
for i in range(len(goods_name_list)):
|
||||
if msg[0] == goods_name_list[i]:
|
||||
goods = goods_list[i]
|
||||
if msg[0] in goods_name_lst:
|
||||
for i in range(len(goods_name_lst)):
|
||||
if msg[0] == goods_name_lst[i]:
|
||||
goods = goods_lst[i]
|
||||
break
|
||||
else:
|
||||
await buy.finish("请输入正确的商品名称!")
|
||||
@@ -77,7 +69,7 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
await BagUser.get_gold(event.user_id, event.group_id)
|
||||
) < goods.goods_price * num * goods.goods_discount:
|
||||
await buy.finish("您的金币好像不太够哦", at_sender=True)
|
||||
if await BagUser.buy_property(event.user_id, event.group_id, goods, num):
|
||||
if await BagUser.buy_props(event.user_id, event.group_id, goods, num):
|
||||
await buy.send(
|
||||
f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!",
|
||||
at_sender=True,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from utils.data_utils import init_rank
|
||||
from models.bag_user import BagUser
|
||||
from utils.message_builder import image
|
||||
from utils.utils import is_number
|
||||
from utils.utils import get_message_text, is_number
|
||||
|
||||
__zx_plugin_name__ = "商店 - 我的金币"
|
||||
__plugin_usage__ = """
|
||||
@@ -33,13 +33,13 @@ gold_rank = on_command("金币排行", priority=5, block=True, permission=GROUP)
|
||||
|
||||
|
||||
@my_gold.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
await my_gold.finish(await BagUser.get_user_total_gold(event.user_id, event.group_id))
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await my_gold.finish(await BagUser.get_my_total_gold(event.user_id, event.group_id))
|
||||
|
||||
|
||||
@gold_rank.handle()
|
||||
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
num = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
num = get_message_text(event.json())
|
||||
if is_number(num) and 51 > int(num) > 10:
|
||||
num = int(num)
|
||||
else:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from nonebot import on_command
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from models.bag_user import BagUser
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
|
||||
|
||||
__zx_plugin_name__ = "商店 - 我的道具"
|
||||
@@ -29,12 +30,22 @@ my_props = on_command("我的道具", priority=5, block=True, permission=GROUP)
|
||||
|
||||
|
||||
@my_props.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
props = await BagUser.get_property(event.user_id, event.group_id)
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
props = await BagUser.get_props(event.user_id, event.group_id)
|
||||
if props:
|
||||
pname_list = []
|
||||
pnum_list = []
|
||||
rst = ""
|
||||
for i, p in enumerate(props.keys()):
|
||||
rst += f"{i+1}.{p}\t×{props[p]}\n"
|
||||
props = props[:-1].split(",")
|
||||
for p in props:
|
||||
if p != "":
|
||||
if p in pname_list:
|
||||
pnum_list[pname_list.index(p)] += 1
|
||||
else:
|
||||
pname_list.append(p)
|
||||
pnum_list.append(1)
|
||||
for i in range(len(pname_list)):
|
||||
rst += f"{i+1}.{pname_list[i]}\t×{pnum_list[i]}\n"
|
||||
await my_props.send("\n" + rst[:-1], at_sender=True)
|
||||
logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具")
|
||||
else:
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from .data_source import create_shop_help, delete_goods, update_goods, register_goods, parse_goods_info
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from .data_source import create_shop_help, delete_goods, update_goods, registered_goods, parse_goods_info
|
||||
from nonebot.permission import SUPERUSER
|
||||
from utils.utils import is_number
|
||||
from nonebot.params import CommandArg
|
||||
from utils.utils import get_message_text, is_number
|
||||
from nonebot.plugin import export
|
||||
from services.log import logger
|
||||
import os
|
||||
@@ -53,7 +53,7 @@ __plugin_block_limit__ = {
|
||||
|
||||
# 导出方法供其他插件使用
|
||||
export = export()
|
||||
export.register_goods = register_goods
|
||||
export.registered_goods = registered_goods
|
||||
export.delete_goods = delete_goods
|
||||
export.update_goods = update_goods
|
||||
|
||||
@@ -67,20 +67,20 @@ shop_update_goods = on_command("修改商品", priority=5, permission=SUPERUSER,
|
||||
|
||||
|
||||
@shop_help.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await shop_help.send(image(b64=await create_shop_help()))
|
||||
|
||||
|
||||
@shop_add_goods.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if msg:
|
||||
data = parse_goods_info(msg)
|
||||
if isinstance(data, str):
|
||||
await shop_add_goods.finish(data)
|
||||
if not data.get("name") or not data.get("price") or not data.get("des"):
|
||||
await shop_add_goods.finish("name:price:des 参数不可缺少!")
|
||||
if await register_goods(**data):
|
||||
if await registered_goods(**data):
|
||||
await shop_add_goods.send(f"添加商品 {data['name']} 成功!\n"
|
||||
f"名称:{data['name']}\n"
|
||||
f"价格:{data['price']}金币\n"
|
||||
@@ -94,8 +94,8 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@shop_del_goods.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if msg:
|
||||
name = ""
|
||||
id_ = 0
|
||||
@@ -115,8 +115,8 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@shop_update_goods.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if msg:
|
||||
data = parse_goods_info(msg)
|
||||
if isinstance(data, str):
|
||||
|
||||
@@ -20,24 +20,36 @@ async def init_default_shop_goods():
|
||||
"""
|
||||
导入内置的三个商品
|
||||
"""
|
||||
async def sign_card(**kwargs):
|
||||
|
||||
async def sign_card_1(**kwargs):
|
||||
user_id = kwargs['user_id']
|
||||
group_id = kwargs['group_id']
|
||||
prob = kwargs["prob"]
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=prob).apply()
|
||||
await user.update(add_probability=0.1).apply()
|
||||
|
||||
async def sign_card_2(**kwargs):
|
||||
user_id = kwargs['user_id']
|
||||
group_id = kwargs['group_id']
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=0.2).apply()
|
||||
|
||||
async def sign_card_3(**kwargs):
|
||||
user_id = kwargs['user_id']
|
||||
group_id = kwargs['group_id']
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=0.3).apply()
|
||||
|
||||
if Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"):
|
||||
await register_goods(
|
||||
await registered_goods(
|
||||
"好感度双倍加持卡Ⅰ", 30, "下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)"
|
||||
)
|
||||
use.register_use("好感度双倍加持卡Ⅰ", sign_card, **{"prob": 0.1})
|
||||
await register_goods("好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)")
|
||||
use.register_use("好感度双倍加持卡Ⅱ", sign_card, **{"prob": 0.2})
|
||||
await register_goods(
|
||||
use.registered_use("好感度双倍加持卡Ⅰ", sign_card_1)
|
||||
await registered_goods("好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)")
|
||||
use.registered_use("好感度双倍加持卡Ⅱ", sign_card_2)
|
||||
await registered_goods(
|
||||
"好感度双倍加持卡Ⅲ", 250, "下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)"
|
||||
)
|
||||
use.register_use("好感度双倍加持卡Ⅲ", sign_card, **{"prob": 0.3})
|
||||
use.registered_use("好感度双倍加持卡Ⅲ", sign_card_3)
|
||||
|
||||
|
||||
# 创建商店界面
|
||||
@@ -124,7 +136,7 @@ async def create_shop_help() -> str:
|
||||
return shop.pic2bs4()
|
||||
|
||||
|
||||
async def register_goods(
|
||||
async def registered_goods(
|
||||
name: str,
|
||||
price: int,
|
||||
des: str,
|
||||
@@ -217,12 +229,11 @@ async def update_goods(**kwargs) -> "str, str, int":
|
||||
tmp += f'折扣:{discount} --> {kwargs["discount"]}\n'
|
||||
discount = kwargs["discount"]
|
||||
if kwargs.get("limit_time"):
|
||||
kwargs["limit_time"] = float(kwargs["limit_time"])
|
||||
new_time = time.strftime(
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
time.localtime(time.time() + kwargs["limit_time"] * 60 * 60),
|
||||
time.localtime(time.time() + int(kwargs["limit_time"] * 60 * 60)),
|
||||
)
|
||||
tmp += f"限时至: {new_time}\n"
|
||||
tmp += f"折扣至: {new_time}\n"
|
||||
limit_time = kwargs["limit_time"]
|
||||
return (
|
||||
await GoodsInfo.update_goods(
|
||||
@@ -250,6 +261,7 @@ def parse_goods_info(msg: str) -> Union[dict, str]:
|
||||
sp = x.split(":", maxsplit=1)
|
||||
if str(sp[1]).strip():
|
||||
sp[1] = sp[1].strip()
|
||||
print(sp)
|
||||
if sp[0] == "name":
|
||||
data["name"] = sp[1]
|
||||
elif sp[0] == "price":
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from nonebot import on_command
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
from utils.utils import is_number
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from utils.utils import is_number, get_message_text
|
||||
from models.bag_user import BagUser
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from services.db_context import db
|
||||
from nonebot.plugin import export
|
||||
from .data_source import effect, register_use, func_manager
|
||||
from .data_source import effect, registered_use
|
||||
|
||||
|
||||
__zx_plugin_name__ = "商店 - 使用道具"
|
||||
@@ -15,7 +15,7 @@ __plugin_usage__ = """
|
||||
usage:
|
||||
普通的使用道具
|
||||
指令:
|
||||
使用道具 [序号或道具名称] ?[数量]=1
|
||||
使用道具 [序号或道具名称]
|
||||
* 序号以 ”我的道具“ 为准 *
|
||||
""".strip()
|
||||
__plugin_des__ = "商店 - 使用道具"
|
||||
@@ -32,50 +32,45 @@ __plugin_settings__ = {
|
||||
|
||||
# 导出方法供其他插件使用
|
||||
export = export()
|
||||
export.register_use = register_use
|
||||
export.registered_use = registered_use
|
||||
|
||||
use_props = on_command("使用道具", priority=5, block=True, permission=GROUP)
|
||||
|
||||
|
||||
@use_props.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
num = 1
|
||||
msg_sp = msg.split()
|
||||
if len(msg_sp) > 1 and is_number(msg_sp[-1]) and int(msg_sp[-1]) > 0:
|
||||
num = int(msg.split()[-1])
|
||||
msg = " ".join(msg.split()[:-1])
|
||||
property_ = await BagUser.get_property(event.user_id, event.group_id)
|
||||
if property_:
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if msg in ["", "帮助"]:
|
||||
await use_props.finish(__plugin_usage__)
|
||||
props = await BagUser.get_props(event.user_id, event.group_id)
|
||||
if props:
|
||||
async with db.transaction():
|
||||
pname_list = []
|
||||
props = props[:-1].split(",")
|
||||
for p in props:
|
||||
if p != "":
|
||||
if p not in pname_list:
|
||||
pname_list.append(p)
|
||||
if is_number(msg):
|
||||
if 0 < int(msg) <= len(property_):
|
||||
name = list(property_.keys())[int(msg) - 1]
|
||||
if 0 < int(msg) <= len(pname_list):
|
||||
name = pname_list[int(msg) - 1]
|
||||
else:
|
||||
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
|
||||
else:
|
||||
if msg not in property_.keys():
|
||||
if msg not in pname_list:
|
||||
await use_props.finish("道具名称错误!", at_sender=True)
|
||||
name = msg
|
||||
_user_prop_count = property_[name]
|
||||
if num > _user_prop_count:
|
||||
await use_props.finish(f"道具数量不足,无法使用{num}次!")
|
||||
if num > (n := func_manager.get_max_num_limit(name)):
|
||||
await use_props.finish(f"该道具单次只能使用 {n} 个!")
|
||||
if await BagUser.delete_property(
|
||||
event.user_id, event.group_id, name, num
|
||||
):
|
||||
if func_manager.check_send_success_message(name):
|
||||
await use_props.send(f"使用道具 {name} {num} 次成功!", at_sender=True)
|
||||
if msg := await effect(bot, event, name, num):
|
||||
await use_props.send(msg, at_sender=True)
|
||||
if await BagUser.del_props(
|
||||
event.user_id, event.group_id, name
|
||||
) and await effect(event.user_id, event.group_id, name):
|
||||
await use_props.send(f"使用道具 {name} 成功!", at_sender=True)
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次成功"
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 成功"
|
||||
)
|
||||
else:
|
||||
await use_props.send(f"使用道具 {name} {num} 次失败!", at_sender=True)
|
||||
await use_props.send(f"使用道具 {name} 失败!", at_sender=True)
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次失败"
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 失败"
|
||||
)
|
||||
else:
|
||||
await use_props.send("您的背包里没有任何的道具噢", at_sender=True)
|
||||
await use_props.send("您的背包里没有任何的道具噢~", at_sender=True)
|
||||
|
||||
@@ -1,121 +1,45 @@
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from typing import Optional, Union
|
||||
import asyncio
|
||||
from services.log import logger
|
||||
|
||||
_use_func_data = {}
|
||||
|
||||
|
||||
class GoodsUseFuncManager:
|
||||
def __init__(self):
|
||||
self._data = {}
|
||||
|
||||
def register_use(self, goods_name: str, **kwargs):
|
||||
"""
|
||||
注册商品使用方法
|
||||
:param goods_name: 商品名称
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
self._data[goods_name] = kwargs
|
||||
|
||||
def exists(self, goods_name: str) -> bool:
|
||||
"""
|
||||
判断商品使用方法是否被注册
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
return bool(self._data.get(goods_name))
|
||||
|
||||
def get_max_num_limit(self, goods_name: str) -> int:
|
||||
"""
|
||||
获取单次商品使用数量
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
if self.exists(goods_name):
|
||||
return self._data[goods_name]["kwargs"]["_max_num_limit"]
|
||||
return 1
|
||||
|
||||
async def use(self, **kwargs) -> Optional[Union[str, MessageSegment]]:
|
||||
"""
|
||||
使用道具
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
goods_name = kwargs.get("goods_name")
|
||||
if self.exists(goods_name):
|
||||
if asyncio.iscoroutinefunction(self._data[goods_name]["func"]):
|
||||
return await self._data[goods_name]["func"](
|
||||
**kwargs,
|
||||
)
|
||||
else:
|
||||
return self._data[goods_name]["func"](
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def check_send_success_message(self, goods_name: str) -> bool:
|
||||
"""
|
||||
检查是否发送使用成功信息
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
if self.exists(goods_name):
|
||||
return bool(self._data[goods_name]["kwargs"]["send_success_msg"])
|
||||
return False
|
||||
|
||||
def get_kwargs(self, goods_name: str) -> dict:
|
||||
"""
|
||||
获取商品使用方法的kwargs
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
if self.exists(goods_name):
|
||||
return self._data[goods_name]["kwargs"]
|
||||
return {}
|
||||
|
||||
|
||||
func_manager = GoodsUseFuncManager()
|
||||
|
||||
|
||||
async def effect(
|
||||
bot: Bot, event: GroupMessageEvent, goods_name: str, num: int
|
||||
) -> Optional[Union[str, MessageSegment]]:
|
||||
async def effect(user_id: int, group_id: int, goods_name: str) -> bool:
|
||||
"""
|
||||
商品生效
|
||||
:param bot: Bot
|
||||
:param event: GroupMessageEvent
|
||||
:param user_id: 用户id
|
||||
:param group_id: 群号
|
||||
:param goods_name: 商品名称
|
||||
:param num: 使用数量
|
||||
:return: 使用是否成功
|
||||
"""
|
||||
# 优先使用注册的商品插件
|
||||
try:
|
||||
if func_manager.exists(goods_name):
|
||||
_kwargs = func_manager.get_kwargs(goods_name)
|
||||
return await func_manager.use(
|
||||
**{
|
||||
if _use_func_data.get(goods_name):
|
||||
_kwargs = _use_func_data[goods_name]["kwargs"]
|
||||
_kwargs["goods_name"] = goods_name
|
||||
_kwargs["user_id"] = user_id
|
||||
_kwargs["group_id"] = group_id
|
||||
if asyncio.iscoroutinefunction(_use_func_data[goods_name]["func"]):
|
||||
await _use_func_data[goods_name]["func"](
|
||||
**_kwargs,
|
||||
"_bot": bot,
|
||||
"event": event,
|
||||
"group_id": event.group_id,
|
||||
"user_id": event.user_id,
|
||||
"num": num,
|
||||
"goods_name": goods_name,
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
_use_func_data[goods_name]["func"](
|
||||
**_kwargs,
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}")
|
||||
return None
|
||||
return False
|
||||
|
||||
|
||||
def register_use(goods_name: str, func, **kwargs):
|
||||
def registered_use(goods_name: str, func, **kwargs):
|
||||
"""
|
||||
注册商品使用方法
|
||||
:param goods_name: 商品名称
|
||||
:param func: 使用函数
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
if func_manager.exists(goods_name):
|
||||
if goods_name in _use_func_data.keys():
|
||||
raise ValueError("该商品使用函数已被注册!")
|
||||
# 发送使用成功信息
|
||||
if kwargs.get("send_success_msg") is None:
|
||||
kwargs["send_success_msg"] = True
|
||||
kwargs["_max_num_limit"] = (
|
||||
kwargs.get("_max_num_limit") if kwargs.get("_max_num_limit") else 1
|
||||
)
|
||||
func_manager.register_use(goods_name, **{"func": func, "kwargs": kwargs})
|
||||
logger.info(f"register_use 成功注册商品:{goods_name} 的使用函数")
|
||||
_use_func_data[goods_name] = {"func": func, "kwargs": kwargs}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message
|
||||
from nonebot.params import Command, CommandArg
|
||||
from typing import Tuple
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import is_number
|
||||
from utils.utils import get_message_text, is_number
|
||||
from utils.manager import requests_manager
|
||||
from utils.message_builder import image
|
||||
from models.group_info import GroupInfo
|
||||
@@ -58,30 +57,37 @@ cls_request = on_command("查看所有请求", permission=SUPERUSER, priority=1,
|
||||
|
||||
|
||||
@cls_group.handle()
|
||||
async def _(bot: Bot):
|
||||
gl = await bot.get_group_list()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
gl = await bot.get_group_list(self_id=int(bot.self_id))
|
||||
msg = ["{group_id} {group_name}".format_map(g) for g in gl]
|
||||
msg = "\n".join(msg)
|
||||
msg = f"bot:{bot.self_id}\n| 群号 | 群名 | 共{len(gl)}个群\n" + msg
|
||||
await cls_group.send(msg)
|
||||
await bot.send_private_msg(
|
||||
self_id=int(bot.self_id),
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=msg,
|
||||
)
|
||||
|
||||
|
||||
@cls_friend.handle()
|
||||
async def _(bot: Bot):
|
||||
gl = await bot.get_friend_list()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
gl = await bot.get_friend_list(self_id=int(bot.self_id))
|
||||
msg = ["{user_id} {nickname}".format_map(g) for g in gl]
|
||||
msg = "\n".join(msg)
|
||||
msg = f"| QQ号 | 昵称 | 共{len(gl)}个好友\n" + msg
|
||||
await cls_friend.send(msg)
|
||||
await bot.send_private_msg(
|
||||
self_id=int(bot.self_id),
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=msg,
|
||||
)
|
||||
|
||||
|
||||
@friend_handle.handle()
|
||||
async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
id_ = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
id_ = get_message_text(event.json())
|
||||
if is_number(id_):
|
||||
id_ = int(id_)
|
||||
if cmd[:2] == "同意":
|
||||
if state["_prefix"]["raw_command"][:2] == "同意":
|
||||
if await requests_manager.approve(bot, id_, "private"):
|
||||
await friend_handle.send("同意好友请求成功..")
|
||||
else:
|
||||
@@ -96,12 +102,11 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
|
||||
|
||||
|
||||
@group_handle.handle()
|
||||
async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
id_ = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
id_ = get_message_text(event.json())
|
||||
if is_number(id_):
|
||||
id_ = int(id_)
|
||||
if cmd[:2] == "同意":
|
||||
if state["_prefix"]["raw_command"][:2] == "同意":
|
||||
rid = await requests_manager.approve(bot, id_, "group")
|
||||
if rid:
|
||||
await friend_handle.send("同意群聊请求成功..")
|
||||
@@ -128,7 +133,7 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
|
||||
|
||||
|
||||
@cls_request.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
_str = ""
|
||||
for type_ in ["private", "group"]:
|
||||
msg = await requests_manager.show(type_)
|
||||
@@ -142,6 +147,6 @@ async def _():
|
||||
|
||||
|
||||
@clear_request.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
requests_manager.clear()
|
||||
await cls_request.send("已清空所有好友/群聊请求..")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from configs.path_config import TEMP_PATH
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import scheduler
|
||||
@@ -33,7 +35,7 @@ resources_manager.add_temp_dir(TEMP_PATH)
|
||||
|
||||
|
||||
@clear_data.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await clear_data.send("开始清理临时数据....")
|
||||
size = await asyncio.get_event_loop().run_in_executor(None, _clear_data)
|
||||
await clear_data.send("共清理了 {:.2f}MB 的数据...".format(size / 1024 / 1024))
|
||||
@@ -45,14 +47,13 @@ def _clear_data() -> float:
|
||||
if dir_.exists():
|
||||
for file in os.listdir(dir_):
|
||||
file = dir_ / file
|
||||
if file.is_file():
|
||||
try:
|
||||
if time.time() - os.path.getatime(file) > 300:
|
||||
file_size = os.path.getsize(file)
|
||||
file.unlink()
|
||||
size += file_size
|
||||
except Exception as e:
|
||||
logger.error(f"清理临时数据错误...{type(e)}:{e}")
|
||||
try:
|
||||
if time.time() - os.path.getatime(file) > 300:
|
||||
file_size = os.path.getsize(file)
|
||||
file.unlink()
|
||||
size += file_size
|
||||
except Exception as e:
|
||||
logger.error(f"清理临时数据错误...{type(e)}:{e}")
|
||||
return float(size)
|
||||
|
||||
|
||||
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
# async def open_remind(group: int, name: str) -> str:
|
||||
# _name = ""
|
||||
# if name == "zwa":
|
||||
# _name = "早晚安"
|
||||
# if name == "dz":
|
||||
# _name = "地震播报"
|
||||
# if name == "hy":
|
||||
# _name = "群欢迎"
|
||||
# if name == "kxcz":
|
||||
# _name = "开箱重置提醒"
|
||||
# if name == "gb":
|
||||
# _name = "广播"
|
||||
# if await GroupRemind.get_status(group, name):
|
||||
# return f"该群已经开启过 {_name} 通知,请勿重复开启!"
|
||||
# if await GroupRemind.set_status(group, name, True):
|
||||
# return f"成功开启 {_name} 通知!0v0"
|
||||
# else:
|
||||
# return f"开启 {_name} 通知失败了..."
|
||||
#
|
||||
#
|
||||
# async def close_remind(group: int, name: str) -> str:
|
||||
# _name = ""
|
||||
# if name == "zwa":
|
||||
# _name = "早晚安"
|
||||
# if name == "dz":
|
||||
# _name = "地震播报"
|
||||
# if name == "hy":
|
||||
# _name = "群欢迎"
|
||||
# if name == "kxcz":
|
||||
# _name = "开箱重置提醒"
|
||||
# if name == "gb":
|
||||
# _name = "广播"
|
||||
# if not await GroupRemind.get_status(group, name):
|
||||
# return f"该群已经取消过 {_name} 通知,请勿重复取消!"
|
||||
# if await GroupRemind.set_status(group, name, False):
|
||||
# return f"成功关闭 {_name} 通知!0v0"
|
||||
# else:
|
||||
# return f"关闭 {_name} 通知失败了..."
|
||||
|
||||
|
||||
# cmd_list = ['总开关', '签到', '发送图片', '色图', '黑白草图', 'coser', '鸡汤/语录', '骂我', '开箱', '鲁迅说', '假消息', '商店系统',
|
||||
# '操作图片', '查询皮肤', '天气', '疫情', '识番', '搜番', '点歌', 'pixiv', 'rss', '方舟一井', '查干员', '骰子娘', '原神一井']
|
||||
#
|
||||
#
|
||||
# def check_group_switch_json(group_id):
|
||||
# if not os.path.exists(DATA_PATH + f'rule/group_switch/'):
|
||||
# os.mkdir(DATA_PATH + f'rule/group_switch/')
|
||||
# if not os.path.exists(DATA_PATH + f'rule/group_switch/{group_id}.json'):
|
||||
# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as f:
|
||||
# data = {}
|
||||
# for cmd in cmd_list:
|
||||
# data[cmd] = True
|
||||
# f.write(json.dumps(data, ensure_ascii=False))
|
||||
# else:
|
||||
# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'r', encoding='utf8') as f:
|
||||
# try:
|
||||
# data = json.load(f)
|
||||
# except ValueError:
|
||||
# data = {}
|
||||
# if len(data.keys()) - 1 != len(cmd_list):
|
||||
# for cmd in cmd_list:
|
||||
# if cmd not in data.keys():
|
||||
# data[cmd] = True
|
||||
# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as wf:
|
||||
# wf.write(json.dumps(data, ensure_ascii=False))
|
||||
# reload(data)
|
||||
# for file in os.listdir(DATA_PATH + 'group_help'):
|
||||
# os.remove(DATA_PATH + f'group_help/{file}')
|
||||
|
||||
|
||||
def reload(data):
|
||||
static_group_dict = data
|
||||
@@ -1,9 +1,10 @@
|
||||
from nonebot.adapters.onebot.v11 import Message
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from nonebot.rule import to_me
|
||||
from services.db_context import db
|
||||
from nonebot.params import CommandArg
|
||||
from utils.utils import get_message_text
|
||||
from services.log import logger
|
||||
|
||||
__zx_plugin_name__ = "执行sql [Superuser]"
|
||||
@@ -25,8 +26,8 @@ exec_ = on_command("exec", rule=to_me(), permission=SUPERUSER, priority=1, block
|
||||
|
||||
|
||||
@exec_.handle()
|
||||
async def _(arg: Message = CommandArg()):
|
||||
sql = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
sql = get_message_text(event.json())
|
||||
async with db.transaction():
|
||||
try:
|
||||
query = db.text(sql)
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GROUP, GroupMessageEvent, Message
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GROUP, GroupMessageEvent
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import is_number
|
||||
from utils.utils import get_message_text, is_number
|
||||
from utils.manager import group_manager, plugins2settings_manager
|
||||
from models.group_info import GroupInfo
|
||||
from services.log import logger
|
||||
from configs.config import NICKNAME
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.params import Command, CommandArg
|
||||
from typing import Tuple
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
|
||||
|
||||
__zx_plugin_name__ = "管理群操作 [Superuser]"
|
||||
@@ -67,8 +65,8 @@ group_auth = on_command(
|
||||
|
||||
|
||||
@del_group.handle()
|
||||
async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
group_id = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
group_id = get_message_text(event.json())
|
||||
if group_id:
|
||||
if is_number(group_id):
|
||||
try:
|
||||
@@ -86,8 +84,8 @@ async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@add_group_level.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
group_id = 0
|
||||
level = 0
|
||||
if not msg:
|
||||
@@ -111,7 +109,7 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@my_group_level.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
level = group_manager.get_group_level(event.group_id)
|
||||
tmp = ""
|
||||
data = plugins2settings_manager.get_data()
|
||||
@@ -127,18 +125,17 @@ async def _(event: GroupMessageEvent):
|
||||
|
||||
|
||||
@what_up_group_level.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await what_up_group_level.finish(
|
||||
f"[此功能用于防止内鬼,如果引起不便那真是抱歉了]\n" f"目前提高群权限的方法:\n" f"\t1.管理员修改权限"
|
||||
)
|
||||
|
||||
|
||||
@manager_group_whitelist.handle()
|
||||
async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json()).split()
|
||||
all_group = [
|
||||
g["group_id"] for g in await bot.get_group_list()
|
||||
g["group_id"] for g in await bot.get_group_list(self_id=int(bot.self_id))
|
||||
]
|
||||
group_list = []
|
||||
for group in msg:
|
||||
@@ -146,20 +143,20 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
|
||||
group_list.append(int(group))
|
||||
if group_list:
|
||||
for group in group_list:
|
||||
if cmd in ["添加群白名单"]:
|
||||
if state["_prefix"]["raw_command"] in ["添加群白名单"]:
|
||||
group_manager.add_group_white_list(group)
|
||||
else:
|
||||
group_manager.delete_group_white_list(group)
|
||||
group_list = [str(x) for x in group_list]
|
||||
await manager_group_whitelist.send(
|
||||
"已成功将 " + "\n".join(group_list) + " " + cmd
|
||||
"已成功将 " + "\n".join(group_list) + " " + state["_prefix"]["raw_command"]
|
||||
)
|
||||
else:
|
||||
await manager_group_whitelist.send(f"添加失败,请检查{NICKNAME}是否已加入这些群聊或重复添加/删除群白单名")
|
||||
|
||||
|
||||
@show_group_whitelist.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
x = group_manager.get_group_white_list()
|
||||
x = [str(g) for g in x]
|
||||
if x:
|
||||
@@ -169,14 +166,13 @@ async def _():
|
||||
|
||||
|
||||
@group_auth.handle()
|
||||
async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
msg = arg.extract_plain_text().strip().split()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json()).split()
|
||||
for group_id in msg:
|
||||
if not is_number(group_id):
|
||||
await group_auth.send(f"{group_id}非纯数字,已跳过该项..")
|
||||
group_id = int(group_id)
|
||||
if cmd[:2] == "添加":
|
||||
if state["_prefix"]["raw_command"][:2] == "添加":
|
||||
if await GroupInfo.get_group_info(group_id):
|
||||
await GroupInfo.set_group_flag(group_id, 1)
|
||||
else:
|
||||
@@ -200,5 +196,5 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
|
||||
if await GroupInfo.get_group_info(group_id):
|
||||
await GroupInfo.set_group_flag(group_id, 0)
|
||||
await group_auth.send(
|
||||
f'已为 {group_id} {cmd[:2]}群认证..'
|
||||
f'已为 {group_id} {state["_prefix"]["raw_command"][:2]}群认证..'
|
||||
)
|
||||
|
||||
@@ -7,9 +7,8 @@ from utils.manager import (
|
||||
plugins2block_manager,
|
||||
group_manager,
|
||||
)
|
||||
from configs.config import Config
|
||||
from services.log import logger
|
||||
from utils.utils import scheduler
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
|
||||
|
||||
__zx_plugin_name__ = "重载插件配置 [Superuser]"
|
||||
@@ -29,18 +28,6 @@ __plugin_cmd__ = [
|
||||
]
|
||||
__plugin_version__ = 0.1
|
||||
__plugin_author__ = "HibiKier"
|
||||
__plugin_configs__ = {
|
||||
"AUTO_RELOAD": {
|
||||
"value": False,
|
||||
"help": "自动重载配置文件",
|
||||
"default_value": False
|
||||
},
|
||||
"AUTO_RELOAD_TIME": {
|
||||
"value": 180,
|
||||
"help": "控制自动重载配置文件时长",
|
||||
"default_value": 180
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reload_plugins_manager = on_command(
|
||||
@@ -49,24 +36,9 @@ reload_plugins_manager = on_command(
|
||||
|
||||
|
||||
@reload_plugins_manager.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
plugins2settings_manager.reload()
|
||||
plugins2cd_manager.reload()
|
||||
plugins2block_manager.reload()
|
||||
group_manager.reload()
|
||||
Config.reload()
|
||||
await reload_plugins_manager.send("重载完成...")
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
'interval',
|
||||
seconds=Config.get_config("reload_setting", "AUTO_RELOAD_TIME", 180),
|
||||
)
|
||||
async def _():
|
||||
if Config.get_config("reload_setting", "AUTO_RELOAD"):
|
||||
plugins2settings_manager.reload()
|
||||
plugins2cd_manager.reload()
|
||||
plugins2block_manager.reload()
|
||||
group_manager.reload()
|
||||
Config.reload()
|
||||
logger.debug("已自动重载所有配置文件...")
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from models.level_user import LevelUser
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
|
||||
from utils.utils import get_message_at, is_number
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, Message
|
||||
from utils.utils import get_message_at, get_message_text, is_number
|
||||
from services.log import logger
|
||||
from utils.message_builder import at
|
||||
from nonebot.params import Command, CommandArg
|
||||
from typing import Tuple
|
||||
|
||||
__zx_plugin_name__ = "用户权限管理 [Superuser]"
|
||||
__plugin_usage__ = """
|
||||
@@ -37,12 +36,11 @@ super_cmd = on_command(
|
||||
|
||||
|
||||
@super_cmd.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
group_id = -1
|
||||
level = 0
|
||||
try:
|
||||
args = arg.extract_plain_text().strip().split()
|
||||
args = get_message_text(event.json()).split()
|
||||
qq = get_message_at(event.json())
|
||||
flag = -1
|
||||
if not qq:
|
||||
@@ -67,7 +65,7 @@ async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command()
|
||||
qq = qq[0]
|
||||
group_id = event.group_id
|
||||
flag = 2
|
||||
if cmd[:2] == "添加":
|
||||
if state["_prefix"]["raw_command"][:2] == "添加":
|
||||
if await LevelUser.set_level(qq, group_id, level, 1):
|
||||
result = "添加管理成功, 权限: " + str(level)
|
||||
else:
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import is_number
|
||||
from utils.utils import get_message_text, is_number
|
||||
from services.log import logger
|
||||
from utils.manager import group_manager
|
||||
from nonebot.params import Command, CommandArg
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
__zx_plugin_name__ = "超级用户被动开关 [Superuser]"
|
||||
@@ -35,9 +34,8 @@ oc_gb = on_command(
|
||||
|
||||
|
||||
@oc_gb.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
group = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
group = get_message_text(event.json())
|
||||
if group:
|
||||
if is_number(group):
|
||||
group = int(group)
|
||||
@@ -46,7 +44,7 @@ async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg
|
||||
break
|
||||
else:
|
||||
await oc_gb.finish("没有加入这个群...", at_sender=True)
|
||||
if cmd == "开启广播通知":
|
||||
if state["_prefix"]["raw_command"] == "开启广播通知":
|
||||
logger.info(f"USER {event.user_id} 开启了 GROUP {group} 的广播")
|
||||
await oc_gb.finish(await group_manager.open_group_task(group, "broadcast",), at_sender=True)
|
||||
else:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import get_bot
|
||||
from services.log import logger
|
||||
@@ -32,7 +34,7 @@ update_friend_info = on_command(
|
||||
|
||||
|
||||
@update_group_info.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
bot = get_bot()
|
||||
gl = await bot.get_group_list()
|
||||
gl = [g["group_id"] for g in gl]
|
||||
@@ -55,7 +57,7 @@ async def _():
|
||||
|
||||
|
||||
@update_friend_info.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
num = 0
|
||||
rst = ""
|
||||
fl = await get_bot().get_friend_list()
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.rule import to_me
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from .data_source import create_help_image
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
__zx_plugin_name__ = '超级用户帮助 [Superuser]'
|
||||
|
||||
|
||||
superuser_help_image = IMAGE_PATH / 'superuser_help.png'
|
||||
superuser_help_image = Path(IMAGE_PATH) / 'superuser_help.png'
|
||||
|
||||
if superuser_help_image.exists():
|
||||
superuser_help_image.unlink()
|
||||
@@ -20,7 +23,7 @@ super_help = on_command(
|
||||
|
||||
|
||||
@super_help.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
if not superuser_help_image.exists():
|
||||
await create_help_image()
|
||||
x = image(superuser_help_image)
|
||||
|
||||
@@ -2,7 +2,8 @@ from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.utils import get_matchers
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
from pathlib import Path
|
||||
from nonebot import Driver
|
||||
import asyncio
|
||||
import nonebot
|
||||
@@ -10,9 +11,9 @@ import nonebot
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
background = IMAGE_PATH / "background" / "0.png"
|
||||
background = Path(IMAGE_PATH) / "background" / "0.png"
|
||||
|
||||
superuser_help_image = IMAGE_PATH / "superuser_help.png"
|
||||
superuser_help_image = Path(IMAGE_PATH) / "superuser_help.png"
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
@@ -35,7 +36,7 @@ def _create_help_image():
|
||||
for matcher in _matchers:
|
||||
plugin_name = ""
|
||||
try:
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||
_plugin = nonebot.plugin.get_plugin(matcher.module)
|
||||
_module = _plugin.module
|
||||
try:
|
||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
||||
@@ -67,7 +68,7 @@ def _create_help_image():
|
||||
width = width if width > x else x
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"获取超级用户插件 {matcher.plugin_name}: {plugin_name} 设置失败... {type(e)}:{e}"
|
||||
f"获取超级用户插件 {matcher.module}: {plugin_name} 设置失败... {type(e)}:{e}"
|
||||
)
|
||||
height = len(help_str.split("\n")) * 33
|
||||
width += 500
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.cqhttp import Bot, Event
|
||||
from nonebot.typing import T_State
|
||||
from utils.message_builder import image
|
||||
|
||||
|
||||
@@ -25,7 +27,7 @@ update_info = on_command("更新信息", aliases={"更新日志"}, priority=5, b
|
||||
|
||||
|
||||
@update_info.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
img = image("update_info.png")
|
||||
if img:
|
||||
await update_info.finish(image("update_info.png"))
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import nonebot
|
||||
from nonebot.adapters.onebot.v11 import Adapter
|
||||
from nonebot.adapters.cqhttp import Bot as CQHTTPBot
|
||||
from services.db_context import init, disconnect
|
||||
|
||||
|
||||
nonebot.init()
|
||||
driver = nonebot.get_driver()
|
||||
driver.register_adapter(Adapter)
|
||||
driver.register_adapter("cqhttp", CQHTTPBot)
|
||||
config = driver.config
|
||||
driver.on_startup(init)
|
||||
driver.on_shutdown(disconnect)
|
||||
|
||||
+21
-25
@@ -1,45 +1,41 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
# 图片路径
|
||||
IMAGE_PATH = Path() / "resources" / "image"
|
||||
# 语音路径
|
||||
RECORD_PATH = Path() / "resources" / "record"
|
||||
IMAGE_PATH = Path("resources/img/")
|
||||
# 音频路径
|
||||
VOICE_PATH = Path("resources/voice/")
|
||||
# 文本路径
|
||||
TEXT_PATH = Path() / "resources" / "text"
|
||||
TEXT_PATH = Path("resources/txt/")
|
||||
# 日志路径
|
||||
LOG_PATH = Path() / "log"
|
||||
LOG_PATH = Path("log/")
|
||||
# 字体路径
|
||||
FONT_PATH = Path() / "resources" / "font"
|
||||
FONT_PATH = Path("resources/ttf/")
|
||||
# 数据路径
|
||||
DATA_PATH = Path() / "data"
|
||||
# 临时数据路径
|
||||
TEMP_PATH = Path() / "resources" / "temp"
|
||||
DATA_PATH = Path("data/")
|
||||
# 临时图片路径
|
||||
TEMP_PATH = Path("resources/img/temp/")
|
||||
|
||||
|
||||
def load_path():
|
||||
old_img_dir = Path() / "resources" / "img"
|
||||
if not IMAGE_PATH.exists() and old_img_dir.exists():
|
||||
os.rename(old_img_dir, IMAGE_PATH)
|
||||
old_voice_dir = Path() / "resources" / "voice"
|
||||
if not RECORD_PATH.exists() and old_voice_dir.exists():
|
||||
os.rename(old_voice_dir, RECORD_PATH)
|
||||
old_ttf_dir = Path() / "resources" / "ttf"
|
||||
if not FONT_PATH.exists() and old_ttf_dir.exists():
|
||||
os.rename(old_ttf_dir, FONT_PATH)
|
||||
old_txt_dir = Path() / "resources" / "txt"
|
||||
if not TEXT_PATH.exists() and old_txt_dir.exists():
|
||||
os.rename(old_txt_dir, TEXT_PATH)
|
||||
def init_path():
|
||||
global IMAGE_PATH, VOICE_PATH, TEXT_PATH, LOG_PATH, FONT_PATH, DATA_PATH, TEMP_PATH
|
||||
IMAGE_PATH.mkdir(parents=True, exist_ok=True)
|
||||
RECORD_PATH.mkdir(parents=True, exist_ok=True)
|
||||
VOICE_PATH.mkdir(parents=True, exist_ok=True)
|
||||
TEXT_PATH.mkdir(parents=True, exist_ok=True)
|
||||
LOG_PATH.mkdir(parents=True, exist_ok=True)
|
||||
FONT_PATH.mkdir(parents=True, exist_ok=True)
|
||||
DATA_PATH.mkdir(parents=True, exist_ok=True)
|
||||
TEMP_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
IMAGE_PATH = str(IMAGE_PATH.absolute()) + '/'
|
||||
VOICE_PATH = str(VOICE_PATH.absolute()) + '/'
|
||||
TEXT_PATH = str(TEXT_PATH.absolute()) + '/'
|
||||
LOG_PATH = str(LOG_PATH.absolute()) + '/'
|
||||
FONT_PATH = str(FONT_PATH.absolute()) + '/'
|
||||
DATA_PATH = str(DATA_PATH.absolute()) + '/'
|
||||
TEMP_PATH = str(TEMP_PATH.absolute()) + '/'
|
||||
|
||||
load_path()
|
||||
|
||||
init_path()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -153,20 +153,6 @@ class ConfigsManager:
|
||||
self._data, f, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True
|
||||
)
|
||||
|
||||
def reload(self):
|
||||
"""
|
||||
重新加载配置文件
|
||||
"""
|
||||
_yaml = YAML()
|
||||
temp_file = Path() / "configs" / "config.yaml"
|
||||
if temp_file.exists():
|
||||
with open(temp_file, "r", encoding="utf8") as f:
|
||||
temp = _yaml.load(f)
|
||||
for key in temp.keys():
|
||||
for k in temp[key].keys():
|
||||
self._data[key][k]["value"] = temp[key][k]
|
||||
self.save()
|
||||
|
||||
def get_admin_level_data(self):
|
||||
"""
|
||||
获取管理插件等级
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 772 KiB |
+74
-59
@@ -1,5 +1,4 @@
|
||||
from services.db_context import db
|
||||
from typing import Dict
|
||||
from typing import Optional, List
|
||||
from services.log import logger
|
||||
|
||||
@@ -8,32 +7,33 @@ class BagUser(db.Model):
|
||||
__tablename__ = "bag_users"
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
gold = db.Column(db.Integer(), default=100)
|
||||
props = db.Column(db.TEXT(), nullable=False, default="") # 旧道具字段(废弃)
|
||||
props = db.Column(db.TEXT(), nullable=False, default="")
|
||||
spend_total_gold = db.Column(db.Integer(), default=0)
|
||||
get_total_gold = db.Column(db.Integer(), default=0)
|
||||
get_today_gold = db.Column(db.Integer(), default=0)
|
||||
spend_today_gold = db.Column(db.Integer(), default=0)
|
||||
property = db.Column(db.JSON(), nullable=False, default={}) # 新道具字段
|
||||
|
||||
_idx1 = db.Index("bag_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
_idx1 = db.Index("bag_group_users_idx1", "user_qq", "belonging_group", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def get_user_total_gold(cls, user_qq: int, group_id: int) -> str:
|
||||
async def get_my_total_gold(cls, user_qq: int, belonging_group: int) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取金币概况
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
if not user:
|
||||
user = await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
)
|
||||
return (
|
||||
f"当前金币:{user.gold}\n今日获取金币:{user.get_today_gold}\n今日花费金币:{user.spend_today_gold}"
|
||||
@@ -42,56 +42,62 @@ class BagUser(db.Model):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_gold(cls, user_qq: int, group_id: int) -> int:
|
||||
async def get_gold(cls, user_qq: int, belonging_group: int) -> int:
|
||||
"""
|
||||
说明:
|
||||
获取当前金币
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.gold
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
)
|
||||
return 100
|
||||
|
||||
@classmethod
|
||||
async def get_property(cls, user_qq: int, group_id: int) -> Dict[str, int]:
|
||||
async def get_props(cls, user_qq: int, belonging_group: int) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取当前道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.property
|
||||
return user.props
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
)
|
||||
return {}
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def add_gold(cls, user_qq: int, group_id: int, num: int):
|
||||
async def add_gold(cls, user_qq: int, belonging_group: int, num: int):
|
||||
"""
|
||||
说明:
|
||||
增加金币
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
:param num: 金币数量
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
@@ -103,23 +109,25 @@ class BagUser(db.Model):
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
gold=100 + num,
|
||||
get_total_gold=num,
|
||||
get_today_gold=num,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def spend_gold(cls, user_qq: int, group_id: int, num: int):
|
||||
async def spend_gold(cls, user_qq: int, belonging_group: int, num: int):
|
||||
"""
|
||||
说明:
|
||||
花费金币
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
:param num: 金币数量
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
@@ -131,84 +139,91 @@ class BagUser(db.Model):
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
gold=100 - num,
|
||||
spend_total_gold=num,
|
||||
spend_today_gold=num,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def add_property(cls, user_qq: int, group_id: int, name: str):
|
||||
async def add_props(cls, user_qq: int, belonging_group: int, name: str):
|
||||
"""
|
||||
说明:
|
||||
增加道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
:param name: 道具名称
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
p = user.property
|
||||
if p.get(name) is None:
|
||||
p[name] = 1
|
||||
else:
|
||||
p[name] += 1
|
||||
await user.update(property=p).apply()
|
||||
await user.update(props=user.props + f"{name},").apply()
|
||||
else:
|
||||
await cls.create(user_qq=user_qq, group_id=group_id, property={name: 1})
|
||||
await cls.create(
|
||||
user_qq=user_qq, belonging_group=belonging_group, props=f"{name},"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def delete_property(
|
||||
cls, user_qq: int, group_id: int, name: str, num: int = 1
|
||||
) -> bool:
|
||||
async def del_props(cls, user_qq: int, belonging_group: int, name: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
使用/删除 道具
|
||||
使用道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param belonging_group: 所在群号
|
||||
:param name: 道具名称
|
||||
:param num: 使用个数
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
property_ = user.property
|
||||
if name in property_:
|
||||
if property_.get(name) == num:
|
||||
del property_[name]
|
||||
else:
|
||||
property_[name] -= num
|
||||
await user.update(property=property_).apply()
|
||||
rst = ""
|
||||
props = user.props
|
||||
if props.find(name) != -1:
|
||||
props = props.split(",")
|
||||
try:
|
||||
index = props.index(name)
|
||||
except ValueError:
|
||||
return False
|
||||
props = props[:index] + props[index + 1 :]
|
||||
for p in props:
|
||||
if p != "":
|
||||
rst += p + ","
|
||||
await user.update(props=rst).apply()
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def buy_property(
|
||||
cls, user_qq: int, group_id: int, goods: "GoodsInfo", goods_num: int
|
||||
async def buy_props(
|
||||
cls, user_qq: int, belonging_group: int, goods: "GoodsInfo", goods_num: int
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
购买道具
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param group_id: 所在群聊
|
||||
:param belonging_group: 所在群聊
|
||||
:param goods: 商品
|
||||
:param goods_num: 商品数量
|
||||
"""
|
||||
try:
|
||||
# 折扣后金币
|
||||
spend_gold = goods.goods_discount * goods.goods_price * goods_num
|
||||
await BagUser.spend_gold(user_qq, group_id, spend_gold)
|
||||
await BagUser.spend_gold(user_qq, belonging_group, spend_gold)
|
||||
for _ in range(goods_num):
|
||||
await BagUser.add_property(user_qq, group_id, goods.goods_name)
|
||||
await BagUser.add_props(user_qq, belonging_group, goods.goods_name)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"buy_property 发生错误 {type(e)}:{e}")
|
||||
logger.error(f"buy_props 发生错误 {type(e)}:{e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@@ -222,5 +237,5 @@ class BagUser(db.Model):
|
||||
if not group_id:
|
||||
query = await cls.query.gino.all()
|
||||
else:
|
||||
query = await cls.query.where((cls.group_id == group_id)).gino.all()
|
||||
query = await cls.query.where((cls.belonging_group == group_id)).gino.all()
|
||||
return query
|
||||
|
||||
+30
-32
@@ -10,18 +10,18 @@ class GroupInfoUser(db.Model):
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
user_name = db.Column(db.Unicode(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
user_join_time = db.Column(db.DateTime(), nullable=False)
|
||||
nickname = db.Column(db.Unicode())
|
||||
uid = db.Column(db.BigInteger())
|
||||
|
||||
_idx1 = db.Index("info_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
_idx1 = db.Index("info_group_users_idx1", "user_qq", "belonging_group", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def add_member_info(
|
||||
cls,
|
||||
user_qq: int,
|
||||
group_id: int,
|
||||
belonging_group: int,
|
||||
user_name: str,
|
||||
user_join_time: datetime,
|
||||
uid: Optional[int] = None,
|
||||
@@ -31,20 +31,20 @@ class GroupInfoUser(db.Model):
|
||||
添加群内用户信息
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
:param user_name: 用户名称
|
||||
:param user_join_time: 入群时间
|
||||
:param uid: 用户唯一 id(自动生成)
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
try:
|
||||
if not await query.gino.first():
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
user_name=user_name,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
user_join_time=user_join_time,
|
||||
uid=uid
|
||||
)
|
||||
@@ -54,31 +54,31 @@ class GroupInfoUser(db.Model):
|
||||
|
||||
@classmethod
|
||||
async def get_member_info(
|
||||
cls, user_qq: int, group_id: int
|
||||
cls, user_qq: int, belonging_group: int
|
||||
) -> "GroupInfoUser":
|
||||
"""
|
||||
说明:
|
||||
查询群员信息
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
return await query.gino.first()
|
||||
|
||||
@classmethod
|
||||
async def delete_member_info(cls, user_qq: int, group_id: int) -> bool:
|
||||
async def delete_member_info(cls, user_qq: int, belonging_group: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
删除群员信息
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
@@ -87,40 +87,40 @@ class GroupInfoUser(db.Model):
|
||||
return True
|
||||
else:
|
||||
await cls.delete.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
).gino.status()
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_id_list(cls, group_id: int) -> List[int]:
|
||||
async def get_group_member_id_list(cls, belonging_group: int) -> List[int]:
|
||||
"""
|
||||
说明:
|
||||
获取该群所有用户qq
|
||||
参数:
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
"""
|
||||
member_list = []
|
||||
query = cls.query.where((cls.group_id == group_id))
|
||||
query = cls.query.where((cls.belonging_group == belonging_group))
|
||||
for user in await query.gino.all():
|
||||
member_list.append(user.user_qq)
|
||||
return member_list
|
||||
|
||||
@classmethod
|
||||
async def set_group_member_nickname(
|
||||
cls, user_qq: int, group_id: int, nickname: str
|
||||
cls, user_qq: int, belonging_group: int, nickname: str
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置群员在该群内的昵称
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
:param nickname: 昵称
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
user = await query.with_for_update().gino.first()
|
||||
if user:
|
||||
@@ -131,27 +131,25 @@ class GroupInfoUser(db.Model):
|
||||
@classmethod
|
||||
async def get_user_all_group(cls, user_qq: int) -> List[int]:
|
||||
"""
|
||||
说明:
|
||||
获取该用户所在的所有群聊
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
获取该用户所在的所有群聊
|
||||
:param user_qq: 用户qq
|
||||
"""
|
||||
query = await cls.query.where(cls.user_qq == user_qq).gino.all()
|
||||
if query:
|
||||
query = [x.group_id for x in query]
|
||||
query = [x.belonging_group for x in query]
|
||||
return query
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_nickname(cls, user_qq: int, group_id: int) -> str:
|
||||
async def get_group_member_nickname(cls, user_qq: int, belonging_group: int) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取用户在该群的昵称
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
@@ -165,12 +163,12 @@ class GroupInfoUser(db.Model):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_uid(cls, user_qq: int, group_id: int) -> Optional[str]:
|
||||
async def get_group_member_uid(cls, user_qq: int, belonging_group: int) -> Optional[str]:
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
_max_uid = cls.query.where((cls.user_qq == 114514) & (cls.group_id == 114514)).with_for_update()
|
||||
_max_uid = cls.query.where((cls.user_qq == 114514) & (cls.belonging_group == 114514)).with_for_update()
|
||||
_max_uid_user = await _max_uid.gino.first()
|
||||
_max_uid = _max_uid_user.uid
|
||||
if not user or not user.uid:
|
||||
@@ -180,9 +178,9 @@ class GroupInfoUser(db.Model):
|
||||
return x.uid
|
||||
else:
|
||||
if not user:
|
||||
await GroupInfoUser.add_member_info(user_qq, group_id, '', datetime.min)
|
||||
await GroupInfoUser.add_member_info(user_qq, belonging_group, '', datetime.min)
|
||||
user = await cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
).gino.first()
|
||||
await user.update(
|
||||
uid=_max_uid + 1,
|
||||
|
||||
+12
-11
@@ -8,7 +8,8 @@ class SignGroupUser(db.Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
|
||||
checkin_count = db.Column(db.Integer(), nullable=False)
|
||||
checkin_time_last = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||
impression = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False)
|
||||
@@ -19,29 +20,29 @@ class SignGroupUser(db.Model):
|
||||
db.Numeric(scale=3, asdecimal=False), nullable=False, default=0
|
||||
)
|
||||
|
||||
_idx1 = db.Index("sign_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
_idx1 = db.Index("sign_group_users_idx1", "user_qq", "belonging_group", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def ensure(
|
||||
cls, user_qq: int, group_id: int, for_update: bool = False
|
||||
cls, user_qq: int, belonging_group: int, for_update: bool = False
|
||||
) -> "SignGroupUser":
|
||||
"""
|
||||
说明:
|
||||
获取签到用户
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param group_id: 所在群聊
|
||||
:param belonging_group: 所在群聊
|
||||
:param for_update: 是否存在修改数据
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
if for_update:
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
return user or await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
belonging_group=belonging_group,
|
||||
checkin_count=0,
|
||||
checkin_time_last=datetime.min, # 从未签到过
|
||||
impression=0,
|
||||
@@ -78,22 +79,22 @@ class SignGroupUser(db.Model):
|
||||
).apply()
|
||||
|
||||
@classmethod
|
||||
async def get_all_impression(cls, group_id: int) -> "list, list, list":
|
||||
async def get_all_impression(cls, belonging_group: int) -> "list, list, list":
|
||||
"""
|
||||
说明:
|
||||
获取该群所有用户 id 及对应 好感度
|
||||
参数:
|
||||
:param group_id: 群号
|
||||
:param belonging_group: 群号
|
||||
"""
|
||||
impression_list = []
|
||||
user_qq_list = []
|
||||
user_group = []
|
||||
if group_id:
|
||||
query = cls.query.where(cls.group_id == group_id)
|
||||
if belonging_group:
|
||||
query = cls.query.where(cls.belonging_group == belonging_group)
|
||||
else:
|
||||
query = cls.query
|
||||
for user in await query.gino.all():
|
||||
impression_list.append(user.impression)
|
||||
user_qq_list.append(user.user_qq)
|
||||
user_group.append(user.group_id)
|
||||
user_group.append(user.belonging_group)
|
||||
return user_qq_list, impression_list, user_group
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
from nonebot import on_regex
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.rule import to_me
|
||||
from pathlib import Path
|
||||
|
||||
@@ -27,7 +29,7 @@ about = on_regex("^关于$", priority=5, block=True, rule=to_me())
|
||||
|
||||
|
||||
@about.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
ver_file = Path() / '__version__'
|
||||
version = None
|
||||
if ver_file.exists():
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import random
|
||||
from nonebot import on_keyword
|
||||
import os
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from nonebot import on_command
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from utils.utils import FreqLimiter
|
||||
from configs.config import NICKNAME
|
||||
import random
|
||||
from nonebot import on_keyword
|
||||
import os
|
||||
|
||||
|
||||
__zx_plugin_name__ = "基本设置 [Hidden]"
|
||||
@@ -24,12 +25,12 @@ config_play_game = on_keyword({"打游戏"}, permission=GROUP, priority=1, block
|
||||
|
||||
|
||||
@config_play_game.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
if not _flmt.check(event.group_id):
|
||||
return
|
||||
_flmt.start_cd(event.group_id)
|
||||
await config_play_game.finish(
|
||||
image(random.choice(os.listdir(IMAGE_PATH / "dayouxi")), "dayouxi")
|
||||
image(random.choice(os.listdir(IMAGE_PATH + "dayouxi/")), "dayouxi")
|
||||
)
|
||||
|
||||
|
||||
@@ -39,7 +40,7 @@ self_introduction = on_command(
|
||||
|
||||
|
||||
@self_introduction.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if NICKNAME.find('真寻') != -1:
|
||||
result = (
|
||||
"我叫绪山真寻\n"
|
||||
@@ -56,6 +57,6 @@ my_wife = on_keyword({"老婆"}, rule=to_me(), priority=5, block=True)
|
||||
|
||||
|
||||
@my_wife.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await my_wife.finish(image("laopo.jpg", "other"))
|
||||
|
||||
|
||||
+22
-17
@@ -1,15 +1,17 @@
|
||||
from nonebot import on_message
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
MessageEvent,
|
||||
)
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from models.friend_user import FriendUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.utils import get_message_img, get_message_text
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from .data_source import get_chat_result, hello, no_result
|
||||
from configs.config import NICKNAME, Config
|
||||
|
||||
@@ -19,35 +21,40 @@ usage:
|
||||
与{NICKNAME}普普通通的对话吧!
|
||||
"""
|
||||
__plugin_version__ = 0.1
|
||||
__plugin_author__ = "HibiKier"
|
||||
__plugin_author__ = 'HibiKier'
|
||||
__plugin_settings__ = {
|
||||
"level": 5,
|
||||
"cmd": ["Ai", "ai", "AI", "aI"],
|
||||
}
|
||||
__plugin_configs__ = {
|
||||
"TL_KEY": {"value": [], "help": "图灵Key"},
|
||||
"ALAPI_AI_CHECK": {"value": False, "help": "是否检测青云客骂娘回复", "default_value": False},
|
||||
"TEXT_FILTER": {
|
||||
"value": ["鸡", "口交"],
|
||||
"help": "文本过滤器,将敏感词更改为*",
|
||||
"default_value": [],
|
||||
"TL_KEY": {
|
||||
"value": [],
|
||||
"help": "图灵Key"
|
||||
},
|
||||
"ALAPI_AI_CHECK": {
|
||||
"value": False,
|
||||
"help": "是否检测青云客骂娘回复",
|
||||
"default_value": False
|
||||
}
|
||||
}
|
||||
Config.add_plugin_config(
|
||||
"alapi", "ALAPI_TOKEN", None, help_="在 https://admin.alapi.cn/user/login 登录后获取token"
|
||||
"alapi",
|
||||
"ALAPI_TOKEN",
|
||||
None,
|
||||
help_="在https://admin.alapi.cn/user/login登录后获取token"
|
||||
)
|
||||
|
||||
ai = on_message(rule=to_me(), priority=8)
|
||||
|
||||
|
||||
@ai.handle()
|
||||
async def _(bot: Bot, event: MessageEvent):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
img = get_message_img(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
if "CQ:xml" in str(event.get_message()):
|
||||
return
|
||||
# 打招呼
|
||||
if (not msg and not img) or msg in [
|
||||
if (not msg and not imgs) or msg in [
|
||||
"你好啊",
|
||||
"你好",
|
||||
"在吗",
|
||||
@@ -58,7 +65,7 @@ async def _(bot: Bot, event: MessageEvent):
|
||||
"在",
|
||||
]:
|
||||
await ai.finish(hello())
|
||||
img = img[0] if img else ""
|
||||
img = imgs[0] if imgs else ""
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
nickname = await GroupInfoUser.get_group_member_nickname(
|
||||
event.user_id, event.group_id
|
||||
@@ -67,7 +74,7 @@ async def _(bot: Bot, event: MessageEvent):
|
||||
nickname = await FriendUser.get_friend_nickname(event.user_id)
|
||||
if not nickname:
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
nickname = event.sender.card or event.sender.nickname
|
||||
nickname = event.sender.card if event.sender.card else event.sender.nickname
|
||||
else:
|
||||
nickname = event.sender.nickname
|
||||
result = await get_chat_result(msg, img, event.user_id, nickname)
|
||||
@@ -76,8 +83,6 @@ async def _(bot: Bot, event: MessageEvent):
|
||||
f"问题:{msg} ---- 回答:{result}"
|
||||
)
|
||||
if result:
|
||||
for t in Config.get_config("ai", "TEXT_FILTER"):
|
||||
result = result.replace(t, "*")
|
||||
await ai.finish(Message(result))
|
||||
else:
|
||||
await ai.finish(no_result())
|
||||
|
||||
@@ -20,7 +20,7 @@ check_url = "https://v2.alapi.cn/api/censor/text"
|
||||
|
||||
index = 0
|
||||
|
||||
anime_data = json.load(open(DATA_PATH / "anime.json", "r", encoding="utf8"))
|
||||
anime_data = json.load(open(DATA_PATH + "anime.json", "r", encoding="utf8"))
|
||||
|
||||
|
||||
async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str) -> str:
|
||||
@@ -139,7 +139,7 @@ async def xie_ai(text: str) -> str:
|
||||
content = content.replace("{br}", "\n")
|
||||
if "提示" in content:
|
||||
content = content[: content.find("提示")]
|
||||
if "淘宝" in content or "taobao.com" in content:
|
||||
if "淘宝" in content:
|
||||
return ""
|
||||
while True:
|
||||
r = re.search("{face:(.*)}", content)
|
||||
@@ -170,7 +170,7 @@ def hello() -> str:
|
||||
"呼呼,叫俺干嘛",
|
||||
)
|
||||
)
|
||||
img = random.choice(os.listdir(IMAGE_PATH / "zai"))
|
||||
img = random.choice(os.listdir(IMAGE_PATH + "zai/"))
|
||||
if img[-4:] == ".gif":
|
||||
result += image(img, "zai")
|
||||
else:
|
||||
@@ -193,7 +193,7 @@ def no_result() -> str:
|
||||
"我!不!知!道!",
|
||||
]
|
||||
)
|
||||
+ image(random.choice(os.listdir(IMAGE_PATH / "noresult")), "noresult")
|
||||
+ image(random.choice(os.listdir(IMAGE_PATH + "noresult/")), "noresult")
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from nonebot import on_regex
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from ._data_source import get_data
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from .data_source import get_data
|
||||
from services.log import logger
|
||||
|
||||
__zx_plugin_name__ = "网易云热评"
|
||||
@@ -22,8 +23,8 @@ __plugin_settings__ = {
|
||||
}
|
||||
|
||||
|
||||
comments_163 = on_regex(
|
||||
"^(网易云热评|网易云评论|到点了|12点了)$", priority=5, block=True
|
||||
comments_163 = on_command(
|
||||
"网易云热评", aliases={"网易云评论", "到点了", "12点了"}, priority=5, block=True
|
||||
)
|
||||
|
||||
|
||||
@@ -31,7 +32,7 @@ comments_163_url = "https://v2.alapi.cn/api/comment"
|
||||
|
||||
|
||||
@comments_163.handle()
|
||||
async def _(event: MessageEvent):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
data, code = await get_data(comments_163_url)
|
||||
if code != 200:
|
||||
await comments_163.finish(data, at_sender=True)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from utils.message_builder import image
|
||||
from nonebot.params import CommandArg
|
||||
from ._data_source import get_data
|
||||
from utils.utils import get_message_text
|
||||
from .data_source import get_data
|
||||
from services.log import logger
|
||||
|
||||
__zx_plugin_name__ = "b封面"
|
||||
@@ -31,8 +32,8 @@ cover_url = "https://v2.alapi.cn/api/bilibili/cover"
|
||||
|
||||
|
||||
@cover.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
params = {"c": msg}
|
||||
data, code = await get_data(cover_url, params)
|
||||
if code != 200:
|
||||
|
||||
Regular → Executable
+49
-49
@@ -1,49 +1,49 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from typing import Optional, Tuple, Union
|
||||
from configs.config import Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
|
||||
|
||||
async def get_data(url: str, params: Optional[dict] = None) -> Tuple[Union[dict, str], int]:
|
||||
"""
|
||||
获取ALAPI数据
|
||||
:param url: 请求链接
|
||||
:param params: 参数
|
||||
"""
|
||||
if not params:
|
||||
params = {}
|
||||
params["token"] = Config.get_config("alapi", "ALAPI_TOKEN")
|
||||
try:
|
||||
data = (await AsyncHttpx.get(url, params=params, timeout=5)).json()
|
||||
if data["code"] == 200:
|
||||
if not data["data"]:
|
||||
return "没有搜索到...", 997
|
||||
return data, 200
|
||||
else:
|
||||
return f'发生了错误...code:{data["code"]}', 999
|
||||
except TimeoutError:
|
||||
return "超时了....", 998
|
||||
|
||||
|
||||
def gen_wbtop_pic(data: dict) -> MessageSegment:
|
||||
"""
|
||||
生成微博热搜图片
|
||||
:param data: 微博热搜数据
|
||||
"""
|
||||
bk = BuildImage(700, 32 * 50 + 280, 700, 32, color="#797979")
|
||||
wbtop_bk = BuildImage(700, 280, background=f"{IMAGE_PATH}/other/webtop.png")
|
||||
bk.paste(wbtop_bk)
|
||||
text_bk = BuildImage(700, 32 * 50, 700, 32, color="#797979")
|
||||
for i, data in enumerate(data):
|
||||
title = f"{i+1}. {data['hot_word']}"
|
||||
hot = data["hot_word_num"]
|
||||
img = BuildImage(700, 30, font_size=20)
|
||||
w, h = img.getsize(title)
|
||||
img.text((10, int((30 - h) / 2)), title)
|
||||
img.text((580, int((30 - h) / 2)), hot)
|
||||
text_bk.paste(img)
|
||||
bk.paste(text_bk, (0, 280))
|
||||
return image(b64=bk.pic2bs4())
|
||||
from nonebot.adapters.cqhttp import MessageSegment
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from typing import Optional
|
||||
from configs.config import Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
|
||||
|
||||
async def get_data(url: str, params: Optional[dict] = None) -> "Union[dict, str], int":
|
||||
"""
|
||||
获取ALAPI数据
|
||||
:param url: 请求链接
|
||||
:param params: 参数
|
||||
"""
|
||||
if not params:
|
||||
params = {}
|
||||
params["token"] = Config.get_config("alapi", "ALAPI_TOKEN")
|
||||
try:
|
||||
data = (await AsyncHttpx.get(url, params=params, timeout=5)).json()
|
||||
if data["code"] == 200:
|
||||
if not data["data"]:
|
||||
return "没有搜索到...", 997
|
||||
return data, 200
|
||||
else:
|
||||
return f'发生了错误...code:{data["code"]}', 999
|
||||
except TimeoutError:
|
||||
return "超时了....", 998
|
||||
|
||||
|
||||
def gen_wbtop_pic(data: dict) -> MessageSegment:
|
||||
"""
|
||||
生成微博热搜图片
|
||||
:param data: 微博热搜数据
|
||||
"""
|
||||
bk = BuildImage(700, 32 * 50 + 280, 700, 32, color="#797979")
|
||||
wbtop_bk = BuildImage(700, 280, background=f"{IMAGE_PATH}/other/webtop.png")
|
||||
bk.paste(wbtop_bk)
|
||||
text_bk = BuildImage(700, 32 * 50, 700, 32, color="#797979")
|
||||
for i, data in enumerate(data):
|
||||
title = f"{i+1}. {data['hot_word']}"
|
||||
hot = data["hot_word_num"]
|
||||
img = BuildImage(700, 30, font_size=20)
|
||||
w, h = img.getsize(title)
|
||||
img.text((10, int((30 - h) / 2)), title)
|
||||
img.text((580, int((30 - h) / 2)), hot)
|
||||
text_bk.paste(img)
|
||||
bk.paste(text_bk, (0, 280))
|
||||
return image(b64=bk.pic2bs4())
|
||||
@@ -1,7 +1,10 @@
|
||||
from nonebot import on_regex
|
||||
from nonebot import on_command
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from ._data_source import get_data
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from configs.config import Config
|
||||
from .data_source import get_data
|
||||
|
||||
|
||||
__zx_plugin_name__ = "鸡汤"
|
||||
@@ -25,11 +28,11 @@ __plugin_settings__ = {
|
||||
url = "https://v2.alapi.cn/api/soul"
|
||||
|
||||
|
||||
jitang = on_regex("^毒?鸡汤$", priority=5, block=True)
|
||||
jitang = on_command("鸡汤", aliases={"毒鸡汤"}, priority=5, block=True)
|
||||
|
||||
|
||||
@jitang.handle()
|
||||
async def _(event: MessageEvent):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
try:
|
||||
data, code = await get_data(url)
|
||||
if code != 200:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from services.log import logger
|
||||
from ._data_source import get_data
|
||||
from .data_source import get_data
|
||||
|
||||
__zx_plugin_name__ = "古诗"
|
||||
__plugin_usage__ = """usage:
|
||||
@@ -26,7 +27,7 @@ poetry_url = "https://v2.alapi.cn/api/shici"
|
||||
|
||||
|
||||
@poetry.handle()
|
||||
async def _(event: MessageEvent):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
data, code = await get_data(poetry_url)
|
||||
if code != 200:
|
||||
await poetry.finish(data, at_sender=True)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from services.log import logger
|
||||
from ._data_source import get_data, gen_wbtop_pic
|
||||
from utils.utils import is_number
|
||||
from .data_source import get_data, gen_wbtop_pic
|
||||
from utils.utils import get_message_text, is_number
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from utils.http_utils import AsyncPlaywright
|
||||
import asyncio
|
||||
|
||||
@@ -37,9 +38,9 @@ wbtop_data = []
|
||||
|
||||
|
||||
@wbtop.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
global wbtop_data
|
||||
msg = arg.extract_plain_text().strip()
|
||||
msg = get_message_text(event.json())
|
||||
if not wbtop_data or not msg:
|
||||
data, code = await get_data(wbtop_url)
|
||||
if code != 200:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent, Message
|
||||
from .data_source import (
|
||||
add_live_sub,
|
||||
delete_sub,
|
||||
@@ -9,15 +9,14 @@ from .data_source import (
|
||||
get_media_id,
|
||||
get_sub_status,
|
||||
SubManager,
|
||||
BilibiliSub,
|
||||
BilibiliSub
|
||||
)
|
||||
from models.level_user import LevelUser
|
||||
from configs.config import Config
|
||||
from utils.utils import is_number, scheduler, get_bot
|
||||
from utils.utils import get_message_text, is_number, scheduler, get_bot
|
||||
from typing import Optional
|
||||
from services.log import logger
|
||||
from nonebot import Driver
|
||||
from nonebot.params import CommandArg, ArgPlainText
|
||||
import nonebot
|
||||
|
||||
__zx_plugin_name__ = "B站订阅"
|
||||
@@ -69,9 +68,18 @@ async def _():
|
||||
sub_manager = SubManager()
|
||||
|
||||
|
||||
@add_sub.args_parser
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
season_data = state["season_data"]
|
||||
msg = get_message_text(event.json())
|
||||
if not is_number(msg) or int(msg) < 1 or int(msg) > len(season_data):
|
||||
await add_sub.reject("Id必须为数字且在范围内!请重新输入...")
|
||||
state["id"] = season_data[int(msg) - 1]["media_id"]
|
||||
|
||||
|
||||
@add_sub.handle()
|
||||
async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip().split()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json()).split()
|
||||
if len(msg) < 2:
|
||||
await add_sub.finish("参数不完全,请查看订阅帮助...")
|
||||
sub_type = msg[0]
|
||||
@@ -113,13 +121,10 @@ async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@add_sub.got("id")
|
||||
async def _(event: MessageEvent, state: T_State, id_: str = ArgPlainText("id")):
|
||||
season_data = state["season_data"]
|
||||
if not is_number(id_) or int(id_) < 1 or int(id_) > len(season_data):
|
||||
await add_sub.reject_arg("id", "Id必须为数字且在范围内!请重新输入...")
|
||||
id_ = season_data[int(id_) - 1]["media_id"]
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
sub_type = state["sub_type"]
|
||||
sub_user = state["sub_user"]
|
||||
id_ = state["id"]
|
||||
if sub_type in ["主播", "直播"]:
|
||||
await add_sub.send(await add_live_sub(id_, sub_user))
|
||||
elif sub_type.lower() in ["up", "用户"]:
|
||||
@@ -136,8 +141,8 @@ async def _(event: MessageEvent, state: T_State, id_: str = ArgPlainText("id")):
|
||||
|
||||
|
||||
@del_sub.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if not is_number(msg):
|
||||
await del_sub.finish("Id必须为数字!", at_sender=True)
|
||||
id_ = (
|
||||
@@ -157,11 +162,12 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@show_sub_info.handle()
|
||||
async def _(event: MessageEvent):
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
id_ = f"{event.group_id}"
|
||||
else:
|
||||
id_ = f"{event.user_id}"
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
id_ = (
|
||||
f"{event.user_id}:{event.group_id}"
|
||||
if isinstance(event, GroupMessageEvent)
|
||||
else f"{event.user_id}"
|
||||
)
|
||||
data = await BilibiliSub.get_sub_data(id_)
|
||||
live_rst = ""
|
||||
up_rst = ""
|
||||
@@ -175,7 +181,6 @@ async def _(event: MessageEvent):
|
||||
up_rst += f"\tUP:{x.uname}\n" f"\tuid:{x.uid}\n" f"------------------\n"
|
||||
if x.sub_type == "season":
|
||||
season_rst += (
|
||||
f"\t番剧id:{x.sub_id}\n"
|
||||
f"\t番名:{x.season_name}\n"
|
||||
f"\t当前集数:{x.season_current_episode}\n"
|
||||
f"------------------\n"
|
||||
@@ -184,9 +189,7 @@ async def _(event: MessageEvent):
|
||||
up_rst = "当前订阅的UP:\n" + up_rst if up_rst else up_rst
|
||||
season_rst = "当前订阅的番剧:\n" + season_rst if season_rst else season_rst
|
||||
if not live_rst and not up_rst and not season_rst:
|
||||
live_rst = (
|
||||
"该群目前没有任何订阅..." if isinstance(event, GroupMessageEvent) else "您目前没有任何订阅..."
|
||||
)
|
||||
live_rst = "您目前没有任何订阅..."
|
||||
await show_sub_info.send(live_rst + up_rst + season_rst)
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from utils.message_builder import image
|
||||
from bilibili_api.user import User
|
||||
from bilibili_api import user
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from datetime import datetime
|
||||
from utils.browser import get_browser
|
||||
@@ -19,7 +20,7 @@ import random
|
||||
|
||||
bilibili_search_url = "https://api.bilibili.com/x/web-interface/search/all/v2"
|
||||
|
||||
dynamic_path = IMAGE_PATH / "bilibili_sub" / "dynamic"
|
||||
dynamic_path = Path(IMAGE_PATH) / "bilibili_sub" / "dynamic"
|
||||
dynamic_path.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
|
||||
@@ -164,9 +165,7 @@ async def get_media_id(keyword: str) -> dict:
|
||||
for _ in range(3):
|
||||
try:
|
||||
_season_data = {}
|
||||
response = await AsyncHttpx.get(
|
||||
bilibili_search_url, params=params, timeout=5
|
||||
)
|
||||
response = await AsyncHttpx.get(bilibili_search_url, params=params, timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("data"):
|
||||
@@ -192,6 +191,7 @@ async def get_sub_status(id_: int, sub_type: str) -> Optional[str]:
|
||||
获取订阅状态
|
||||
:param id_: 订阅 id
|
||||
:param sub_type: 订阅类型
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
if sub_type == "live":
|
||||
@@ -201,7 +201,7 @@ async def get_sub_status(id_: int, sub_type: str) -> Optional[str]:
|
||||
elif sub_type == "season":
|
||||
return await _get_season_status(id_)
|
||||
except ResponseCodeException:
|
||||
return f"Id:{id_} 获取信息失败...请检查订阅Id是否存在或稍后再试..."
|
||||
return "获取信息失败...请检查订阅Id是否存在或稍后再试..."
|
||||
# except Exception as e:
|
||||
# logger.error(f"获取订阅状态发生预料之外的错误 id_:{id_} {type(e)}:{e}")
|
||||
# return "发生了预料之外的错误..请稍后再试或联系管理员....."
|
||||
@@ -254,12 +254,7 @@ async def _get_up_status(id_: int) -> Optional[str]:
|
||||
if dynamic_img:
|
||||
await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time)
|
||||
rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n"
|
||||
if (
|
||||
latest_video_created
|
||||
and _user.latest_video_created
|
||||
and video
|
||||
and _user.latest_video_created < latest_video_created
|
||||
):
|
||||
if _user.latest_video_created < latest_video_created and video:
|
||||
rst = rst + "-------------\n" if rst else rst
|
||||
await BilibiliSub.update_sub_info(
|
||||
id_, latest_video_created=latest_video_created
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from pathlib import Path
|
||||
from bilibili_api import user
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
BORDER_PATH = IMAGE_PATH / "border"
|
||||
BORDER_PATH = Path(IMAGE_PATH) / "border"
|
||||
BORDER_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
||||
+36
-27
@@ -1,12 +1,12 @@
|
||||
from nonebot import on_command
|
||||
from .data_source import get_bt_info
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import PrivateMessageEvent, Message
|
||||
from nonebot.adapters.onebot.v11.permission import PRIVATE
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from utils.utils import is_number
|
||||
from nonebot.params import CommandArg, ArgStr
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.adapters.cqhttp import PrivateMessageEvent
|
||||
from utils.utils import get_message_text
|
||||
from nonebot.adapters.cqhttp.permission import PRIVATE
|
||||
from asyncio.exceptions import TimeoutError
|
||||
|
||||
__zx_plugin_name__ = "磁力搜索"
|
||||
__plugin_usage__ = """
|
||||
@@ -28,7 +28,9 @@ __plugin_settings__ = {
|
||||
"limit_superuser": False,
|
||||
"cmd": ["bt", "磁力搜索", "Bt", "BT"],
|
||||
}
|
||||
__plugin_block_limit__ = {"rst": "您有bt任务正在进行,请等待结束."}
|
||||
__plugin_block_limit__ = {
|
||||
"rst": "您有bt任务正在进行,请等待结束."
|
||||
}
|
||||
__plugin_configs__ = {
|
||||
"BT_MAX_NUM": {
|
||||
"value": 10,
|
||||
@@ -41,37 +43,44 @@ __plugin_configs__ = {
|
||||
bt = on_command("bt", permission=PRIVATE, priority=5, block=True)
|
||||
|
||||
|
||||
@bt.args_parser
|
||||
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
if str(event.get_message()) in ["取消", "算了"]:
|
||||
await bt.finish("已取消操作..", at_sender=True)
|
||||
msg = get_message_text(event.json())
|
||||
if not msg:
|
||||
await bt.reject("你想搜索什么呢?", at_sender=True)
|
||||
state["keyword"] = msg
|
||||
state["page"] = "1"
|
||||
|
||||
|
||||
@bt.handle()
|
||||
async def _(state: T_State, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip().split()
|
||||
if msg:
|
||||
keyword = None
|
||||
page = 1
|
||||
if n := len(msg):
|
||||
keyword = msg[0]
|
||||
if n > 1 and is_number(msg[1]) and int(msg[1]) > 0:
|
||||
page = int(msg[1])
|
||||
state["keyword"] = keyword
|
||||
state["page"] = page
|
||||
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
mp = get_message_text(event.json())
|
||||
if not mp:
|
||||
return
|
||||
mp = mp.split()
|
||||
if len(mp) == 2:
|
||||
state["keyword"] = mp[0]
|
||||
state["page"] = mp[1]
|
||||
else:
|
||||
state["page"] = 1
|
||||
state["keyword"] = mp[0]
|
||||
state["page"] = "1"
|
||||
|
||||
|
||||
@bt.got("keyword", prompt="请输入要查询的内容!")
|
||||
async def _(
|
||||
event: PrivateMessageEvent,
|
||||
state: T_State,
|
||||
keyword: str = ArgStr("keyword"),
|
||||
page: str = ArgStr("page"),
|
||||
):
|
||||
@bt.got("keyword", prompt="虚空磁力?查什么GKD")
|
||||
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
keyword = state["keyword"]
|
||||
page = state["page"]
|
||||
await bt.send("开始搜索....", at_sender=True)
|
||||
send_flag = False
|
||||
try:
|
||||
async for title, type_, create_time, file_size, link in get_bt_info(
|
||||
async for title, itype, create_time, file_size, link in get_bt_info(
|
||||
keyword, page
|
||||
):
|
||||
await bt.send(
|
||||
f"标题:{title}\n"
|
||||
f"类型:{type_}\n"
|
||||
f"类型:{itype}\n"
|
||||
f"创建时间:{create_time}\n"
|
||||
f"文件大小:{file_size}\n"
|
||||
f"种子:{link}"
|
||||
|
||||
@@ -12,7 +12,7 @@ if platform.system() == "Windows":
|
||||
url = "http://www.eclzz.world"
|
||||
|
||||
|
||||
async def get_bt_info(keyword: str, page: int):
|
||||
async def get_bt_info(keyword: str, page: str):
|
||||
"""
|
||||
获取资源信息
|
||||
:param keyword: 关键词
|
||||
@@ -34,11 +34,11 @@ async def get_bt_info(keyword: str, page: int):
|
||||
.strip()
|
||||
)
|
||||
spans = divs[2].find_all("span")
|
||||
type_ = spans[0].text
|
||||
itype = spans[0].text
|
||||
create_time = spans[1].find("b").text
|
||||
file_size = spans[2].find("b").text
|
||||
link = await get_download_link(divs[0].find("a")["href"])
|
||||
yield title, type_, create_time, file_size, link
|
||||
yield title, itype, create_time, file_size, link
|
||||
|
||||
|
||||
async def get_download_link(_url: str) -> str:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from .music_163 import get_song_id, get_song_info
|
||||
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.cqhttp import Bot, Event, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from services.log import logger
|
||||
from nonebot import on_command
|
||||
@@ -30,8 +29,8 @@ music = on_command("点歌", priority=5, block=True)
|
||||
|
||||
|
||||
@music.handle()
|
||||
async def handle_first_receive(state: T_State, arg: Message = CommandArg()):
|
||||
args = arg.extract_plain_text().strip()
|
||||
async def handle_first_receive(bot: Bot, event: Event, state: T_State):
|
||||
args = str(event.get_message()).strip()
|
||||
if args:
|
||||
state["song_name"] = args
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from nonebot import on_command
|
||||
from .data_source import Check
|
||||
from nonebot.adapters.cqhttp import Bot, Event
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.permission import SUPERUSER
|
||||
from utils.message_builder import image
|
||||
@@ -27,5 +29,5 @@ check_ = on_command(
|
||||
|
||||
|
||||
@check_.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
await check_.send(image(b64=await check.show()))
|
||||
|
||||
@@ -4,6 +4,7 @@ from datetime import datetime
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from pathlib import Path
|
||||
import asyncio
|
||||
from services.log import logger
|
||||
|
||||
@@ -72,6 +73,6 @@ class Check:
|
||||
A.transparent(1)
|
||||
A.text((10, 10), rst)
|
||||
_x = max(width, height)
|
||||
bk = BuildImage(_x + 100, _x + 100, background=IMAGE_PATH / "background" / "check" / "0.jpg")
|
||||
bk = BuildImage(_x + 100, _x + 100, background=Path(IMAGE_PATH) / "background" / "check" / "0.jpg")
|
||||
bk.paste(A, alpha=True, center_type='center')
|
||||
return bk.pic2bs4()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot import on_command
|
||||
@@ -45,7 +45,7 @@ restart = on_command(
|
||||
|
||||
|
||||
@update_zhenxun.handle()
|
||||
async def _(bot: Bot):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
try:
|
||||
code, error = await check_update(bot)
|
||||
if error:
|
||||
@@ -67,13 +67,13 @@ async def _(bot: Bot):
|
||||
|
||||
|
||||
@restart.handle()
|
||||
async def _():
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if str(platform.system()).lower() == "windows":
|
||||
await restart.finish("暂无windows重启脚本...")
|
||||
|
||||
|
||||
@restart.got("flag", prompt="确定是否重启真寻?(重启失败咱们将失去联系,请谨慎!)")
|
||||
async def _(state: T_State):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
flag = state["flag"]
|
||||
if flag.lower() in ["true", "是", "好", "确定", "确定是"]:
|
||||
await restart.send("开始重启真寻..请稍等...")
|
||||
@@ -107,7 +107,8 @@ async def _():
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=f"检测到真寻版本更新\n"
|
||||
f"当前版本:{_version},最新版本:{latest_version}",
|
||||
f"当前版本:{_version},最新版本:{latest_version}\n"
|
||||
f"尝试自动更新...",
|
||||
)
|
||||
# try:
|
||||
# code = await check_update(bot)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message
|
||||
from nonebot.adapters.cqhttp import Bot, Message
|
||||
from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from nonebot import on_regex
|
||||
from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from utils.message_builder import image
|
||||
from services.log import logger
|
||||
from utils.manager import withdraw_message_manager
|
||||
@@ -31,10 +31,12 @@ __plugin_configs__ = {
|
||||
},
|
||||
}
|
||||
|
||||
coser = on_regex("^(cos|COS|coser|括丝)$", priority=5, block=True)
|
||||
coser = on_command(
|
||||
"cos", aliases={"coser", "括丝", "COS", "Cos", "cOS", "coS"}, priority=5, block=True
|
||||
)
|
||||
|
||||
|
||||
url = "https://api.iyk0.com/cos"
|
||||
url = "http://iw233.cn/API/cos.php"
|
||||
|
||||
|
||||
@coser.handle()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.permission import SUPERUSER
|
||||
from utils.utils import is_number, get_message_img
|
||||
from utils.utils import get_message_text, is_number, get_message_imgs
|
||||
from utils.message_builder import image
|
||||
from utils.message_builder import text as _text
|
||||
from services.log import logger
|
||||
from utils.message_builder import at
|
||||
from nonebot.params import CommandArg
|
||||
|
||||
|
||||
__zx_plugin_name__ = "联系管理员"
|
||||
@@ -58,10 +58,12 @@ reply = on_command("/t", priority=1, permission=SUPERUSER, block=True)
|
||||
|
||||
|
||||
@dialogue.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
text = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
uid = event.user_id
|
||||
coffee = int(list(bot.config.superusers)[0])
|
||||
text = get_message_text(event.json())
|
||||
img_msg = _text("")
|
||||
for img in get_message_img(event.json()):
|
||||
for img in get_message_imgs(event.json()):
|
||||
img_msg += image(img)
|
||||
if not text and not img_msg:
|
||||
await dialogue.send("请发送[滴滴滴]+您要说的内容~", at_sender=True)
|
||||
@@ -74,18 +76,17 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
group_name = (await bot.get_group_info(group_id=event.group_id))[
|
||||
"group_name"
|
||||
]
|
||||
nickname = event.sender.card or event.sender.nickname
|
||||
for coffee in bot.config.superusers:
|
||||
await bot.send_private_msg(
|
||||
user_id=int(coffee),
|
||||
message=_text(
|
||||
f"*****一份交流报告*****\n"
|
||||
f"昵称:{nickname}({event.user_id})\n"
|
||||
f"群聊:{group_name}({group_id})\n"
|
||||
f"消息:{text}"
|
||||
)
|
||||
+ img_msg,
|
||||
nickname = event.sender.card if event.sender.card else event.sender.nickname
|
||||
await bot.send_private_msg(
|
||||
user_id=coffee,
|
||||
message=_text(
|
||||
f"*****一份交流报告*****\n"
|
||||
f"昵称:{nickname}({uid})\n"
|
||||
f"群聊:{group_name}({group_id})\n"
|
||||
f"消息:{text}"
|
||||
)
|
||||
+ img_msg,
|
||||
)
|
||||
await dialogue.send(
|
||||
_text(f"您的话已发送至管理员!\n======\n{text}") + img_msg, at_sender=True
|
||||
)
|
||||
@@ -98,12 +99,12 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
"msg": _text(text) + img_msg,
|
||||
}
|
||||
# print(dialogue_data)
|
||||
logger.info(f"Q{event.user_id}@群{group_id} 联系管理员:text:{text}")
|
||||
logger.info(f"Q{uid}@群{group_id} 联系管理员:{coffee} text:{text}")
|
||||
|
||||
|
||||
@reply.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if not msg:
|
||||
result = "*****待回复消息总览*****\n"
|
||||
for key in dialogue_data.keys():
|
||||
@@ -126,26 +127,26 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
id_ = msg[0]
|
||||
user_id = dialogue_data[id_]["user_id"]
|
||||
group_id = dialogue_data[id_]["group_id"]
|
||||
text = " ".join(msg[1:])
|
||||
text = msg[1]
|
||||
dialogue_data.pop(id_)
|
||||
else:
|
||||
user_id = 0
|
||||
if is_number(msg[1]):
|
||||
group_id = int(msg[1])
|
||||
text = " ".join(msg[2:])
|
||||
text = msg[2]
|
||||
else:
|
||||
await reply.finish("群号错误...", at_sender=True)
|
||||
else:
|
||||
user_id = int(msg[0])
|
||||
if is_number(msg[1]) and len(msg[1]) > 5:
|
||||
group_id = int(msg[1])
|
||||
text = " ".join(msg[2:])
|
||||
text = msg[2]
|
||||
else:
|
||||
group_id = 0
|
||||
text = " ".join(msg[1:])
|
||||
text = msg[1]
|
||||
else:
|
||||
await reply.finish("第一参数,请输入数字.....", at_sender=True)
|
||||
for img in get_message_img(event.json()):
|
||||
for img in get_message_imgs(event.json()):
|
||||
text += image(img)
|
||||
if group_id:
|
||||
if user_id:
|
||||
|
||||
+167
-105
@@ -1,13 +1,16 @@
|
||||
from nonebot import on_regex, on_keyword
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.params import RegexGroup
|
||||
from utils.utils import scheduler
|
||||
from .genshin_handle import genshin_draw, update_genshin_info, reset_count, reload_genshin_pool
|
||||
from .genshin_handle import (
|
||||
genshin_draw,
|
||||
update_genshin_info,
|
||||
reset_count,
|
||||
reload_genshin_pool,
|
||||
)
|
||||
from .prts_handle import update_prts_info, prts_draw, reload_prts_pool
|
||||
from .pretty_handle import update_pretty_info, pretty_draw, reload_pretty_pool
|
||||
from .guardian_handle import update_guardian_info, guardian_draw, reload_guardian_pool
|
||||
from .guardian_handle import update_guardian_info, guardian_draw
|
||||
from .pcr_handle import update_pcr_info, pcr_draw
|
||||
from .azur_handle import update_azur_info, azur_draw
|
||||
from .fgo_handle import update_fgo_info, fgo_draw
|
||||
@@ -15,12 +18,21 @@ from .onmyoji_handle import update_onmyoji_info, onmyoji_draw
|
||||
from .update_game_info import update_info
|
||||
from .util import is_number, check_num
|
||||
from .rule import is_switch
|
||||
from .config import draw_config
|
||||
from .config import (
|
||||
PRTS_FLAG,
|
||||
PRETTY_FLAG,
|
||||
GUARDIAN_FLAG,
|
||||
GENSHIN_FLAG,
|
||||
PCR_FLAG,
|
||||
AZUR_FLAG,
|
||||
FGO_FLAG,
|
||||
ONMYOJI_FLAG,
|
||||
)
|
||||
from .async_update_game_info import async_update_game
|
||||
from typing import Tuple, Any
|
||||
import re
|
||||
import asyncio
|
||||
|
||||
from utils.utils import scheduler
|
||||
from services.log import logger
|
||||
|
||||
__zx_plugin_name__ = "游戏抽卡"
|
||||
__plugin_usage__ = """
|
||||
@@ -89,44 +101,81 @@ __plugin_settings__ = {
|
||||
"cmd": ["游戏抽卡", "抽卡"],
|
||||
}
|
||||
|
||||
prts = on_regex(r'.*?方舟([1-9|一][0-9]{0,2}[抽|井|连])', rule=is_switch('prts'), priority=5, block=True)
|
||||
prts_update = on_keyword({'更新方舟信息', '更新明日方舟信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
prts_up_reload = on_keyword({'重载方舟卡池'}, priority=1, block=True)
|
||||
|
||||
genshin = on_regex(r'.*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('genshin'), priority=5, block=True)
|
||||
genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True)
|
||||
genshin_up_reload = on_keyword({'重载原神卡池'}, priority=1, block=True)
|
||||
prts = on_regex(
|
||||
r".*?方舟[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("prts"), priority=5, block=True
|
||||
)
|
||||
prts_update = on_keyword(
|
||||
{"更新方舟信息", "更新明日方舟信息"}, permission=SUPERUSER, priority=1, block=True
|
||||
)
|
||||
prts_up_reload = on_keyword({"重载方舟卡池"}, priority=1, block=True)
|
||||
|
||||
pretty = on_regex(r'.*?马娘卡?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('pretty'), priority=5, block=True)
|
||||
pretty_update = on_keyword({'更新马娘信息', '更新赛马娘信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
pretty_up_reload = on_keyword({'重载赛马娘卡池'}, priority=1, block=True)
|
||||
genshin = on_regex(
|
||||
".*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井]",
|
||||
rule=is_switch("genshin"),
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
genshin_update = on_keyword({"更新原神信息"}, permission=SUPERUSER, priority=1, block=True)
|
||||
genshin_reset = on_keyword({"重置原神抽卡"}, priority=1, block=True)
|
||||
genshin_up_reload = on_keyword({"重载原神卡池"}, priority=1, block=True)
|
||||
|
||||
guardian = on_regex(r'.*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('guardian'), priority=5, block=True)
|
||||
guardian_update = on_keyword({'更新坎公骑冠剑信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
guardian_up_reload = on_keyword({'重载坎公骑冠剑卡池'}, priority=1, block=True)
|
||||
pretty = on_regex(
|
||||
".*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("pretty"), priority=5, block=True
|
||||
)
|
||||
pretty_update = on_keyword(
|
||||
{"更新马娘信息", "更新赛马娘信息"}, permission=SUPERUSER, priority=1, block=True
|
||||
)
|
||||
pretty_up_reload = on_keyword({"重载赛马娘卡池"}, priority=1, block=True)
|
||||
|
||||
pcr = on_regex(r'.*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('pcr'), priority=5, block=True)
|
||||
pcr_update = on_keyword({'更新pcr信息', '更新公主连结信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
guardian = on_regex(
|
||||
".*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井]",
|
||||
rule=is_switch("guardian"),
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
guardian_update = on_keyword(
|
||||
{"更新坎公骑冠剑信息"}, permission=SUPERUSER, priority=1, block=True
|
||||
)
|
||||
|
||||
azur = on_regex(r'.*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('azur'), priority=5, block=True)
|
||||
azur_update = on_keyword({'更新碧蓝信息', '更新碧蓝航线信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
pcr = on_regex(
|
||||
".*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井]",
|
||||
rule=is_switch("pcr"),
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
pcr_update = on_keyword(
|
||||
{"更新pcr信息", "更新公主连结信息"}, permission=SUPERUSER, priority=1, block=True
|
||||
)
|
||||
|
||||
fgo = on_regex(r'.*?fgo[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('fgo'), priority=5, block=True)
|
||||
fgo_update = on_keyword({'更新fgo信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
azur = on_regex(
|
||||
".*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽]",
|
||||
rule=is_switch("azur"),
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
azur_update = on_keyword(
|
||||
{"更新碧蓝信息", "更新碧蓝航线信息"}, permission=SUPERUSER, priority=1, block=True
|
||||
)
|
||||
|
||||
onmyoji = on_regex(r'.*?阴阳师[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('onmyoji'), priority=5, block=True)
|
||||
onmyoji_update = on_keyword({'更新阴阳师信息'}, permission=SUPERUSER, priority=1, block=True)
|
||||
fgo = on_regex(
|
||||
".*?fgo[1-9|一][0-9]{0,2}[抽]", rule=is_switch("fgo"), priority=5, block=True
|
||||
)
|
||||
fgo_update = on_keyword({"更新fgo信息"}, permission=SUPERUSER, priority=1, block=True)
|
||||
|
||||
onmyoji = on_regex(
|
||||
".*?阴阳师[1-9|一][0-9]{0,2}[抽]", rule=is_switch("onmyoji"), priority=5, block=True
|
||||
)
|
||||
onmyoji_update = on_keyword({"更新阴阳师信息"}, permission=SUPERUSER, priority=1, block=True)
|
||||
|
||||
|
||||
@prts.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State, reg: Tuple[Any, ...] = RegexGroup()):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
print(reg)
|
||||
if msg in ['方舟一井', '方舟1井']:
|
||||
if msg in ["方舟一井", "方舟1井"]:
|
||||
num = 300
|
||||
else:
|
||||
rmsg = re.search(r'.*?方舟(.*)[抽|连]', msg)
|
||||
rmsg = re.search(r".*?方舟(.*)抽", msg)
|
||||
if rmsg:
|
||||
num, flag = check_num(rmsg.group(1), 300)
|
||||
if not flag:
|
||||
@@ -134,28 +183,31 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, reg: Tuple[Any, ...]
|
||||
else:
|
||||
return
|
||||
await prts.send(await prts_draw(int(num)), at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 方舟 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@prts_up_reload.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
text = await reload_prts_pool()
|
||||
await prts_up_reload.finish(Message(f'重载完成!\n{text}'))
|
||||
await prts_up_reload.finish(Message(f"重载完成!\n{text}"))
|
||||
|
||||
|
||||
@genshin.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
rmsg = re.search(r'.*?原神(武器|角色)?池?(.*)[抽|井|连]', msg)
|
||||
rmsg = re.search(r".*?原神(武器|角色)?池?(.*)[抽|井]", msg)
|
||||
if rmsg:
|
||||
pool_name = rmsg.group(1)
|
||||
if pool_name == '武器':
|
||||
pool_name = 'arms'
|
||||
elif pool_name == '角色':
|
||||
pool_name = 'char'
|
||||
if pool_name == "武器":
|
||||
pool_name = "arms"
|
||||
elif pool_name == "角色":
|
||||
pool_name = "char"
|
||||
else:
|
||||
pool_name = ''
|
||||
pool_name = ""
|
||||
num = rmsg.group(2)
|
||||
if msg.find('一井') != -1 or msg.find('1井') != -1:
|
||||
if msg.find("一井") != -1 or msg.find("1井") != -1:
|
||||
num = 180
|
||||
else:
|
||||
num, flag = check_num(num, 180)
|
||||
@@ -163,89 +215,94 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await genshin.finish(num, at_sender=True)
|
||||
else:
|
||||
return
|
||||
await genshin.send(await genshin_draw(event.user_id, int(num), pool_name), at_sender=True)
|
||||
await genshin.send(
|
||||
await genshin_draw(event.user_id, int(num), pool_name), at_sender=True
|
||||
)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 原神 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@genshin_up_reload.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
text = await reload_genshin_pool()
|
||||
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
|
||||
await genshin_reset.finish(Message(f"重载成功!\n{text}"))
|
||||
|
||||
|
||||
@genshin_reset.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
reset_count(event.user_id)
|
||||
await genshin_reset.send('重置了原神抽卡次数', at_sender=True)
|
||||
await genshin_reset.send("重置了原神抽卡次数", at_sender=True)
|
||||
|
||||
|
||||
@pretty.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
if msg.find('1井') != -1 or msg.find('一井') != -1:
|
||||
if msg.find("1井") != -1 or msg.find("一井") != -1:
|
||||
num = 200
|
||||
if msg.find("卡") == -1:
|
||||
pool_name = 'char'
|
||||
pool_name = "char"
|
||||
else:
|
||||
pool_name = 'card'
|
||||
pool_name = "card"
|
||||
else:
|
||||
rmsg = re.search(r'.*?马娘(.*)[抽|连]', msg)
|
||||
rmsg = re.search(r".*?马娘(.*)抽", msg)
|
||||
if rmsg:
|
||||
num = rmsg.group(1)
|
||||
if num[0] == '卡':
|
||||
if num[0] == "卡":
|
||||
num = num[1:]
|
||||
pool_name = 'card'
|
||||
pool_name = "card"
|
||||
else:
|
||||
pool_name = 'char'
|
||||
pool_name = "char"
|
||||
num, flag = check_num(num, 200)
|
||||
if not flag:
|
||||
await pretty.finish(num, at_sender=True)
|
||||
else:
|
||||
return
|
||||
await pretty.send(await pretty_draw(int(num), pool_name), at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 赛马娘 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@pretty_up_reload.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
text = await reload_pretty_pool()
|
||||
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
|
||||
await genshin_reset.finish(Message(f"重载成功!\n{text}"))
|
||||
|
||||
|
||||
@guardian.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
pool_name = 'char'
|
||||
if msg.find('1井') != -1 or msg.find('一井') != -1:
|
||||
pool_name = "char"
|
||||
if msg.find("1井") != -1 or msg.find("一井") != -1:
|
||||
num = 300
|
||||
if msg.find('武器') != -1:
|
||||
pool_name = 'arms'
|
||||
if msg.find("武器") != -1:
|
||||
pool_name = "arms"
|
||||
else:
|
||||
rmsg = re.search(r'.*?坎公骑冠剑(.*)[抽|连]', msg)
|
||||
rmsg = re.search(r".*?坎公骑冠剑(.*)抽", msg)
|
||||
if rmsg:
|
||||
num = rmsg.group(1)
|
||||
if num.find('武器') != -1:
|
||||
pool_name = 'arms'
|
||||
num = num.replace('武器', '')
|
||||
if num.find("武器") != -1:
|
||||
pool_name = "arms"
|
||||
num = num.replace("武器", "")
|
||||
num, flag = check_num(num, 300)
|
||||
if not flag:
|
||||
await guardian.finish(num, at_sender=True)
|
||||
else:
|
||||
return
|
||||
await guardian.send(await guardian_draw(int(num), pool_name), at_sender=True)
|
||||
|
||||
|
||||
@guardian_up_reload.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
text = await reload_guardian_pool()
|
||||
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 坎公骑冠剑 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@pcr.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
if msg.find('1井') != -1 or msg.find('一井') != -1:
|
||||
if msg.find("1井") != -1 or msg.find("一井") != -1:
|
||||
num = 300
|
||||
else:
|
||||
rmsg = re.search(r'.*?(pcr|公主连结)(.*)[抽|井|连]', msg)
|
||||
rmsg = re.search(r".*?(pcr|公主连结)(.*)[抽|井]", msg)
|
||||
if rmsg:
|
||||
num, flag = check_num(rmsg.group(2), 300)
|
||||
if not flag:
|
||||
@@ -253,12 +310,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
else:
|
||||
return
|
||||
await pcr.send(await pcr_draw(int(num)), at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 公主连结 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@azur.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
rmsg = re.search(r'.*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽|连]', msg)
|
||||
rmsg = re.search(".*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽]", msg)
|
||||
if rmsg:
|
||||
pool_name = rmsg.group(1)
|
||||
num, flag = check_num(rmsg.group(2), 300)
|
||||
@@ -267,12 +327,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
else:
|
||||
return
|
||||
await azur.send(await azur_draw(int(num), pool_name), at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 碧蓝航线 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@fgo.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
rmsg = re.search(r'.*?fgo(.*)[抽|连]', msg)
|
||||
rmsg = re.search(".*?fgo(.*)抽", msg)
|
||||
if rmsg:
|
||||
num, flag = check_num(rmsg.group(1), 300)
|
||||
if not flag:
|
||||
@@ -280,12 +343,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
else:
|
||||
return
|
||||
await fgo.send(await fgo_draw(int(num)), at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) fgo {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@onmyoji.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
rmsg = re.search(r'.*?阴阳师(.*)[抽|连]', msg)
|
||||
rmsg = re.search(".*?阴阳师(.*)抽", msg)
|
||||
if rmsg:
|
||||
num, flag = check_num(rmsg.group(1), 300)
|
||||
if not flag:
|
||||
@@ -293,122 +359,118 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
else:
|
||||
return
|
||||
await onmyoji.send(await onmyoji_draw(int(num)), at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 阴阳师 {num}抽"
|
||||
)
|
||||
|
||||
|
||||
@prts_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_prts_info()
|
||||
await prts_update.finish('更新完成!')
|
||||
await prts_update.finish("更新完成!")
|
||||
|
||||
|
||||
@genshin_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_genshin_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
@pretty_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_pretty_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
@guardian_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_guardian_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
@pcr_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_pcr_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
@azur_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_azur_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
@fgo_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_fgo_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
@onmyoji_update.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_onmyoji_info()
|
||||
await genshin_update.finish('更新完成!')
|
||||
await genshin_update.finish("更新完成!")
|
||||
|
||||
|
||||
# 更新资源
|
||||
@scheduler.scheduled_job(
|
||||
'cron',
|
||||
"cron",
|
||||
hour=4,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
tasks = []
|
||||
if draw_config.PRTS_FLAG:
|
||||
if PRTS_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_prts_info()))
|
||||
if draw_config.GENSHIN_FLAG:
|
||||
if GENSHIN_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_genshin_info()))
|
||||
if draw_config.PRETTY_FLAG:
|
||||
if PRETTY_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_pretty_info()))
|
||||
if draw_config.GUARDIAN_FLAG:
|
||||
if GUARDIAN_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_guardian_info()))
|
||||
if draw_config.PCR_FLAG:
|
||||
if PCR_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_pcr_info()))
|
||||
if draw_config.AZUR_FLAG:
|
||||
if AZUR_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_azur_info()))
|
||||
if draw_config.FGO_FLAG:
|
||||
if FGO_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_fgo_info()))
|
||||
if draw_config.ONMYOJI_FLAG:
|
||||
if ONMYOJI_FLAG:
|
||||
tasks.append(asyncio.ensure_future(update_onmyoji_info()))
|
||||
await asyncio.gather(*tasks)
|
||||
logger.info("draw_card 抽卡自动更新完成...")
|
||||
|
||||
|
||||
# 每天四点重载方舟up卡池
|
||||
@scheduler.scheduled_job(
|
||||
'cron',
|
||||
"cron",
|
||||
hour=4,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
if draw_config.PRTS_FLAG:
|
||||
if PRTS_FLAG:
|
||||
await reload_prts_pool()
|
||||
logger.info("自动重载方舟卡池UP成功")
|
||||
|
||||
|
||||
# 每天四点重载赛马娘up卡池
|
||||
@scheduler.scheduled_job(
|
||||
'cron',
|
||||
"cron",
|
||||
hour=4,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
if draw_config.PRETTY_FLAG:
|
||||
if PRETTY_FLAG:
|
||||
await reload_pretty_pool()
|
||||
logger.info("自动重载赛马娘UP成功")
|
||||
|
||||
|
||||
# 每天下午六点点重载原神up卡池
|
||||
@scheduler.scheduled_job(
|
||||
'cron',
|
||||
"cron",
|
||||
hour=18,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
if draw_config.PRTS_FLAG:
|
||||
if PRTS_FLAG:
|
||||
await reload_genshin_pool()
|
||||
|
||||
|
||||
# 重载坎公骑冠剑卡池
|
||||
@scheduler.scheduled_job(
|
||||
'cron',
|
||||
hour=4,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
if draw_config.GUARDIAN_FLAG:
|
||||
await reload_guardian_pool()
|
||||
logger.info("自动重载原神卡池UP成功")
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from bs4 import BeautifulSoup
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
from .config import DRAW_DATA_PATH
|
||||
from .config import DRAW_PATH
|
||||
from pathlib import Path
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from nonebot.log import logger
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
|
||||
import re
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
@@ -13,10 +13,10 @@ except ModuleNotFoundError:
|
||||
|
||||
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
|
||||
|
||||
prts_up_char = DRAW_DATA_PATH / "draw_card_up" / "prts_up_char.json"
|
||||
genshin_up_char = DRAW_DATA_PATH / "draw_card_up" / "genshin_up_char.json"
|
||||
pretty_up_char = DRAW_DATA_PATH / "draw_card_up" / "pretty_up_char.json"
|
||||
guardian_up_char = DRAW_DATA_PATH / "draw_card_up" / "guardian_up_char.json"
|
||||
prts_up_char = Path(DRAW_PATH + "/draw_card_up/prts_up_char.json")
|
||||
genshin_up_char = Path(DRAW_PATH + "/draw_card_up/genshin_up_char.json")
|
||||
pretty_up_char = Path(DRAW_PATH + "/draw_card_up/pretty_up_char.json")
|
||||
guardian_up_char = Path(DRAW_PATH + "/draw_card_up/guardian_up_char.json")
|
||||
|
||||
prts_url = "https://ak.hypergryph.com/news.html"
|
||||
genshin_url = "https://wiki.biligame.com/ys/%E7%A5%88%E6%84%BF"
|
||||
@@ -26,37 +26,37 @@ guardian_url = "https://wiki.biligame.com/gt/%E9%A6%96%E9%A1%B5"
|
||||
|
||||
# 是否过时
|
||||
def is_expired(data: dict):
|
||||
times = data['time'].split('-')
|
||||
for i in range(len(times)):
|
||||
times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-')
|
||||
start_date = datetime.strptime(times[0], '%Y-%m-%d').date()
|
||||
end_date = datetime.strptime(times[1], '%Y-%m-%d').date()
|
||||
now = datetime.now().date()
|
||||
return not start_date <= now <= end_date
|
||||
try:
|
||||
times = data['time'].split('-')
|
||||
for i in range(len(times)):
|
||||
times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-')
|
||||
start_date = datetime.strptime(times[0], '%Y-%m-%d').date()
|
||||
end_date = datetime.strptime(times[1], '%Y-%m-%d').date()
|
||||
now = datetime.now().date()
|
||||
except ValueError:
|
||||
return False
|
||||
return start_date <= now <= end_date
|
||||
|
||||
|
||||
# 检查写入
|
||||
def check_write(data: dict, up_char_file):
|
||||
try:
|
||||
if is_expired(data['char']):
|
||||
for x in list(data.keys()):
|
||||
data[x]['title'] = ''
|
||||
if is_expired(data['char']):
|
||||
for x in list(data.keys()):
|
||||
data[x]['title'] = ''
|
||||
else:
|
||||
with open(up_char_file, 'w', encoding='utf8') as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
if not up_char_file.exists():
|
||||
with open(up_char_file, 'w', encoding='utf8') as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
else:
|
||||
with open(up_char_file, 'r', encoding='utf8') as f:
|
||||
old_data = json.load(f)
|
||||
if is_expired(old_data['char']):
|
||||
return old_data
|
||||
else:
|
||||
with open(up_char_file, 'w', encoding='utf8') as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
if not up_char_file.exists():
|
||||
with open(up_char_file, 'w', encoding='utf8') as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
else:
|
||||
with open(up_char_file, 'r', encoding='utf8') as f:
|
||||
old_data = json.load(f)
|
||||
if is_expired(old_data['char']):
|
||||
return old_data
|
||||
else:
|
||||
with open(up_char_file, 'w', encoding='utf8') as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
except ValueError:
|
||||
pass
|
||||
return data
|
||||
|
||||
|
||||
@@ -66,22 +66,17 @@ class PrtsAnnouncement:
|
||||
self.game_name = '明日方舟'
|
||||
|
||||
async def _get_announcement_text(self):
|
||||
res = await AsyncHttpx.get(prts_url, timeout=7)
|
||||
soup = BeautifulSoup(res.text, 'lxml')
|
||||
text = (await AsyncHttpx.get(prts_url)).text
|
||||
soup = BeautifulSoup(text, 'lxml')
|
||||
ol = soup.find('ol', {'class': 'articleList active', 'data-category-key': 'LATEST'})
|
||||
for li in ol:
|
||||
type_ = li.find('span', {'class': 'articleItemCate'}).text
|
||||
if type_ == '活动':
|
||||
itype = li.find('span', {'class': 'articleItemCate'}).text
|
||||
if itype == '活动':
|
||||
a = li.find('a')['href']
|
||||
return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}', timeout=7)).text
|
||||
|
||||
return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}')).text
|
||||
|
||||
async def update_up_char(self):
|
||||
prts_up_char.parent.mkdir(parents=True, exist_ok=True)
|
||||
if prts_up_char.exists():
|
||||
with open(prts_up_char, 'r', encoding='utf8') as f:
|
||||
data = json.load(f)
|
||||
if not data.get('char'):
|
||||
prts_up_char.unlink()
|
||||
try:
|
||||
data = {'char': {'up_char': {'6': {}, '5': {}, '4': {}}, 'title': '', 'time': '', 'pool_img': ''}}
|
||||
text = await self._get_announcement_text()
|
||||
@@ -150,7 +145,7 @@ class GenshinAnnouncement:
|
||||
self.game_name = '原神'
|
||||
|
||||
async def _get_announcement_text(self):
|
||||
return (await AsyncHttpx.get(genshin_url, timeout=7)).text
|
||||
return (await AsyncHttpx.get(genshin_url)).text
|
||||
|
||||
async def update_up_char(self):
|
||||
genshin_up_char.parent.mkdir(exist_ok=True, parents=True)
|
||||
@@ -167,34 +162,34 @@ class GenshinAnnouncement:
|
||||
trs = table.find('tbody').find_all('tr')
|
||||
pool_img = trs[0].find('th').find('img')
|
||||
if pool_img['title'].find('角色活动') == -1:
|
||||
type_ = 'arms'
|
||||
itype = 'arms'
|
||||
else:
|
||||
type_ = 'char'
|
||||
itype = 'char'
|
||||
try:
|
||||
data[type_]['pool_img'] = str(pool_img['srcset']).split(' ')[0]
|
||||
data[itype]['pool_img'] = str(pool_img['srcset']).split(' ')[0]
|
||||
except KeyError:
|
||||
data[type_]['pool_img'] = pool_img['src']
|
||||
data[type_]['title'] = str(pool_img['title']).split(f'期{"角色" if type_ == "char" else "武器"}')[0][:-3]
|
||||
data[type_]['time'] = trs[1].find('td').text
|
||||
if data[type_]['time'][-1] == '\n':
|
||||
data[type_]['time'] = data[type_]['time'][:-1]
|
||||
if '版本更新后' in data[type_]['time']:
|
||||
sp = data[type_]['time'].split('~')
|
||||
end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M")
|
||||
data[itype]['pool_img'] = pool_img['src']
|
||||
data[itype]['title'] = str(pool_img['title']).split(f'期{"角色" if itype == "char" else "武器"}')[0][:-3]
|
||||
data[itype]['time'] = trs[1].find('td').text
|
||||
if data[itype]['time'][-1] == '\n':
|
||||
data[itype]['time'] = data[itype]['time'][:-1]
|
||||
if '版本更新后' in data[itype]['time']:
|
||||
sp = data[itype]['time'].split('~')
|
||||
end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M:%S")
|
||||
start_time = end_time - timedelta(days=20)
|
||||
data[type_]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d')
|
||||
data[itype]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d')
|
||||
tmp = ''
|
||||
for tm in data[type_]['time'].split('~'):
|
||||
for tm in data[itype]['time'].split('~'):
|
||||
date_time_sp = tm.split('/')
|
||||
date_time_sp[2] = date_time_sp[2].strip().replace(' ', '日 ')
|
||||
tmp += date_time_sp[1] + '月' + date_time_sp[2] + ' - '
|
||||
data[type_]['time'] = tmp[:-2].strip()
|
||||
data[itype]['time'] = tmp[:-2].strip()
|
||||
for a in trs[2].find('td').find_all('a'):
|
||||
char_name = a['title']
|
||||
data[type_]['up_char']['5'][char_name] = "50"
|
||||
data[itype]['up_char']['5'][char_name] = "50"
|
||||
for a in trs[3].find('td').find_all('a'):
|
||||
char_name = a['title']
|
||||
data[type_]['up_char']['4'][char_name] = "50"
|
||||
data[itype]['up_char']['4'][char_name] = "50"
|
||||
except TimeoutError:
|
||||
logger.warning(f'更新原神UP池信息超时...')
|
||||
if genshin_up_char.exists():
|
||||
@@ -219,9 +214,10 @@ class PrettyAnnouncement:
|
||||
self.game_name = '赛马娘'
|
||||
|
||||
async def _get_announcement_text(self):
|
||||
res = await AsyncHttpx.get(pretty_url, timeout=7)
|
||||
soup = BeautifulSoup(res.text, 'lxml')
|
||||
text = (await AsyncHttpx.get(pretty_url)).text
|
||||
soup = BeautifulSoup(text, 'lxml')
|
||||
divs = soup.find('div', {'id': 'mw-content-text'}).find('div').find_all('div')
|
||||
title = " "
|
||||
for div in divs:
|
||||
a = div.find('a')
|
||||
try:
|
||||
@@ -231,9 +227,10 @@ class PrettyAnnouncement:
|
||||
if title.find('新角色追加') != -1:
|
||||
url = a['href']
|
||||
break
|
||||
return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}', timeout=7)).text, title[:-2]
|
||||
return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}')).text, title[:-2]
|
||||
|
||||
async def update_up_char(self):
|
||||
pretty_up_char.parent.mkdir(exist_ok=True, parents=True)
|
||||
data = {
|
||||
'char': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''},
|
||||
'card': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''}
|
||||
@@ -246,14 +243,12 @@ class PrettyAnnouncement:
|
||||
context = soup.find('div', {'class': 'mw-parser-output'})
|
||||
data['char']['title'] = title
|
||||
data['card']['title'] = title
|
||||
for big in context.find_all('big'):
|
||||
r = re.search(r'\d{1,2}/\d{1,2} \d{1,2}:\d{1,2}', str(big.text))
|
||||
if r:
|
||||
time = str(big.text)
|
||||
break
|
||||
r = re.search(r'(\d{1,2}/\d{1,2} \d{1,2}:\d{1,2} ~ \d{1,2}/\d{1,2} \d{1,2}:\d{1,2})', str(context.text))
|
||||
if r:
|
||||
time = str(r.group(1))
|
||||
else:
|
||||
logger.warning('赛马娘UP无法找到活动日期....取消更新UP池子...')
|
||||
return
|
||||
logger.error('赛马娘UP无法找到活动日期....取消更新UP池子...')
|
||||
return check_write(data, pretty_up_char)
|
||||
time = time.replace('~', '-').replace('/', '月').split(' ')
|
||||
time = time[0] + '日 ' + time[1] + ' - ' + time[3] + '日 ' + time[4]
|
||||
data['char']['time'] = time
|
||||
@@ -314,7 +309,7 @@ class PrettyAnnouncement:
|
||||
if star == 'R':
|
||||
data['card']['up_char']['1'][char_name] = '70'
|
||||
# 日文->中文
|
||||
with open(DRAW_DATA_PATH / 'pretty_card.json', 'r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f:
|
||||
all_data = json.load(f)
|
||||
for star in data['card']['up_char'].keys():
|
||||
for name in list(data['card']['up_char'][star].keys()):
|
||||
@@ -343,7 +338,7 @@ class GuardianAnnouncement:
|
||||
self.game_name = '坎公骑冠剑'
|
||||
|
||||
async def _get_announcement_text(self):
|
||||
return (await AsyncHttpx.get(guardian_url, timeout=7)).text
|
||||
return (await AsyncHttpx.get(guardian_url)).text
|
||||
|
||||
async def update_up_char(self):
|
||||
data = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import asyncio
|
||||
import nonebot
|
||||
from nonebot.log import logger
|
||||
import os
|
||||
from services.log import logger
|
||||
from .pcr_handle import update_pcr_info, init_pcr_data
|
||||
from .azur_handle import update_azur_info, init_azur_data
|
||||
from .prts_handle import update_prts_info, init_prts_data
|
||||
@@ -9,10 +10,11 @@ from .guardian_handle import update_guardian_info, init_guardian_data
|
||||
from .genshin_handle import update_genshin_info, init_genshin_data
|
||||
from .fgo_handle import update_fgo_info, init_fgo_data
|
||||
from .onmyoji_handle import update_onmyoji_info, init_onmyoji_data
|
||||
from .config import draw_config, DRAW_DATA_PATH
|
||||
from .config import DRAW_PATH, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, PCR_FLAG, AZUR_FLAG, GENSHIN_FLAG, FGO_FLAG, \
|
||||
ONMYOJI_FLAG
|
||||
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
driver: nonebot.Driver = nonebot.get_driver()
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
@@ -20,44 +22,49 @@ async def async_update_game():
|
||||
tasks = []
|
||||
init_lst = [init_pcr_data, init_pretty_data, init_azur_data, init_prts_data, init_genshin_data, init_guardian_data,
|
||||
init_fgo_data, init_onmyoji_data]
|
||||
if draw_config.PRTS_FLAG and not (DRAW_DATA_PATH / 'prts.json').exists():
|
||||
if PRTS_FLAG and not os.path.exists(DRAW_PATH + 'prts.json'):
|
||||
tasks.append(asyncio.ensure_future(update_prts_info()))
|
||||
init_lst.remove(init_prts_data)
|
||||
|
||||
if draw_config.PRETTY_FLAG and (not (DRAW_DATA_PATH / 'pretty.json').exists() or
|
||||
not (DRAW_DATA_PATH / 'pretty_card.json').exists()):
|
||||
if PRETTY_FLAG and (not os.path.exists(DRAW_PATH + 'pretty.json') or
|
||||
not os.path.exists(DRAW_PATH + 'pretty_card.json')):
|
||||
tasks.append(asyncio.ensure_future(update_pretty_info()))
|
||||
init_lst.remove(init_pretty_data)
|
||||
|
||||
if draw_config.GUARDIAN_FLAG and not (DRAW_DATA_PATH / 'guardian.json').exists():
|
||||
if GUARDIAN_FLAG and not os.path.exists(DRAW_PATH + 'guardian.json'):
|
||||
tasks.append(asyncio.ensure_future(update_guardian_info()))
|
||||
init_lst.remove(init_guardian_data)
|
||||
|
||||
if draw_config.PCR_FLAG and not (DRAW_DATA_PATH / 'pcr.json').exists():
|
||||
if PCR_FLAG and not os.path.exists(DRAW_PATH + 'pcr.json'):
|
||||
tasks.append(asyncio.ensure_future(update_pcr_info()))
|
||||
init_lst.remove(init_pcr_data)
|
||||
|
||||
if draw_config.GENSHIN_FLAG and (not (DRAW_DATA_PATH / 'genshin.json').exists() or
|
||||
not (DRAW_DATA_PATH / 'genshin_arms.json').exists()):
|
||||
if GENSHIN_FLAG and (not os.path.exists(DRAW_PATH + 'genshin.json') or
|
||||
not os.path.exists(DRAW_PATH + 'genshin_arms.json')):
|
||||
tasks.append(asyncio.ensure_future(update_genshin_info()))
|
||||
init_lst.remove(init_genshin_data)
|
||||
|
||||
if draw_config.AZUR_FLAG and not (DRAW_DATA_PATH / 'azur.json').exists():
|
||||
if AZUR_FLAG and not os.path.exists(DRAW_PATH + 'azur.json'):
|
||||
tasks.append(asyncio.ensure_future(update_azur_info()))
|
||||
init_lst.remove(init_azur_data)
|
||||
|
||||
if draw_config.FGO_FLAG and (not (DRAW_DATA_PATH / 'fgo.json').exists() or
|
||||
not (DRAW_DATA_PATH / 'fgo_card.json').exists()):
|
||||
if FGO_FLAG and (not os.path.exists(DRAW_PATH + 'fgo.json') or
|
||||
not os.path.exists(DRAW_PATH + 'fgo_card.json')):
|
||||
tasks.append(asyncio.ensure_future(update_fgo_info()))
|
||||
init_lst.remove(init_fgo_data)
|
||||
|
||||
if draw_config.ONMYOJI_FLAG and not (DRAW_DATA_PATH / 'onmyoji.json').exists():
|
||||
if ONMYOJI_FLAG and not os.path.exists(DRAW_PATH + 'onmyoji.json'):
|
||||
tasks.append(asyncio.ensure_future(update_onmyoji_info()))
|
||||
init_lst.remove(init_onmyoji_data)
|
||||
|
||||
try:
|
||||
await asyncio.gather(*tasks)
|
||||
for func in init_lst:
|
||||
await func()
|
||||
except asyncio.exceptions.CancelledError:
|
||||
logger.warning('更新异常:CancelledError,再次更新...')
|
||||
logger.info('更新异常:CancelledError,再次更新...')
|
||||
await async_update_game()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from nonebot.adapters.cqhttp import MessageSegment
|
||||
import random
|
||||
from .update_game_simple_info import update_simple_info
|
||||
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card, format_card_information
|
||||
from .config import draw_config, DRAW_DATA_PATH
|
||||
from .config import AZUR_ONE_P, AZUR_TWO_P, AZUR_THREE_P, AZUR_FOUR_P, AZUR_FLAG, DRAW_PATH
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
try:
|
||||
@@ -15,7 +16,7 @@ ALL_CHAR = []
|
||||
|
||||
@dataclass
|
||||
class AzurChar(BaseData):
|
||||
type_: str # 舰娘类型
|
||||
itype: str # 舰娘类型
|
||||
|
||||
|
||||
async def azur_draw(count: int, pool_name: str):
|
||||
@@ -41,22 +42,22 @@ async def update_azur_info():
|
||||
|
||||
async def init_azur_data():
|
||||
global ALL_CHAR
|
||||
if draw_config.AZUR_FLAG:
|
||||
with (DRAW_DATA_PATH / 'azur.json').open('r', encoding='utf8') as f:
|
||||
if AZUR_FLAG:
|
||||
with open(DRAW_PATH + 'azur.json', 'r', encoding='utf8') as f:
|
||||
azur_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('azur', azur_dict, AzurChar)
|
||||
|
||||
|
||||
# 抽取卡池
|
||||
def _get_azur_card(pool_name: str, mode: int = 1):
|
||||
def _get_azur_card(pool_name: str):
|
||||
global ALL_CHAR
|
||||
azur_config = draw_config.azur
|
||||
if pool_name == '轻型':
|
||||
type_ = ['驱逐', '轻巡', '维修']
|
||||
itype = ['驱逐', '轻巡', '维修']
|
||||
elif pool_name == '重型':
|
||||
type_ = ['重巡', '战列', '战巡', '重炮']
|
||||
itype = ['重巡', '战列', '战巡', '重炮']
|
||||
else:
|
||||
type_ = ['维修', '潜艇', '重巡', '轻航', '航母']
|
||||
star = get_star([4, 3, 2, 1], [azur_config.AZUR_FOUR_P, azur_config.AZUR_THREE_P, azur_config.AZUR_TWO_P, azur_config.AZUR_ONE_P])
|
||||
chars = [x for x in ALL_CHAR if x.star == star and x.type_ in type_ and not x.limited]
|
||||
itype = ['维修', '潜艇', '重巡', '轻航', '航母']
|
||||
star = get_star([4, 3, 2, 1], [AZUR_FOUR_P, AZUR_THREE_P, AZUR_TWO_P, AZUR_ONE_P])
|
||||
chars = [x for x in ALL_CHAR if x.star == star and x.itype in itype and not x.limited]
|
||||
return random.choice(chars), 4 - star
|
||||
|
||||
|
||||
+371
-123
@@ -1,7 +1,6 @@
|
||||
import nonebot
|
||||
from nonebot.log import logger
|
||||
from pydantic import BaseModel, Extra, ValidationError
|
||||
from configs.path_config import IMAGE_PATH, DATA_PATH
|
||||
from pathlib import Path
|
||||
from configs.path_config import DATA_PATH
|
||||
from configs.config import Config
|
||||
|
||||
try:
|
||||
@@ -10,111 +9,133 @@ except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
|
||||
# 原神
|
||||
class GenshinConfig(BaseModel, extra=Extra.ignore):
|
||||
GENSHIN_FIVE_P: float = 0.006
|
||||
GENSHIN_FOUR_P: float = 0.051
|
||||
GENSHIN_THREE_P: float = 0.43
|
||||
GENSHIN_G_FIVE_P: float = 0.13
|
||||
GENSHIN_G_FOUR_P: float = 0.016
|
||||
I72_ADD: float = 0.0585
|
||||
DRAW_PATH = DATA_PATH + "/draw_card/"
|
||||
|
||||
_draw_config = Path(rf"{DRAW_PATH}/draw_card_config/draw_card_config.json")
|
||||
|
||||
|
||||
# 明日方舟
|
||||
class PrtsConfig(BaseModel, extra=Extra.ignore):
|
||||
PRTS_SIX_P: float = 0.02
|
||||
PRTS_FIVE_P: float = 0.08
|
||||
PRTS_FOUR_P: float = 0.48
|
||||
PRTS_THREE_P: float = 0.42
|
||||
for game_flag, game_name in zip(
|
||||
[
|
||||
"PRTS_FLAG",
|
||||
"GENSHIN_FLAG",
|
||||
"PRETTY_FLAG",
|
||||
"GUARDIAN_FLAG",
|
||||
"PCR_FLAG",
|
||||
"AZUR_FLAG",
|
||||
"FGO_FLAG",
|
||||
"ONMYOJI_FLAG",
|
||||
"PCR_TAI",
|
||||
],
|
||||
["明日方舟", "原神", "赛马娘", "坎公骑冠剑", "公主连结", "碧蓝航线", "命运-冠位指定(FGO)", "阴阳师", "pcr台服卡池"],
|
||||
):
|
||||
Config.add_plugin_config(
|
||||
"draw_card",
|
||||
game_flag,
|
||||
True,
|
||||
name="游戏抽卡",
|
||||
help_=f"{game_name} 抽卡开关",
|
||||
default_value=True,
|
||||
)
|
||||
Config.add_plugin_config(
|
||||
"draw_card", "SEMAPHORE", 5, help_=f"异步数据下载数量限制", default_value=5
|
||||
)
|
||||
PRTS_FLAG = Config.get_config("draw_card", "PRTS_FLAG")
|
||||
GENSHIN_FLAG = Config.get_config("draw_card", "GENSHIN_FLAG")
|
||||
PRETTY_FLAG = Config.get_config("draw_card", "PRETTY_FLAG")
|
||||
GUARDIAN_FLAG = Config.get_config("draw_card", "GUARDIAN_FLAG")
|
||||
PCR_FLAG = Config.get_config("draw_card", "PCR_FLAG")
|
||||
AZUR_FLAG = Config.get_config("draw_card", "AZUR_FLAG")
|
||||
FGO_FLAG = Config.get_config("draw_card", "FGO_FLAG")
|
||||
ONMYOJI_FLAG = Config.get_config("draw_card", "ONMYOJI_FLAG")
|
||||
|
||||
PCR_TAI = Config.get_config("draw_card", "PCR_TAI")
|
||||
SEMAPHORE = Config.get_config("draw_card", "SEMAPHORE")
|
||||
|
||||
|
||||
# 赛马娘
|
||||
class PrettyConfig(BaseModel, extra=Extra.ignore):
|
||||
PRETTY_THREE_P: float = 0.03
|
||||
PRETTY_TWO_P: float = 0.18
|
||||
PRETTY_ONE_P: float = 0.79
|
||||
# 方舟概率
|
||||
PRTS_SIX_P = 0.02
|
||||
PRTS_FIVE_P = 0.08
|
||||
PRTS_FOUR_P = 0.48
|
||||
PRTS_THREE_P = 0.42
|
||||
|
||||
# 原神概率
|
||||
GENSHIN_FIVE_P = 0.006
|
||||
GENSHIN_FOUR_P = 0.051
|
||||
GENSHIN_THREE_P = 0.43
|
||||
# 保底概率
|
||||
GENSHIN_G_FIVE_P = 0.016
|
||||
GENSHIN_G_FOUR_P = 0.13
|
||||
# 72抽后增加的概率
|
||||
I72_ADD = 0.0585
|
||||
|
||||
# 赛马娘概率
|
||||
PRETTY_THREE_P = 0.03
|
||||
PRETTY_TWO_P = 0.18
|
||||
PRETTY_ONE_P = 0.79
|
||||
|
||||
# 坎公骑冠剑
|
||||
class GuardianConfig(BaseModel, extra=Extra.ignore):
|
||||
GUARDIAN_THREE_CHAR_P: float = 0.0275
|
||||
GUARDIAN_TWO_CHAR_P: float = 0.19
|
||||
GUARDIAN_ONE_CHAR_P: float = 0.7825
|
||||
GUARDIAN_THREE_CHAR_UP_P: float = 0.01375
|
||||
GUARDIAN_THREE_CHAR_OTHER_P: float = 0.01375
|
||||
GUARDIAN_EXCLUSIVE_ARMS_P: float = 0.03
|
||||
GUARDIAN_FIVE_ARMS_P: float = 0.03
|
||||
GUARDIAN_FOUR_ARMS_P: float = 0.09
|
||||
GUARDIAN_THREE_ARMS_P: float = 0.27
|
||||
GUARDIAN_TWO_ARMS_P: float = 0.58
|
||||
GUARDIAN_EXCLUSIVE_ARMS_UP_P: float = 0.01
|
||||
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P: float = 0.02
|
||||
|
||||
|
||||
# 公主连结
|
||||
class PcrConfig(BaseModel, extra=Extra.ignore):
|
||||
PCR_THREE_P: float = 0.025
|
||||
PCR_TWO_P: float = 0.18
|
||||
PCR_ONE_P: float = 0.795
|
||||
PCR_G_THREE_P: float = 0.025
|
||||
PCR_G_TWO_P: float = 0.975
|
||||
# 角色概率
|
||||
GUARDIAN_THREE_CHAR_P = 0.0275
|
||||
GUARDIAN_TWO_CHAR_P = 0.19
|
||||
GUARDIAN_ONE_CHAR_P = 0.7825
|
||||
# UP角色
|
||||
GUARDIAN_THREE_CHAR_UP_P = 0.01375
|
||||
GUARDIAN_THREE_CHAR_OTHER_P = 0.01375
|
||||
# 武器概率
|
||||
GUARDIAN_EXCLUSIVE_ARMS_P = 0.03
|
||||
GUARDIAN_FIVE_ARMS_P = 0.03
|
||||
GUARDIAN_FOUR_ARMS_P = 0.09
|
||||
GUARDIAN_THREE_ARMS_P = 0.27
|
||||
GUARDIAN_TWO_ARMS_P = 0.58
|
||||
# UP武器
|
||||
GUARDIAN_EXCLUSIVE_ARMS_UP_P = 0.01
|
||||
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P = 0.02
|
||||
|
||||
# PCR
|
||||
PCR_THREE_P = 0.025
|
||||
PCR_TWO_P = 0.18
|
||||
PCR_ONE_P = 0.795
|
||||
# 保底
|
||||
PCR_G_THREE_P = 0.025
|
||||
PCR_G_TWO_P = 0.975
|
||||
|
||||
# 碧蓝航线
|
||||
class AzurConfig(BaseModel, extra=Extra.ignore):
|
||||
AZUR_FIVE_P: float = 0.012
|
||||
AZUR_FOUR_P: float = 0.07
|
||||
AZUR_THREE_P: float = 0.12
|
||||
AZUR_TWO_P: float = 0.51
|
||||
AZUR_ONE_P: float = 0.3
|
||||
|
||||
|
||||
# 命运-冠位指定
|
||||
class FgoConfig(BaseModel, extra=Extra.ignore):
|
||||
FGO_SERVANT_FIVE_P: float = 0.01
|
||||
FGO_SERVANT_FOUR_P: float = 0.03
|
||||
FGO_SERVANT_THREE_P: float = 0.4
|
||||
FGO_CARD_FIVE_P: float = 0.04
|
||||
FGO_CARD_FOUR_P: float = 0.12
|
||||
FGO_CARD_THREE_P: float = 0.4
|
||||
AZUR_FIVE_P = 0.012
|
||||
AZUR_FOUR_P = 0.07
|
||||
AZUR_THREE_P = 0.12
|
||||
AZUR_TWO_P = 0.51
|
||||
AZUR_ONE_P = 0.3
|
||||
|
||||
# FGO
|
||||
FGO_SERVANT_FIVE_P = 0.01
|
||||
FGO_SERVANT_FOUR_P = 0.03
|
||||
FGO_SERVANT_THREE_P = 0.4
|
||||
FGO_CARD_FIVE_P = 0.04
|
||||
FGO_CARD_FOUR_P = 0.12
|
||||
FGO_CARD_THREE_P = 0.4
|
||||
|
||||
# 阴阳师
|
||||
class OnmyojiConfig(BaseModel, extra=Extra.ignore):
|
||||
ONMYOJI_SP: float = 0.0025
|
||||
ONMYOJI_SSR: float = 0.01
|
||||
ONMYOJI_SR: float = 0.2
|
||||
ONMYOJI_R: float = 0.7875
|
||||
ONMYOJI_SP = 0.0025
|
||||
ONMYOJI_SSR = 0.01
|
||||
ONMYOJI_SR = 0.2
|
||||
ONMYOJI_R = 0.7875
|
||||
|
||||
|
||||
class PathDict(BaseModel, extra=Extra.ignore):
|
||||
genshin: str = "原神"
|
||||
prts: str = "明日方舟"
|
||||
pretty: str = "赛马娘"
|
||||
guardian: str = "坎公骑冠剑"
|
||||
pcr: str = "公主连结"
|
||||
azur: str = "碧蓝航线"
|
||||
fgo: str = "命运-冠位指定"
|
||||
onmyoji: str = "阴阳师"
|
||||
path_dict = {
|
||||
"genshin": "原神",
|
||||
"prts": "明日方舟",
|
||||
"pretty": "赛马娘",
|
||||
"guardian": "坎公骑冠剑",
|
||||
"pcr": "公主连结",
|
||||
"azur": "碧蓝航线",
|
||||
"fgo": "命运-冠位指定",
|
||||
"onmyoji": "阴阳师",
|
||||
}
|
||||
|
||||
driver: nonebot.Driver = nonebot.get_driver()
|
||||
|
||||
class DrawConfig(BaseModel, extra=Extra.ignore):
|
||||
# 开关
|
||||
PRTS_FLAG: bool = Config.get_config("draw_card", "PRTS_FLAG")
|
||||
GENSHIN_FLAG: bool = Config.get_config("draw_card", "GENSHIN_FLAG")
|
||||
PRETTY_FLAG: bool = Config.get_config("draw_card", "PRETTY_FLAG")
|
||||
GUARDIAN_FLAG: bool = Config.get_config("draw_card", "GUARDIAN_FLAG")
|
||||
PCR_FLAG: bool = Config.get_config("draw_card", "PCR_FLAG")
|
||||
AZUR_FLAG: bool = Config.get_config("draw_card", "AZUR_FLAG")
|
||||
FGO_FLAG: bool = Config.get_config("draw_card", "FGO_FLAG")
|
||||
ONMYOJI_FLAG: bool = Config.get_config("draw_card", "ONMYOJI_FLAG")
|
||||
|
||||
# 其他配置
|
||||
PCR_TAI: bool = Config.get_config("draw_card", "PCR_TAI")
|
||||
SEMAPHORE: int = Config.get_config("draw_card", "SEMAPHORE")
|
||||
|
||||
# 路径
|
||||
path_dict: dict = {
|
||||
config_default_data = {
|
||||
"path_dict": {
|
||||
"genshin": "原神",
|
||||
"prts": "明日方舟",
|
||||
"pretty": "赛马娘",
|
||||
@@ -123,41 +144,268 @@ class DrawConfig(BaseModel, extra=Extra.ignore):
|
||||
"azur": "碧蓝航线",
|
||||
"fgo": "命运-冠位指定",
|
||||
"onmyoji": "阴阳师",
|
||||
}
|
||||
|
||||
# 抽卡概率
|
||||
prts: PrtsConfig = PrtsConfig()
|
||||
genshin: GenshinConfig = GenshinConfig()
|
||||
pretty: PrettyConfig = PrettyConfig()
|
||||
guardian: GuardianConfig = GuardianConfig()
|
||||
pcr: PcrConfig = PcrConfig()
|
||||
azur: AzurConfig = AzurConfig()
|
||||
fgo: FgoConfig = FgoConfig()
|
||||
onmyoji: OnmyojiConfig = OnmyojiConfig()
|
||||
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
global_config = driver.config
|
||||
DRAW_DATA_PATH = DATA_PATH / "draw_card"
|
||||
DRAW_IMAGE_PATH = IMAGE_PATH / "draw_card"
|
||||
# DRAW_PATH = Path(draw_path) if draw_path else Path("data/draw_card").absolute()
|
||||
config_path = DRAW_DATA_PATH / "draw_card_config" / "draw_card_config.json"
|
||||
|
||||
draw_config: Config = DrawConfig()
|
||||
},
|
||||
"prts": {
|
||||
"PRTS_SIX_P": 0.02,
|
||||
"PRTS_FIVE_P": 0.08,
|
||||
"PRTS_FOUR_P": 0.48,
|
||||
"PRTS_THREE_P": 0.42,
|
||||
},
|
||||
"genshin": {
|
||||
"GENSHIN_FIVE_P": 0.006,
|
||||
"GENSHIN_FOUR_P": 0.051,
|
||||
"GENSHIN_THREE_P": 0.43,
|
||||
"GENSHIN_G_FIVE_P": 0.13,
|
||||
"GENSHIN_G_FOUR_P": 0.016,
|
||||
"I72_ADD": 0.0585,
|
||||
},
|
||||
"pretty": {
|
||||
"PRETTY_THREE_P": 0.03,
|
||||
"PRETTY_TWO_P": 0.18,
|
||||
"PRETTY_ONE_P": 0.79,
|
||||
},
|
||||
"guardian": {
|
||||
"GUARDIAN_THREE_CHAR_P": 0.0275,
|
||||
"GUARDIAN_TWO_CHAR_P": 0.19,
|
||||
"GUARDIAN_ONE_CHAR_P": 0.7825,
|
||||
"GUARDIAN_THREE_CHAR_UP_P": 0.01375,
|
||||
"GUARDIAN_THREE_CHAR_OTHER_P": 0.01375,
|
||||
"GUARDIAN_EXCLUSIVE_ARMS_P": 0.03,
|
||||
"GUARDIAN_FIVE_ARMS_P": 0.03,
|
||||
"GUARDIAN_FOUR_ARMS_P": 0.09,
|
||||
"GUARDIAN_THREE_ARMS_P": 0.27,
|
||||
"GUARDIAN_TWO_ARMS_P": 0.58,
|
||||
"GUARDIAN_EXCLUSIVE_ARMS_UP_P": 0.01,
|
||||
"GUARDIAN_EXCLUSIVE_ARMS_OTHER_P": 0.02,
|
||||
},
|
||||
"pcr": {
|
||||
"PCR_THREE_P": 0.025,
|
||||
"PCR_TWO_P": 0.18,
|
||||
"PCR_ONE_P": 0.795,
|
||||
},
|
||||
"azur": {
|
||||
"AZUR_FIVE_P": 0.012,
|
||||
"AZUR_FOUR_P": 0.07,
|
||||
"AZUR_THREE_P": 0.12,
|
||||
"AZUR_TWO_P": 0.51,
|
||||
"AZUR_ONE_P": 0.3,
|
||||
},
|
||||
"fgo": {
|
||||
"FGO_SERVANT_FIVE_P": 0.01,
|
||||
"FGO_SERVANT_FOUR_P": 0.03,
|
||||
"FGO_SERVANT_THREE_P": 0.4,
|
||||
"FGO_CARD_FIVE_P": 0.04,
|
||||
"FGO_CARD_FOUR_P": 0.12,
|
||||
"FGO_CARD_THREE_P": 0.4,
|
||||
},
|
||||
"onmyoji": {
|
||||
"ONMYOJI_SP": 0.0025,
|
||||
"ONMYOJI_SSR": 0.01,
|
||||
"ONMYOJI_SR": 0.2,
|
||||
"ONMYOJI_R": 0.7875,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
def check_config():
|
||||
global draw_config
|
||||
global PRTS_SIX_P, PRTS_FOUR_P, PRTS_FIVE_P, PRTS_THREE_P, GENSHIN_G_FIVE_P, config_default_data, GENSHIN_G_FOUR_P, GENSHIN_FOUR_P, GENSHIN_FIVE_P, I72_ADD, path_dict, PRETTY_THREE_P, PRETTY_ONE_P, PRETTY_TWO_P, GENSHIN_THREE_P, GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_ONE_CHAR_P, GUARDIAN_THREE_CHAR_UP_P, GUARDIAN_THREE_CHAR_OTHER_P, GUARDIAN_EXCLUSIVE_ARMS_P, GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P, GUARDIAN_THREE_ARMS_P, GUARDIAN_TWO_ARMS_P, GENSHIN_FLAG, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, GUARDIAN_EXCLUSIVE_ARMS_UP_P, GUARDIAN_EXCLUSIVE_ARMS_OTHER_P, DRAW_PATH, PCR_THREE_P, PCR_TWO_P, PCR_ONE_P, AZUR_FOUR_P, AZUR_THREE_P, AZUR_TWO_P, AZUR_ONE_P, AZUR_FIVE_P, FGO_CARD_FIVE_P, FGO_CARD_FOUR_P, FGO_CARD_THREE_P, FGO_SERVANT_THREE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_FIVE_P, ONMYOJI_R, ONMYOJI_SP, ONMYOJI_SSR, ONMYOJI_SR
|
||||
_draw_config.parent.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
data = json.load(open(_draw_config, "r", encoding="utf8"))
|
||||
except (FileNotFoundError, ValueError):
|
||||
_draw_config.parent.mkdir(parents=True, exist_ok=True)
|
||||
json.dump(
|
||||
config_default_data,
|
||||
open(_draw_config, "w", encoding="utf8"),
|
||||
indent=4,
|
||||
ensure_ascii=False,
|
||||
)
|
||||
print("draw_card:配置文件不存在或格式错误,已重新生成配置文件.....")
|
||||
else:
|
||||
|
||||
if not config_path.exists():
|
||||
config_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
draw_config = DrawConfig()
|
||||
logger.warning("draw_card:配置文件不存在,已重新生成配置文件.....")
|
||||
try:
|
||||
PRTS_SIX_P = float(data["prts"]["PRTS_SIX_P"])
|
||||
PRTS_FIVE_P = float(data["prts"]["PRTS_FIVE_P"])
|
||||
PRTS_FOUR_P = float(data["prts"]["PRTS_FOUR_P"])
|
||||
PRTS_THREE_P = float(data["prts"]["PRTS_THREE_P"])
|
||||
except KeyError:
|
||||
data["prts"] = {}
|
||||
data["prts"]["PRTS_SIX_P"] = config_default_data["prts"]["PRTS_SIX_P"]
|
||||
data["prts"]["PRTS_FIVE_P"] = config_default_data["prts"]["PRTS_FIVE_P"]
|
||||
data["prts"]["PRTS_FOUR_P"] = config_default_data["prts"]["PRTS_FOUR_P"]
|
||||
data["prts"]["PRTS_THREE_P"] = config_default_data["prts"]["PRTS_THREE_P"]
|
||||
|
||||
json.dump(
|
||||
draw_config.dict(),
|
||||
config_path.open("w", encoding="utf8"),
|
||||
indent=4,
|
||||
ensure_ascii=False,
|
||||
)
|
||||
try:
|
||||
GENSHIN_FIVE_P = float(data["genshin"]["GENSHIN_FIVE_P"])
|
||||
GENSHIN_FOUR_P = float(data["genshin"]["GENSHIN_FOUR_P"])
|
||||
GENSHIN_THREE_P = float(data["genshin"]["GENSHIN_THREE_P"])
|
||||
GENSHIN_G_FIVE_P = float(data["genshin"]["GENSHIN_G_FIVE_P"])
|
||||
GENSHIN_G_FOUR_P = float(data["genshin"]["GENSHIN_G_FOUR_P"])
|
||||
I72_ADD = float(data["genshin"]["I72_ADD"])
|
||||
except KeyError:
|
||||
data["genshin"] = {}
|
||||
data["genshin"]["GENSHIN_FIVE_P"] = config_default_data["genshin"][
|
||||
"GENSHIN_FIVE_P"
|
||||
]
|
||||
data["genshin"]["GENSHIN_FOUR_P"] = config_default_data["genshin"][
|
||||
"GENSHIN_FOUR_P"
|
||||
]
|
||||
data["genshin"]["GENSHIN_THREE_P"] = config_default_data["genshin"][
|
||||
"GENSHIN_THREE_P"
|
||||
]
|
||||
data["genshin"]["GENSHIN_G_FIVE_P"] = config_default_data["genshin"][
|
||||
"GENSHIN_G_FIVE_P"
|
||||
]
|
||||
data["genshin"]["GENSHIN_G_FOUR_P"] = config_default_data["genshin"][
|
||||
"GENSHIN_G_FOUR_P"
|
||||
]
|
||||
data["genshin"]["I72_ADD"] = config_default_data["genshin"]["I72_ADD"]
|
||||
|
||||
try:
|
||||
PRETTY_THREE_P = float(data["pretty"]["PRETTY_THREE_P"])
|
||||
PRETTY_TWO_P = float(data["pretty"]["PRETTY_TWO_P"])
|
||||
PRETTY_ONE_P = float(data["pretty"]["PRETTY_ONE_P"])
|
||||
except KeyError:
|
||||
data["pretty"] = {}
|
||||
data["pretty"]["PRETTY_THREE_P"] = config_default_data["pretty"][
|
||||
"PRETTY_THREE_P"
|
||||
]
|
||||
data["pretty"]["PRETTY_TWO_P"] = config_default_data["pretty"][
|
||||
"PRETTY_TWO_P"
|
||||
]
|
||||
data["pretty"]["PRETTY_ONE_P"] = config_default_data["pretty"][
|
||||
"PRETTY_ONE_P"
|
||||
]
|
||||
|
||||
try:
|
||||
GUARDIAN_THREE_CHAR_P = float(data["guardian"]["GUARDIAN_THREE_CHAR_P"])
|
||||
GUARDIAN_TWO_CHAR_P = float(data["guardian"]["GUARDIAN_TWO_CHAR_P"])
|
||||
GUARDIAN_ONE_CHAR_P = float(data["guardian"]["GUARDIAN_ONE_CHAR_P"])
|
||||
GUARDIAN_THREE_CHAR_UP_P = float(
|
||||
data["guardian"]["GUARDIAN_THREE_CHAR_UP_P"]
|
||||
)
|
||||
GUARDIAN_THREE_CHAR_OTHER_P = float(
|
||||
data["guardian"]["GUARDIAN_THREE_CHAR_OTHER_P"]
|
||||
)
|
||||
GUARDIAN_EXCLUSIVE_ARMS_P = float(
|
||||
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_P"]
|
||||
)
|
||||
GUARDIAN_FIVE_ARMS_P = float(data["guardian"]["GUARDIAN_FIVE_ARMS_P"])
|
||||
GUARDIAN_FOUR_ARMS_P = float(data["guardian"]["GUARDIAN_FOUR_ARMS_P"])
|
||||
GUARDIAN_THREE_ARMS_P = float(data["guardian"]["GUARDIAN_THREE_ARMS_P"])
|
||||
GUARDIAN_TWO_ARMS_P = float(data["guardian"]["GUARDIAN_TWO_ARMS_P"])
|
||||
GUARDIAN_EXCLUSIVE_ARMS_UP_P = float(
|
||||
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_UP_P"]
|
||||
)
|
||||
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P = float(
|
||||
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_OTHER_P"]
|
||||
)
|
||||
except KeyError:
|
||||
data["guardian"] = {}
|
||||
data["guardian"]["GUARDIAN_THREE_CHAR_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_THREE_CHAR_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_TWO_CHAR_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_TWO_CHAR_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_ONE_CHAR_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_ONE_CHAR_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_THREE_CHAR_UP_P"] = config_default_data[
|
||||
"guardian"
|
||||
]["GUARDIAN_THREE_CHAR_UP_P"]
|
||||
data["guardian"]["GUARDIAN_THREE_CHAR_OTHER_P"] = config_default_data[
|
||||
"guardian"
|
||||
]["GUARDIAN_THREE_CHAR_OTHER_P"]
|
||||
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_P"] = config_default_data[
|
||||
"guardian"
|
||||
]["GUARDIAN_EXCLUSIVE_ARMS_P"]
|
||||
data["guardian"]["GUARDIAN_FIVE_ARMS_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_FIVE_ARMS_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_FOUR_ARMS_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_FOUR_ARMS_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_THREE_ARMS_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_THREE_ARMS_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_TWO_ARMS_P"] = config_default_data["guardian"][
|
||||
"GUARDIAN_TWO_ARMS_P"
|
||||
]
|
||||
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_UP_P"] = config_default_data[
|
||||
"guardian"
|
||||
]["GUARDIAN_EXCLUSIVE_ARMS_UP_P"]
|
||||
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_OTHER_P"] = config_default_data[
|
||||
"guardian"
|
||||
]["GUARDIAN_EXCLUSIVE_ARMS_OTHER_P"]
|
||||
|
||||
try:
|
||||
PCR_THREE_P = float(data["pcr"]["PCR_THREE_P"])
|
||||
PCR_TWO_P = float(data["pcr"]["PCR_TWO_P"])
|
||||
PCR_ONE_P = float(data["pcr"]["PCR_ONE_P"])
|
||||
except KeyError:
|
||||
data["pcr"] = {}
|
||||
data["pcr"]["PCR_THREE_P"] = config_default_data["pcr"]["PCR_THREE_P"]
|
||||
data["pcr"]["PCR_TWO_P"] = config_default_data["pcr"]["PCR_TWO_P"]
|
||||
data["pcr"]["PCR_ONE_P"] = config_default_data["pcr"]["PCR_ONE_P"]
|
||||
|
||||
try:
|
||||
AZUR_FIVE_P = float(data["azur"]["AZUR_FIVE_P"])
|
||||
AZUR_FOUR_P = float(data["azur"]["AZUR_FOUR_P"])
|
||||
AZUR_THREE_P = float(data["azur"]["AZUR_THREE_P"])
|
||||
AZUR_TWO_P = float(data["azur"]["AZUR_TWO_P"])
|
||||
AZUR_ONE_P = float(data["azur"]["AZUR_ONE_P"])
|
||||
except KeyError:
|
||||
data["azur"] = {}
|
||||
data["azur"]["AZUR_FIVE_P"] = config_default_data["azur"]["AZUR_FIVE_P"]
|
||||
data["azur"]["AZUR_FOUR_P"] = config_default_data["azur"]["AZUR_FOUR_P"]
|
||||
data["azur"]["AZUR_THREE_P"] = config_default_data["azur"]["AZUR_THREE_P"]
|
||||
data["azur"]["AZUR_TWO_P"] = config_default_data["azur"]["AZUR_TWO_P"]
|
||||
data["azur"]["AZUR_ONE_P"] = config_default_data["azur"]["AZUR_ONE_P"]
|
||||
|
||||
try:
|
||||
FGO_SERVANT_FIVE_P = float(data["fgo"]["FGO_SERVANT_FIVE_P"])
|
||||
FGO_SERVANT_FOUR_P = float(data["fgo"]["FGO_SERVANT_FOUR_P"])
|
||||
FGO_SERVANT_THREE_P = float(data["fgo"]["FGO_SERVANT_THREE_P"])
|
||||
FGO_CARD_FIVE_P = float(data["fgo"]["FGO_CARD_FIVE_P"])
|
||||
FGO_CARD_FOUR_P = float(data["fgo"]["FGO_CARD_FOUR_P"])
|
||||
FGO_CARD_THREE_P = float(data["fgo"]["FGO_CARD_THREE_P"])
|
||||
except KeyError:
|
||||
data["fgo"] = {}
|
||||
data["fgo"]["FGO_SERVANT_FIVE_P"] = config_default_data["fgo"][
|
||||
"FGO_SERVANT_FIVE_P"
|
||||
]
|
||||
data["fgo"]["FGO_SERVANT_FOUR_P"] = config_default_data["fgo"][
|
||||
"FGO_SERVANT_FOUR_P"
|
||||
]
|
||||
data["fgo"]["FGO_SERVANT_THREE_P"] = config_default_data["fgo"][
|
||||
"FGO_SERVANT_THREE_P"
|
||||
]
|
||||
data["fgo"]["FGO_CARD_FIVE_P"] = config_default_data["fgo"][
|
||||
"FGO_CARD_FIVE_P"
|
||||
]
|
||||
data["fgo"]["FGO_CARD_FOUR_P"] = config_default_data["fgo"][
|
||||
"FGO_CARD_FOUR_P"
|
||||
]
|
||||
data["fgo"]["FGO_CARD_THREE_P"] = config_default_data["fgo"][
|
||||
"FGO_CARD_THREE_P"
|
||||
]
|
||||
|
||||
try:
|
||||
ONMYOJI_SP = float(data["onmyoji"]["ONMYOJI_SP"])
|
||||
ONMYOJI_SSR = float(data["onmyoji"]["ONMYOJI_SSR"])
|
||||
ONMYOJI_SR = float(data["onmyoji"]["ONMYOJI_SR"])
|
||||
ONMYOJI_R = float(data["onmyoji"]["ONMYOJI_R"])
|
||||
except KeyError:
|
||||
data["onmyoji"] = {}
|
||||
data["onmyoji"]["ONMYOJI_SP"] = config_default_data["onmyoji"]["ONMYOJI_SP"]
|
||||
data["onmyoji"]["ONMYOJI_SSR"] = config_default_data["onmyoji"][
|
||||
"ONMYOJI_SSR"
|
||||
]
|
||||
data["onmyoji"]["ONMYOJI_SR"] = config_default_data["onmyoji"]["ONMYOJI_SR"]
|
||||
data["onmyoji"]["ONMYOJI_R"] = config_default_data["onmyoji"]["ONMYOJI_R"]
|
||||
|
||||
json.dump(
|
||||
data, open(_draw_config, "w", encoding="utf8"), indent=4, ensure_ascii=False
|
||||
)
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
from typing import Optional, Union
|
||||
|
||||
|
||||
class DrawCountManager:
|
||||
"""
|
||||
抽卡统计保底
|
||||
"""
|
||||
|
||||
def __init__(self, game_draw_count_rule: tuple, star2name: tuple):
|
||||
"""
|
||||
初始化保底统计
|
||||
|
||||
例如:DrawCountManager((10, 90, 180), ("4", "5", "5"))
|
||||
|
||||
抽卡保底需要的次数和返回的对应名称,例如星级等
|
||||
|
||||
"""
|
||||
# 只有保底
|
||||
self._data = {}
|
||||
self._guarantee_tuple = game_draw_count_rule
|
||||
self._star2name = star2name
|
||||
|
||||
def increase(self, key: int, value: int = 1):
|
||||
"""
|
||||
用户抽卡次数加1
|
||||
"""
|
||||
if self._data.get(key) is None:
|
||||
self._data[key] = {
|
||||
"count": value,
|
||||
}
|
||||
for x in range(len(self._guarantee_tuple)):
|
||||
self._data[key][f"count_{x}"] = 0
|
||||
else:
|
||||
self._data[key][f"count"] += value
|
||||
if self._data[key][f"count"] > self._guarantee_tuple[-1]:
|
||||
self._data[key][f"count"] = self._data[key][f"count"] % self._guarantee_tuple[-1]
|
||||
|
||||
def reset(self, key: int):
|
||||
"""
|
||||
清空记录
|
||||
"""
|
||||
del self._data[key]
|
||||
|
||||
def set_count(self, key: int, type_: int, count: int):
|
||||
if self._data.get(key):
|
||||
self._data[key][f"count_{type_}"] = count
|
||||
|
||||
def check(self, key: int, *args) -> Optional[Union[str, int]]:
|
||||
"""
|
||||
是否保底
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_user_count(self, key: int, type_: Optional[int] = None) -> int:
|
||||
"""
|
||||
获取用户当前抽卡次数
|
||||
"""
|
||||
if self._data.get(key):
|
||||
if type_ is None:
|
||||
return self._data[key]["count"]
|
||||
return self._data[key][f"count_{type_}"]
|
||||
return 0
|
||||
|
||||
def record_count(self, key: int, type_: int):
|
||||
"""
|
||||
抽出对应星级后记录当前次数
|
||||
"""
|
||||
if self._data.get(key):
|
||||
self._data[key][f"count_{type_}"] = self._data[key]["count"]
|
||||
|
||||
|
||||
class GenshinCountManager(DrawCountManager):
|
||||
|
||||
def increase(self, key: int, value: int = 1):
|
||||
"""
|
||||
用户抽卡次数加1
|
||||
"""
|
||||
if self._data.get(key) is None:
|
||||
self._data[key] = {
|
||||
"is_up": False,
|
||||
"count": value,
|
||||
}
|
||||
for x in range(len(self._guarantee_tuple)):
|
||||
self._data[key][f"count_{x}"] = 0
|
||||
else:
|
||||
self._data[key][f"count"] += value
|
||||
if self._data[key][f"count"] > self._guarantee_tuple[-1]:
|
||||
self._data[key][f"count"] = self._data[key][f"count"] % 180
|
||||
|
||||
def set_is_up(self, key: int, value: bool):
|
||||
if self._data.get(key):
|
||||
self._data[key]["is_up"] = value
|
||||
|
||||
def is_up(self, key: int) -> bool:
|
||||
if self._data.get(key):
|
||||
return self._data[key]["is_up"]
|
||||
return False
|
||||
|
||||
def check(self, key: int, *args) -> Optional[Union[str, int]]:
|
||||
"""
|
||||
是否保底
|
||||
"""
|
||||
# print(self._data)
|
||||
if self._data.get(key):
|
||||
for i in [1, 0]:
|
||||
count = self._data[key]["count"]
|
||||
if count - self._data[key][f"count_{i}"] == self._guarantee_tuple[i]:
|
||||
if i in [2, 1]:
|
||||
# print("clean four count")
|
||||
self._data[key][f"count_0"] = self._data[key]['count']
|
||||
self._data[key][f"count_{i}"] = self._data[key]['count']
|
||||
return self._star2name[i]
|
||||
return None
|
||||
@@ -1,8 +1,10 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from nonebot.adapters.cqhttp import MessageSegment
|
||||
import random
|
||||
from .update_game_requests_info import update_requests_info
|
||||
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .config import FGO_CARD_FOUR_P, FGO_CARD_FIVE_P, FGO_CARD_THREE_P, FGO_SERVANT_THREE_P, \
|
||||
FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_FLAG, DRAW_PATH
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
|
||||
@@ -43,11 +45,11 @@ async def update_fgo_info():
|
||||
|
||||
async def init_fgo_data():
|
||||
global ALL_CHAR, ALL_CARD
|
||||
if draw_config.FGO_FLAG:
|
||||
with (DRAW_DATA_PATH / 'fgo.json').open('r', encoding='utf8') as f:
|
||||
if FGO_FLAG:
|
||||
with open(DRAW_PATH + 'fgo.json', 'r', encoding='utf8') as f:
|
||||
fgo_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('fgo', fgo_dict, FgoChar)
|
||||
with (DRAW_DATA_PATH / 'fgo_card.json').open('r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + 'fgo_card.json', 'r', encoding='utf8') as f:
|
||||
fgo_dict = json.load(f)
|
||||
ALL_CARD = init_game_pool('fgo', fgo_dict, FgoChar)
|
||||
|
||||
@@ -55,22 +57,21 @@ async def init_fgo_data():
|
||||
# 抽取卡池
|
||||
def _get_fgo_card(mode: int = 1):
|
||||
global ALL_CHAR, ALL_CARD
|
||||
fgo_config = draw_config.fgo
|
||||
if mode == 1:
|
||||
star = get_star([8, 7, 6, 5, 4, 3], [fgo_config.FGO_SERVANT_FIVE_P, fgo_config.FGO_SERVANT_FOUR_P, fgo_config.FGO_SERVANT_THREE_P,
|
||||
fgo_config.FGO_CARD_FIVE_P, fgo_config.FGO_CARD_FOUR_P, fgo_config.FGO_CARD_THREE_P])
|
||||
star = get_star([8, 7, 6, 5, 4, 3], [FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_THREE_P,
|
||||
FGO_CARD_FIVE_P, FGO_CARD_FOUR_P, FGO_CARD_THREE_P])
|
||||
elif mode == 2:
|
||||
star = get_star([5, 4], [fgo_config.FGO_CARD_FIVE_P, fgo_config.FGO_CARD_FOUR_P])
|
||||
star = get_star([5, 4], [FGO_CARD_FIVE_P, FGO_CARD_FOUR_P])
|
||||
else:
|
||||
star = get_star([8, 7, 6], [fgo_config.FGO_SERVANT_FIVE_P, fgo_config.FGO_SERVANT_FOUR_P, fgo_config.FGO_SERVANT_THREE_P])
|
||||
star = get_star([8, 7, 6], [FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_THREE_P])
|
||||
if star > 5:
|
||||
type_ = 'servant'
|
||||
itype = 'servant'
|
||||
star -= 3
|
||||
chars = [x for x in ALL_CHAR if x.star == star if not x.limited]
|
||||
else:
|
||||
type_ = 'card'
|
||||
itype = 'card'
|
||||
chars = [x for x in ALL_CARD if x.star == star if not x.limited]
|
||||
return random.choice(chars), 5 - star, type_
|
||||
return random.choice(chars), 5 - star, itype
|
||||
|
||||
|
||||
# 整理数据
|
||||
@@ -87,18 +88,18 @@ def _format_card_information(count: int):
|
||||
card_count += 1
|
||||
# 四星卡片保底
|
||||
if card_count == 9:
|
||||
obj, code, type_ = _get_fgo_card(2)
|
||||
obj, code, itype = _get_fgo_card(2)
|
||||
# 三星从者保底
|
||||
elif servant_count == 10:
|
||||
obj, code, type_ = _get_fgo_card(3)
|
||||
obj, code, itype = _get_fgo_card(3)
|
||||
_count = 0
|
||||
# 普通抽
|
||||
else:
|
||||
obj, code, type_ = _get_fgo_card()
|
||||
obj, code, itype = _get_fgo_card()
|
||||
star_list[code] += 1
|
||||
if type_ == 'card' and code < 2:
|
||||
if itype == 'card' and code < 2:
|
||||
card_count = 0
|
||||
if type_ == 'servant':
|
||||
if itype == 'servant':
|
||||
servant_count = 0
|
||||
if code == 0:
|
||||
max_star_lst.append(obj.name)
|
||||
|
||||
+110
-188
@@ -1,16 +1,10 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, Message
|
||||
import os
|
||||
from nonebot.adapters.cqhttp import MessageSegment, Message
|
||||
import random
|
||||
from .update_game_info import update_info
|
||||
from .util import (
|
||||
generate_img,
|
||||
init_rst,
|
||||
BaseData,
|
||||
set_list,
|
||||
get_star,
|
||||
init_up_char,
|
||||
)
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .count_manager import GenshinCountManager
|
||||
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, init_up_char
|
||||
from .config import GENSHIN_FIVE_P, GENSHIN_FOUR_P, GENSHIN_G_FIVE_P, GENSHIN_G_FOUR_P, GENSHIN_THREE_P, I72_ADD, \
|
||||
DRAW_PATH, GENSHIN_FLAG
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
from .announcement import GenshinAnnouncement
|
||||
@@ -23,11 +17,9 @@ except ModuleNotFoundError:
|
||||
|
||||
announcement = GenshinAnnouncement()
|
||||
|
||||
draw_count_manager = GenshinCountManager((10, 90), ("4", "5"))
|
||||
|
||||
# genshin_five = {}
|
||||
# genshin_count = {}
|
||||
# genshin_pl_count = {}
|
||||
genshin_five = {}
|
||||
genshin_count = {}
|
||||
genshin_pl_count = {}
|
||||
|
||||
ALL_CHAR = []
|
||||
ALL_ARMS = []
|
||||
@@ -35,10 +27,9 @@ ALL_ARMS = []
|
||||
UP_CHAR = []
|
||||
UP_ARMS = []
|
||||
|
||||
|
||||
_CURRENT_CHAR_POOL_TITLE = ""
|
||||
_CURRENT_ARMS_POOL_TITLE = ""
|
||||
POOL_IMG = ""
|
||||
_CURRENT_CHAR_POOL_TITLE = ''
|
||||
_CURRENT_ARMS_POOL_TITLE = ''
|
||||
POOL_IMG = ''
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -48,22 +39,19 @@ class GenshinChar(BaseData):
|
||||
|
||||
async def genshin_draw(user_id: int, count: int, pool_name: str):
|
||||
# 0 1 2
|
||||
star = ["★★★★★", "★★★★", "★★★"]
|
||||
(
|
||||
char_list,
|
||||
five_dict,
|
||||
star_num_list,
|
||||
) = _format_card_information(count, user_id, pool_name)
|
||||
title = ""
|
||||
cnlist = ['★★★★★', '★★★★', '★★★']
|
||||
char_list, five_list, five_index_list, char_dict, star_list = _format_card_information(count, user_id, pool_name)
|
||||
temp = ''
|
||||
title = ''
|
||||
up_type = []
|
||||
up_list = []
|
||||
if pool_name == "char" and _CURRENT_CHAR_POOL_TITLE:
|
||||
if pool_name == 'char' and _CURRENT_CHAR_POOL_TITLE:
|
||||
up_type = UP_CHAR
|
||||
title = _CURRENT_CHAR_POOL_TITLE
|
||||
elif pool_name == "arms" and _CURRENT_ARMS_POOL_TITLE:
|
||||
elif pool_name == 'arms' and _CURRENT_ARMS_POOL_TITLE:
|
||||
up_type = UP_ARMS
|
||||
title = _CURRENT_ARMS_POOL_TITLE
|
||||
tmp = ""
|
||||
tmp = ''
|
||||
if up_type:
|
||||
for x in up_type:
|
||||
for operator in x.operators:
|
||||
@@ -72,217 +60,151 @@ async def genshin_draw(user_id: int, count: int, pool_name: str):
|
||||
tmp += f'五星UP:{" ".join(x.operators)} \n'
|
||||
elif x.star == 4:
|
||||
tmp += f'四星UP:{" ".join(x.operators)}'
|
||||
rst = init_rst(five_dict, star_num_list, star, up_list)
|
||||
pool_info = f"当前up池:{title}\n{tmp}" if title else ""
|
||||
rst = init_star_rst(star_list, cnlist, five_list, five_index_list, up_list)
|
||||
pool_info = f'当前up池:{title}\n{tmp}' if title else ''
|
||||
if count > 90:
|
||||
char_list = set_list(char_list)
|
||||
return (
|
||||
pool_info
|
||||
+ "\n"
|
||||
+ MessageSegment.image(
|
||||
"base64://" + await generate_img(char_list, "genshin", star_num_list)
|
||||
)
|
||||
+ rst
|
||||
+ f'\n距离保底发还剩 {draw_count_manager.get_user_count(user_id, 1) % 90} 抽'
|
||||
+ "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】"
|
||||
)
|
||||
return pool_info + '\n' + MessageSegment.image(
|
||||
"base64://" + await generate_img(char_list, 'genshin', star_list)) + '\n' + rst[:-1] + \
|
||||
temp[:-1] + f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"} 抽' \
|
||||
+ "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】"
|
||||
|
||||
|
||||
async def update_genshin_info():
|
||||
global ALL_CHAR, ALL_ARMS
|
||||
url = "https://wiki.biligame.com/ys/角色筛选"
|
||||
data, code = await update_info(url, "genshin")
|
||||
url = 'https://wiki.biligame.com/ys/角色筛选'
|
||||
data, code = await update_info(url, 'genshin')
|
||||
if code == 200:
|
||||
ALL_CHAR = init_game_pool("genshin", data, GenshinChar)
|
||||
url = "https://wiki.biligame.com/ys/武器图鉴"
|
||||
data, code = await update_info(
|
||||
url,
|
||||
"genshin_arms",
|
||||
)
|
||||
ALL_CHAR = init_game_pool('genshin', data, GenshinChar)
|
||||
url = 'https://wiki.biligame.com/ys/武器图鉴'
|
||||
data, code = await update_info(url, 'genshin_arms', ['头像', '名称', '类型', '稀有度.alt',
|
||||
'获取途径', '初始基础属性1', '初始基础属性2',
|
||||
'攻击力(MAX)', '副属性(MAX)', '技能'])
|
||||
if code == 200:
|
||||
ALL_ARMS = init_game_pool("genshin_arms", data, GenshinChar)
|
||||
ALL_ARMS = init_game_pool('genshin_arms', data, GenshinChar)
|
||||
await _genshin_init_up_char()
|
||||
|
||||
|
||||
async def init_genshin_data():
|
||||
global ALL_CHAR, ALL_ARMS
|
||||
if draw_config.GENSHIN_FLAG:
|
||||
if not (DRAW_DATA_PATH / "genshin.json").exists() or not (DRAW_DATA_PATH / "genshin_arms.json").exists():
|
||||
if GENSHIN_FLAG:
|
||||
if not os.path.exists(DRAW_PATH + 'genshin.json') or not os.path.exists(DRAW_PATH + 'genshin_arms.json'):
|
||||
await update_genshin_info()
|
||||
else:
|
||||
with (DRAW_DATA_PATH / "genshin.json").open("r", encoding="utf8") as f:
|
||||
with open(DRAW_PATH + 'genshin.json', 'r', encoding='utf8') as f:
|
||||
genshin_dict = json.load(f)
|
||||
with (DRAW_DATA_PATH / "genshin_arms.json").open("r", encoding="utf8") as f:
|
||||
with open(DRAW_PATH + 'genshin_arms.json', 'r', encoding='utf8') as f:
|
||||
genshin_ARMS_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool("genshin", genshin_dict, GenshinChar)
|
||||
ALL_ARMS = init_game_pool("genshin_arms", genshin_ARMS_dict, GenshinChar)
|
||||
ALL_CHAR = init_game_pool('genshin', genshin_dict, GenshinChar)
|
||||
ALL_ARMS = init_game_pool('genshin_arms', genshin_ARMS_dict, GenshinChar)
|
||||
await _genshin_init_up_char()
|
||||
|
||||
|
||||
# 抽取卡池
|
||||
def _get_genshin_card(mode: int = 1, pool_name: str = "", add: float = 0.0, is_up: bool = False):
|
||||
"""
|
||||
mode 1:普通抽 2:四星保底 3:五星保底
|
||||
"""
|
||||
def _get_genshin_card(mode: int = 1, pool_name: str = '', add: float = 0.0):
|
||||
global ALL_ARMS, ALL_CHAR, UP_ARMS, UP_CHAR, _CURRENT_ARMS_POOL_TITLE, _CURRENT_CHAR_POOL_TITLE
|
||||
genshin_config = draw_config.genshin
|
||||
if mode == 1:
|
||||
star = get_star(
|
||||
[5, 4, 3], [genshin_config.GENSHIN_FIVE_P + add, genshin_config.GENSHIN_FOUR_P, genshin_config.GENSHIN_THREE_P]
|
||||
)
|
||||
star = get_star([5, 4, 3], [GENSHIN_FIVE_P + add, GENSHIN_FOUR_P, GENSHIN_THREE_P])
|
||||
elif mode == 2:
|
||||
star = get_star([5, 4], [genshin_config.GENSHIN_G_FIVE_P + add, genshin_config.GENSHIN_G_FOUR_P])
|
||||
star = get_star([5, 4], [GENSHIN_G_FIVE_P + add, GENSHIN_G_FOUR_P])
|
||||
else:
|
||||
star = 5
|
||||
if pool_name == "char":
|
||||
if pool_name == 'char':
|
||||
data_lst = UP_CHAR
|
||||
flag = _CURRENT_CHAR_POOL_TITLE
|
||||
type_all_lst = ALL_CHAR + [
|
||||
x for x in ALL_ARMS if x.star == star and x.star < 5
|
||||
]
|
||||
elif pool_name == "arms":
|
||||
itype_all_lst = ALL_CHAR + [x for x in ALL_ARMS if x.star == star and x.star < 5]
|
||||
elif pool_name == 'arms':
|
||||
data_lst = UP_ARMS
|
||||
flag = _CURRENT_ARMS_POOL_TITLE
|
||||
type_all_lst = ALL_ARMS + [
|
||||
x for x in ALL_CHAR if x.star == star and x.star < 5
|
||||
]
|
||||
itype_all_lst = ALL_ARMS + [x for x in ALL_CHAR if x.star == star and x.star < 5]
|
||||
else:
|
||||
data_lst = ""
|
||||
flag = ""
|
||||
type_all_lst = ""
|
||||
data_lst = ''
|
||||
flag = ''
|
||||
itype_all_lst = ''
|
||||
all_lst = ALL_ARMS + ALL_CHAR
|
||||
# 是否UP
|
||||
try:
|
||||
if flag and star > 3:
|
||||
# 获取up角色列表
|
||||
up_char_lst = [x.operators for x in data_lst if x.star == star][0]
|
||||
# print(up_char_lst)
|
||||
# 成功获取up角色
|
||||
if random.random() < 0.5 or is_up:
|
||||
up_char_name = random.choice(up_char_lst)
|
||||
acquire_char = [x for x in all_lst if x.name == up_char_name][0]
|
||||
else:
|
||||
# 无up
|
||||
all_char_lst = [
|
||||
x
|
||||
for x in type_all_lst
|
||||
if x.star == star and x.name not in up_char_lst and not x.limited
|
||||
]
|
||||
acquire_char = random.choice(all_char_lst)
|
||||
if flag and star > 3 and pool_name:
|
||||
# 获取up角色列表
|
||||
up_char_lst = [x.operators for x in data_lst if x.star == star][0]
|
||||
# 成功获取up角色
|
||||
if random.random() < 0.5:
|
||||
up_char_name = random.choice(up_char_lst)
|
||||
acquire_char = [x for x in all_lst if x.name == up_char_name][0]
|
||||
else:
|
||||
chars = [x for x in all_lst if x.star == star and not x.limited]
|
||||
acquire_char = random.choice(chars)
|
||||
except IndexError:
|
||||
# 无up
|
||||
all_char_lst = [x for x in itype_all_lst if x.star == star and x.name not in up_char_lst and not x.limited]
|
||||
acquire_char = random.choice(all_char_lst)
|
||||
else:
|
||||
chars = [x for x in all_lst if x.star == star and not x.limited]
|
||||
acquire_char = random.choice(chars)
|
||||
return acquire_char, 5 - star
|
||||
|
||||
|
||||
def _format_card_information(_count: int, user_id, pool_name):
|
||||
char_list = [] # 获取角色列表
|
||||
star_num_list = [0, 0, 0] # 各个星级数量
|
||||
five_dict = {} # 五星数量
|
||||
char_list = []
|
||||
star_list = [0, 0, 0]
|
||||
five_index_list = []
|
||||
five_list = []
|
||||
five_dict = {}
|
||||
_start_add_count = 72 if pool_name == 'char' else 62
|
||||
_x = 90 if pool_name == 'char' else 80 # 保底
|
||||
add = 0.0
|
||||
pool = UP_CHAR if pool_name == 'char' else UP_ARMS
|
||||
for _ in range(_count):
|
||||
draw_count_manager.increase(user_id)
|
||||
star = draw_count_manager.check(user_id)
|
||||
if (draw_count_manager.get_user_count(user_id) - draw_count_manager.get_user_count(user_id, 1)) % 90 >= 72:
|
||||
add += draw_config.genshin.I72_ADD
|
||||
if star:
|
||||
star = int(star)
|
||||
if star == 4:
|
||||
char, code = _get_genshin_card(2, pool_name, add=add)
|
||||
draw_count_manager.record_count(user_id, 0)
|
||||
else:
|
||||
char, code = _get_genshin_card(3, pool_name, add, draw_count_manager.is_up(user_id))
|
||||
if genshin_count.get(user_id) and _count <= _x:
|
||||
f_count = genshin_count[user_id]
|
||||
else:
|
||||
f_count = 0
|
||||
if genshin_pl_count.get(user_id) and _count <= _x:
|
||||
count = genshin_pl_count[user_id]
|
||||
else:
|
||||
count = 0
|
||||
for i in range(_count):
|
||||
count += 1
|
||||
f_count += 1
|
||||
# 十连保底
|
||||
if count == 10 and f_count != _x:
|
||||
if f_count >= _start_add_count:
|
||||
add += I72_ADD
|
||||
char, code = _get_genshin_card(2, pool_name, add=add)
|
||||
count = 0
|
||||
# 大保底
|
||||
elif f_count == _x:
|
||||
char, code = _get_genshin_card(3, pool_name)
|
||||
else:
|
||||
char, code = _get_genshin_card(1, pool_name, add, draw_count_manager.is_up(user_id))
|
||||
if f_count >= _start_add_count:
|
||||
add += I72_ADD
|
||||
char, code = _get_genshin_card(pool_name=pool_name, add=add)
|
||||
if code == 1:
|
||||
count = 0
|
||||
star_list[code] += 1
|
||||
if code == 0:
|
||||
add = 0
|
||||
if not five_dict.get(char.name):
|
||||
five_dict[char.name] = [draw_count_manager.get_user_count(user_id)]
|
||||
else:
|
||||
five_dict[char.name].append(draw_count_manager.get_user_count(user_id) % 90)
|
||||
draw_count_manager.set_count(user_id, 2, draw_count_manager.get_user_count(user_id, 1))
|
||||
draw_count_manager.record_count(user_id, 0)
|
||||
draw_count_manager.record_count(user_id, 1)
|
||||
if char.name not in [x.operators for x in pool if x.star == 5][0]:
|
||||
draw_count_manager.set_is_up(user_id, True)
|
||||
else:
|
||||
draw_count_manager.set_is_up(user_id, False)
|
||||
star_num_list[code] += 1
|
||||
if _count <= _x:
|
||||
genshin_five[user_id] = f_count
|
||||
add = 0.0
|
||||
f_count = 0
|
||||
five_list.append(char.name)
|
||||
five_index_list.append(i)
|
||||
try:
|
||||
five_dict[char.name] += 1
|
||||
except KeyError:
|
||||
five_dict[char.name] = 1
|
||||
char_list.append(char)
|
||||
return char_list, five_dict, star_num_list
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# if genshin_count.get(user_id) and _count <= 90:
|
||||
# f_count = genshin_count[user_id]
|
||||
# else:
|
||||
# f_count = 0
|
||||
# if genshin_pl_count.get(user_id) and _count <= 90:
|
||||
# count = genshin_pl_count[user_id]
|
||||
# else:
|
||||
# count = 0
|
||||
# for i in range(_count):
|
||||
# count += 1
|
||||
# f_count += 1
|
||||
# # 十连保底
|
||||
# if count == 10 and f_count != 90:
|
||||
# if f_count >= 72:
|
||||
# add += I72_ADD
|
||||
# char, code = _get_genshin_card(2, pool_name, add=add)
|
||||
# count = 0
|
||||
# # 大保底
|
||||
# elif f_count == 90:
|
||||
# char, code = _get_genshin_card(3, pool_name)
|
||||
# else:
|
||||
# if f_count >= 72:
|
||||
# add += I72_ADD
|
||||
# char, code = _get_genshin_card(pool_name=pool_name, add=add)
|
||||
# if code == 1:
|
||||
# count = 0
|
||||
# star_list[code] += 1
|
||||
# if code == 0:
|
||||
# if _count <= 90:
|
||||
# genshin_five[user_id] = f_count
|
||||
# add = 0.0
|
||||
# f_count = 0
|
||||
# five_list.append(char.name)
|
||||
# five_index_list.append(i)
|
||||
# try:
|
||||
# five_dict[char.name] += 1
|
||||
# except KeyError:
|
||||
# five_dict[char.name] = 1
|
||||
# char_list.append(char)
|
||||
# if _count <= 90:
|
||||
# genshin_count[user_id] = f_count
|
||||
# genshin_pl_count[user_id] = count
|
||||
# return char_list, five_list, five_index_list, five_dict, star_list
|
||||
if _count <= _x:
|
||||
genshin_count[user_id] = f_count
|
||||
genshin_pl_count[user_id] = count
|
||||
return char_list, five_list, five_index_list, five_dict, star_list
|
||||
|
||||
|
||||
def reset_count(user_id: int):
|
||||
draw_count_manager.reset(user_id)
|
||||
genshin_count[user_id] = 0
|
||||
genshin_pl_count[user_id] = 0
|
||||
|
||||
|
||||
# 获取up和概率
|
||||
async def _genshin_init_up_char():
|
||||
global _CURRENT_CHAR_POOL_TITLE, _CURRENT_ARMS_POOL_TITLE, UP_CHAR, UP_ARMS, POOL_IMG
|
||||
(
|
||||
_CURRENT_CHAR_POOL_TITLE,
|
||||
_CURRENT_ARMS_POOL_TITLE,
|
||||
POOL_IMG,
|
||||
UP_CHAR,
|
||||
UP_ARMS,
|
||||
) = await init_up_char(announcement)
|
||||
_CURRENT_CHAR_POOL_TITLE, _CURRENT_ARMS_POOL_TITLE, POOL_IMG, UP_CHAR, UP_ARMS = await init_up_char(announcement)
|
||||
|
||||
|
||||
async def reload_genshin_pool():
|
||||
await _genshin_init_up_char()
|
||||
return Message(
|
||||
f"当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE} {POOL_IMG}"
|
||||
)
|
||||
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE} {POOL_IMG}')
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, Message
|
||||
|
||||
import os
|
||||
from nonebot.adapters.cqhttp import MessageSegment, Message
|
||||
from .update_game_info import update_info
|
||||
from .announcement import GuardianAnnouncement
|
||||
from .util import init_star_rst, generate_img, max_card, BaseData,\
|
||||
set_list, get_star, format_card_information, init_up_char
|
||||
import random
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .config import DRAW_PATH, GUARDIAN_ONE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_THREE_CHAR_P, \
|
||||
GUARDIAN_THREE_CHAR_UP_P, GUARDIAN_TWO_ARMS_P, GUARDIAN_FIVE_ARMS_P, GUARDIAN_THREE_CHAR_OTHER_P, \
|
||||
GUARDIAN_FOUR_ARMS_P, GUARDIAN_THREE_ARMS_P, GUARDIAN_EXCLUSIVE_ARMS_P, GUARDIAN_EXCLUSIVE_ARMS_UP_P, \
|
||||
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P, GUARDIAN_FLAG
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
from .announcement import GuardianAnnouncement
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
@@ -91,13 +96,13 @@ async def update_guardian_info():
|
||||
|
||||
async def init_guardian_data():
|
||||
global ALL_CHAR, ALL_ARMS
|
||||
if draw_config.GUARDIAN_FLAG:
|
||||
if not (DRAW_DATA_PATH / 'guardian.json').exists() or not (DRAW_DATA_PATH / 'guardian_arms.json').exists():
|
||||
if GUARDIAN_FLAG:
|
||||
if not os.path.exists(DRAW_PATH + 'guardian.json') or not os.path.exists(DRAW_PATH + 'guardian_arms.json'):
|
||||
await update_guardian_info()
|
||||
else:
|
||||
with (DRAW_DATA_PATH / 'guardian.json').open('r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + 'guardian.json', 'r', encoding='utf8') as f:
|
||||
guardian_char_dict = json.load(f)
|
||||
with (DRAW_DATA_PATH / 'guardian_arms.json').open('r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + 'guardian_arms.json', 'r', encoding='utf8') as f:
|
||||
guardian_arms_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('guardian', guardian_char_dict, GuardianChar)
|
||||
ALL_ARMS = init_game_pool('guardian_arms', guardian_arms_dict, GuardianArms)
|
||||
@@ -107,22 +112,21 @@ async def init_guardian_data():
|
||||
# 抽取卡池
|
||||
def _get_guardian_card(pool_name: str = '', mode: int = 1):
|
||||
global ALL_ARMS, ALL_CHAR, UP_ARMS, UP_CHAR, _CURRENT_ARMS_POOL_TITLE, _CURRENT_CHAR_POOL_TITLE
|
||||
guardian_config = draw_config.guardian
|
||||
if pool_name == 'char':
|
||||
if mode == 1:
|
||||
star = get_star([3, 2, 1], [guardian_config.GUARDIAN_THREE_CHAR_P, guardian_config.GUARDIAN_TWO_CHAR_P, guardian_config.GUARDIAN_ONE_CHAR_P])
|
||||
star = get_star([3, 2, 1], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_ONE_CHAR_P])
|
||||
else:
|
||||
star = get_star([3, 2], [guardian_config.GUARDIAN_THREE_CHAR_P, guardian_config.GUARDIAN_TWO_CHAR_P])
|
||||
star = get_star([3, 2], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P])
|
||||
up_lst = UP_CHAR
|
||||
flag = _CURRENT_CHAR_POOL_TITLE
|
||||
_max_star = 3
|
||||
all_data = ALL_CHAR
|
||||
else:
|
||||
if mode == 1:
|
||||
star = get_star([5, 4, 3, 2], [guardian_config.GUARDIAN_FIVE_ARMS_P, guardian_config.GUARDIAN_FOUR_ARMS_P,
|
||||
guardian_config.GUARDIAN_THREE_ARMS_P, guardian_config.GUARDIAN_TWO_ARMS_P])
|
||||
star = get_star([5, 4, 3, 2], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P,
|
||||
GUARDIAN_THREE_ARMS_P, GUARDIAN_TWO_ARMS_P])
|
||||
else:
|
||||
star = get_star([5, 4], [guardian_config.GUARDIAN_FIVE_ARMS_P, guardian_config.GUARDIAN_FOUR_ARMS_P])
|
||||
star = get_star([5, 4], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P])
|
||||
up_lst = UP_ARMS
|
||||
flag = _CURRENT_ARMS_POOL_TITLE
|
||||
_max_star = 5
|
||||
@@ -154,6 +158,3 @@ async def _guardian_init_up_char():
|
||||
async def reload_guardian_pool():
|
||||
await _guardian_init_up_char()
|
||||
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE}')
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,204 +1,137 @@
|
||||
from typing import Any
|
||||
from .config import DRAW_DATA_PATH
|
||||
from .util import is_number
|
||||
from nonebot.log import logger
|
||||
|
||||
from .config import DATA_PATH
|
||||
from utils.utils import is_number
|
||||
from pathlib import Path
|
||||
from services.log import logger
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
|
||||
def init_game_pool(game: str, data: dict, operator: Any):
|
||||
def init_game_pool(game: str, data: dict, Operator: Any):
|
||||
tmp_lst = []
|
||||
if game == "prts":
|
||||
if game == 'prts':
|
||||
for key in data.keys():
|
||||
limited = False
|
||||
recruit_only = False
|
||||
event_only = False
|
||||
if "限定寻访" in data[key]["获取途径"]:
|
||||
if '限定寻访' in data[key]['获取途径']:
|
||||
limited = True
|
||||
if "干员寻访" not in data[key]["获取途径"] and "公开招募" in data[key]["获取途径"]:
|
||||
if '干员寻访' not in data[key]['获取途径'] and '公开招募' in data[key]['获取途径']:
|
||||
recruit_only = True
|
||||
if "活动获取" in data[key]["获取途径"]:
|
||||
if '活动获取' in data[key]['获取途径']:
|
||||
event_only = True
|
||||
if "干员寻访" not in data[key]["获取途径"] and "凭证交易所" == data[key]["获取途径"][0]:
|
||||
if '干员寻访' not in data[key]['获取途径'] and '凭证交易所' == data[key]['获取途径'][0]:
|
||||
limited = True
|
||||
if "干员寻访" not in data[key]["获取途径"] and "信用累计奖励" == data[key]["获取途径"][0]:
|
||||
if '干员寻访' not in data[key]['获取途径'] and '信用累计奖励' == data[key]['获取途径'][0]:
|
||||
limited = True
|
||||
if key.find("阿米娅") != -1:
|
||||
if key.find('阿米娅') != -1:
|
||||
continue
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=key,
|
||||
star=int(data[key]["星级"]),
|
||||
limited=limited,
|
||||
recruit_only=recruit_only,
|
||||
event_only=event_only,
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
|
||||
limited=limited, recruit_only=recruit_only, event_only=event_only))
|
||||
except Exception as e:
|
||||
logger.warning(f"明日方舟导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
if game == "genshin":
|
||||
if game == 'genshin':
|
||||
for key in data.keys():
|
||||
if key.find("旅行者") != -1:
|
||||
if key.find('旅行者') != -1:
|
||||
continue
|
||||
limited = False
|
||||
if data[key]["常驻/限定"] == "限定UP":
|
||||
if data[key]['常驻/限定'] == '限定UP':
|
||||
limited = True
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(name=key, star=int(data[key]["稀有度"][:1]), limited=limited)
|
||||
)
|
||||
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
|
||||
except Exception as e:
|
||||
logger.warning(f"原神导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
if game == "genshin_arms":
|
||||
if game == 'genshin_arms':
|
||||
for key in data.keys():
|
||||
if data[key]["获取途径"].find("祈愿") != -1:
|
||||
if data[key]['获取途径'].find('祈愿') != -1:
|
||||
limited = False
|
||||
if data[key]["获取途径"].find("限定祈愿") != -1:
|
||||
if data[key]['获取途径'].find('限定祈愿') != -1:
|
||||
limited = True
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=key, star=int(data[key]["稀有度"][:1]), limited=limited
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
|
||||
except Exception as e:
|
||||
logger.warning(f"原神导入武器 {key} 数据错误:{type(e)}:{e}")
|
||||
if game == "pretty":
|
||||
if game == 'pretty':
|
||||
for key in data.keys():
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(name=key, star=data[key]["初始星级"], limited=False)
|
||||
)
|
||||
tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False))
|
||||
except Exception as e:
|
||||
logger.warning(f"赛马娘导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
if game == "pretty_card":
|
||||
if game == 'pretty_card':
|
||||
for key in data.keys():
|
||||
limited = False
|
||||
if "卡池" not in data[key]["获取方式"]:
|
||||
if '卡池' not in data[key]['获取方式']:
|
||||
limited = True
|
||||
if not data[key]["获取方式"]:
|
||||
if not data[key]['获取方式']:
|
||||
limited = False
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=data[key]["中文名"],
|
||||
star=len(data[key]["稀有度"]),
|
||||
limited=limited,
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited))
|
||||
except Exception as e:
|
||||
logger.warning(f"赛马娘导入卡片 {key} 数据错误:{type(e)}:{e}")
|
||||
if game in ["guardian", "guardian_arms"]:
|
||||
if game in ['guardian', 'guardian_arms']:
|
||||
for key in data.keys():
|
||||
tmp_lst.append(
|
||||
operator(name=data[key]["名称"], star=int(data[key]["星级"]), limited=False)
|
||||
)
|
||||
if game == "pcr":
|
||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False))
|
||||
if game == 'pcr':
|
||||
for key in data.keys():
|
||||
limited = False
|
||||
if key.find("(") != -1:
|
||||
if key.find('(') != -1:
|
||||
limited = True
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=data[key]["名称"], star=int(data[key]["星级"]), limited=limited
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
|
||||
except Exception as e:
|
||||
logger.warning(f"公主连接导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
if game == "azur":
|
||||
if game == 'azur':
|
||||
for key in data.keys():
|
||||
if is_number(data[key]["星级"]):
|
||||
if is_number(data[key]['星级']):
|
||||
limited = False
|
||||
if "可以建造" not in data[key]["获取途径"]:
|
||||
if '可以建造' not in data[key]['获取途径']:
|
||||
limited = True
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=data[key]["名称"],
|
||||
star=int(data[key]["星级"]),
|
||||
limited=limited,
|
||||
type_=data[key]["类型"],
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
|
||||
limited=limited, itype=data[key]['类型']))
|
||||
except Exception as e:
|
||||
logger.warning(f"碧蓝航线导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
if game in ["fgo", "fgo_card"]:
|
||||
if game in ['fgo', 'fgo_card']:
|
||||
for key in data.keys():
|
||||
limited = False
|
||||
try:
|
||||
if (
|
||||
"圣晶石召唤" not in data[key]["入手方式"]
|
||||
and "圣晶石召唤(Story卡池)" not in data[key]["入手方式"]
|
||||
):
|
||||
if "圣晶石召唤" not in data[key]['入手方式'] and "圣晶石召唤(Story卡池)" not in data[key]['入手方式']:
|
||||
limited = True
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=data[key]["名称"], star=int(data[key]["星级"]), limited=limited
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
|
||||
except Exception as e:
|
||||
logger.warning(f"FGO导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
if game == "onmyoji":
|
||||
if game == 'onmyoji':
|
||||
for key in data.keys():
|
||||
limited = False
|
||||
if key in [
|
||||
"奴良陆生",
|
||||
"卖药郎",
|
||||
"鬼灯",
|
||||
"阿香",
|
||||
"蜜桃&芥子",
|
||||
"犬夜叉",
|
||||
"杀生丸",
|
||||
"桔梗",
|
||||
"朽木露琪亚",
|
||||
"黑崎一护",
|
||||
"灶门祢豆子",
|
||||
"灶门炭治郎",
|
||||
]:
|
||||
if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护',
|
||||
'灶门祢豆子', '灶门炭治郎']:
|
||||
limited = True
|
||||
try:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=data[key]["名称"], star=data[key]["星级"], limited=limited
|
||||
)
|
||||
)
|
||||
tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited))
|
||||
except Exception as e:
|
||||
logger.warning(f"阴阳师导入角色 {key} 数据错误:{type(e)}:{e}")
|
||||
# print(tmp_lst)
|
||||
char_name_lst = [x.name for x in tmp_lst]
|
||||
up_char_file = (
|
||||
DRAW_DATA_PATH
|
||||
/ f"draw_card"
|
||||
/ "draw_card_up"
|
||||
/ f"{game.split('_')[0]}_up_char.json"
|
||||
)
|
||||
up_char_file = Path(f'{DATA_PATH}/draw_card/draw_card_up/{game.split("_")[0]}_up_char.json')
|
||||
if up_char_file.exists():
|
||||
data = json.load(open(up_char_file, "r", encoding="utf8"))
|
||||
if len(game.split("_")) == 1:
|
||||
key = "char"
|
||||
data = json.load(open(up_char_file, 'r', encoding='utf8'))
|
||||
if len(game.split('_')) == 1:
|
||||
key = 'char'
|
||||
else:
|
||||
key = list(data.keys())[1]
|
||||
for x in data[key]["up_char"]:
|
||||
for char in data[key]["up_char"][x]:
|
||||
for x in data[key]['up_char']:
|
||||
for char in data[key]['up_char'][x]:
|
||||
if char not in char_name_lst:
|
||||
if game.find("prts") != -1:
|
||||
tmp_lst.append(
|
||||
operator(
|
||||
name=char,
|
||||
star=int(x),
|
||||
recruit_only=False,
|
||||
event_only=False,
|
||||
limited=False,
|
||||
)
|
||||
)
|
||||
if game.find('prts') != -1:
|
||||
tmp_lst.append(Operator(name=char, star=int(x),
|
||||
recruit_only=False, event_only=False, limited=False))
|
||||
else:
|
||||
tmp_lst.append(operator(name=char, star=int(x), limited=False))
|
||||
tmp_lst.append(Operator(name=char, star=int(x), limited=False))
|
||||
return tmp_lst
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from nonebot.adapters.cqhttp import MessageSegment
|
||||
import random
|
||||
from .update_game_requests_info import update_requests_info
|
||||
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_FLAG
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
try:
|
||||
@@ -38,8 +39,8 @@ async def update_onmyoji_info():
|
||||
|
||||
async def init_onmyoji_data():
|
||||
global ALL_CHAR
|
||||
if draw_config.ONMYOJI_FLAG:
|
||||
with (DRAW_DATA_PATH / 'onmyoji.json').open('r', encoding='utf8') as f:
|
||||
if ONMYOJI_FLAG:
|
||||
with open(DRAW_PATH + 'onmyoji.json', 'r', encoding='utf8') as f:
|
||||
azur_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('onmyoji', azur_dict, OnmyojiChar)
|
||||
|
||||
@@ -55,8 +56,7 @@ onmyoji_star = {
|
||||
# 抽取卡池
|
||||
def _get_onmyoji_card():
|
||||
global ALL_CHAR
|
||||
onmyoji_config = draw_config.onmyoji
|
||||
star = get_star([5, 4, 3, 2], [onmyoji_config.ONMYOJI_SP, onmyoji_config.ONMYOJI_SSR, onmyoji_config.ONMYOJI_SR, onmyoji_config.ONMYOJI_R])
|
||||
star = get_star([5, 4, 3, 2], [ONMYOJI_SP, ONMYOJI_SSR, ONMYOJI_SR, ONMYOJI_R])
|
||||
chars = [x for x in ALL_CHAR if x.star == onmyoji_star[star] and not x.limited]
|
||||
return random.choice(chars), 5 - star
|
||||
|
||||
@@ -79,3 +79,4 @@ def format_card_information(count: int):
|
||||
obj_dict[obj.name] = 1
|
||||
obj_list.append(obj)
|
||||
return obj_list, obj_dict, star_list, rst
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
import ujson as json
|
||||
from nonebot.adapters.cqhttp import MessageSegment
|
||||
import random
|
||||
from .update_game_info import update_info
|
||||
from .update_game_simple_info import update_simple_info
|
||||
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .config import PCR_TWO_P, PCR_THREE_P, PCR_ONE_P, DRAW_PATH, PCR_FLAG, PCR_G_TWO_P, PCR_G_THREE_P, PCR_TAI
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
ALL_CHAR = []
|
||||
|
||||
@@ -33,7 +30,7 @@ async def pcr_draw(count: int):
|
||||
|
||||
async def update_pcr_info():
|
||||
global ALL_CHAR
|
||||
if draw_config.PCR_TAI:
|
||||
if PCR_TAI:
|
||||
url = 'https://wiki.biligame.com/pcr/角色图鉴'
|
||||
data, code = await update_simple_info(url, 'pcr')
|
||||
else:
|
||||
@@ -45,8 +42,8 @@ async def update_pcr_info():
|
||||
|
||||
async def init_pcr_data():
|
||||
global ALL_CHAR
|
||||
if draw_config.PCR_FLAG:
|
||||
with (DRAW_DATA_PATH / 'pcr.json').open('r', encoding='utf8') as f:
|
||||
if PCR_FLAG:
|
||||
with open(DRAW_PATH + 'pcr.json', 'r', encoding='utf8') as f:
|
||||
pcr_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('pcr', pcr_dict, PcrChar)
|
||||
|
||||
@@ -54,11 +51,10 @@ async def init_pcr_data():
|
||||
# 抽取卡池
|
||||
def _get_pcr_card(mode: int = 1):
|
||||
global ALL_CHAR
|
||||
pcr_config = draw_config.pcr
|
||||
if mode == 2:
|
||||
star = get_star([3, 2], [pcr_config.PCR_G_THREE_P, pcr_config.PCR_G_TWO_P])
|
||||
star = get_star([3, 2], [PCR_G_THREE_P, PCR_G_TWO_P])
|
||||
else:
|
||||
star = get_star([3, 2, 1], [pcr_config.PCR_THREE_P, pcr_config.PCR_TWO_P, pcr_config.PCR_ONE_P])
|
||||
star = get_star([3, 2, 1], [PCR_THREE_P, PCR_TWO_P, PCR_ONE_P])
|
||||
chars = [x for x in ALL_CHAR if x.star == star and not x.limited]
|
||||
return random.choice(chars), 3 - star
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from .announcement import PrettyAnnouncement
|
||||
|
||||
from .update_game_info import update_info
|
||||
from .announcement import PrettyAnnouncement
|
||||
from .util import init_star_rst, generate_img, max_card, BaseData, \
|
||||
set_list, get_star, format_card_information, init_up_char
|
||||
import random
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .config import PRETTY_THREE_P, PRETTY_TWO_P, DRAW_PATH, PRETTY_ONE_P, PRETTY_FLAG
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
from nonebot.adapters.cqhttp import MessageSegment, Message
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -73,8 +74,7 @@ async def pretty_draw(count: int, pool_name):
|
||||
rst = init_star_rst(star_list, cnlist, three_list, three_olist, up_list)
|
||||
if count > 90:
|
||||
obj_list = set_list(obj_list)
|
||||
return pool_info + MessageSegment.image(
|
||||
"base64://" + await generate_img(obj_list, 'pretty', star_list)) \
|
||||
return pool_info + MessageSegment.image("base64://" + await generate_img(obj_list, 'pretty', star_list)) \
|
||||
+ '\n' + rst[:-1] + '\n' + max_card(obj_dict)
|
||||
|
||||
|
||||
@@ -93,10 +93,10 @@ async def update_pretty_info():
|
||||
|
||||
async def init_pretty_data():
|
||||
global ALL_CHAR, ALL_CARD
|
||||
if draw_config.PRETTY_FLAG:
|
||||
with (DRAW_DATA_PATH / 'pretty.json').open('r', encoding='utf8') as f:
|
||||
if PRETTY_FLAG:
|
||||
with open(DRAW_PATH + 'pretty.json', 'r', encoding='utf8') as f:
|
||||
pretty_char_dict = json.load(f)
|
||||
with (DRAW_DATA_PATH / 'pretty_card.json').open('r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f:
|
||||
pretty_card_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar)
|
||||
ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar)
|
||||
@@ -106,11 +106,10 @@ async def init_pretty_data():
|
||||
# 抽取卡池
|
||||
def _get_pretty_card(pool_name: str, mode: int = 1):
|
||||
global ALL_CHAR, ALL_CARD, _CURRENT_CHAR_POOL_TITLE, _CURRENT_CARD_POOL_TITLE
|
||||
pretty_config = draw_config.pretty
|
||||
if mode == 1:
|
||||
star = get_star([3, 2, 1], [pretty_config.PRETTY_THREE_P, pretty_config.PRETTY_TWO_P, pretty_config.PRETTY_ONE_P])
|
||||
star = get_star([3, 2, 1], [PRETTY_THREE_P, PRETTY_TWO_P, PRETTY_ONE_P])
|
||||
else:
|
||||
star = get_star([3, 2], [pretty_config.PRETTY_THREE_P, pretty_config.PRETTY_TWO_P])
|
||||
star = get_star([3, 2], [PRETTY_THREE_P, PRETTY_TWO_P])
|
||||
if pool_name == 'card':
|
||||
title = _CURRENT_CARD_POOL_TITLE
|
||||
up_data = UP_CARD
|
||||
@@ -128,6 +127,7 @@ def _get_pretty_card(pool_name: str, mode: int = 1):
|
||||
acquire_operator = random.choice(all_up_star)
|
||||
if pool_name == 'char':
|
||||
acquire_operator = acquire_operator.split(']')[1]
|
||||
print(acquire_operator)
|
||||
acquire_operator = [x for x in data if x.name == acquire_operator][0]
|
||||
else:
|
||||
acquire_operator = random.choice([x for x in data if x.star == star and not x.limited])
|
||||
@@ -144,5 +144,6 @@ async def _pretty_init_up_char():
|
||||
|
||||
async def reload_pretty_pool():
|
||||
await _pretty_init_up_char()
|
||||
return f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_CARD_POOL_TITLE} {POOL_IMG}'
|
||||
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_CARD_POOL_TITLE} {POOL_IMG}')
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, Message
|
||||
|
||||
from nonebot.adapters.cqhttp import MessageSegment, Message
|
||||
import random
|
||||
from .config import DRAW_DATA_PATH, draw_config
|
||||
from .config import PRTS_FIVE_P, PRTS_FOUR_P, PRTS_SIX_P, PRTS_THREE_P, DRAW_PATH, PRTS_FLAG
|
||||
from .update_game_info import update_info
|
||||
from .util import generate_img, init_star_rst, max_card, BaseData, UpEvent, set_list, get_star
|
||||
from .init_card_pool import init_game_pool
|
||||
from pathlib import Path
|
||||
from .announcement import PrtsAnnouncement
|
||||
from services.log import logger
|
||||
from dataclasses import dataclass
|
||||
from nonebot.log import logger
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
@@ -15,6 +17,8 @@ except ModuleNotFoundError:
|
||||
|
||||
announcement = PrtsAnnouncement()
|
||||
|
||||
up_char_file = Path() / "data" / "draw_card" / "draw_card_up" / "prts_up_char.json"
|
||||
|
||||
prts_dict = {}
|
||||
UP_OPERATOR = []
|
||||
ALL_OPERATOR = []
|
||||
@@ -67,8 +71,8 @@ async def update_prts_info():
|
||||
|
||||
async def init_prts_data():
|
||||
global prts_dict, ALL_OPERATOR
|
||||
if draw_config.PRTS_FLAG:
|
||||
with (DRAW_DATA_PATH / 'prts.json').open('r', encoding='utf8') as f:
|
||||
if PRTS_FLAG:
|
||||
with open(DRAW_PATH + 'prts.json', 'r', encoding='utf8') as f:
|
||||
prts_dict = json.load(f)
|
||||
ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator)
|
||||
await _init_up_char()
|
||||
@@ -76,8 +80,7 @@ async def init_prts_data():
|
||||
|
||||
# 抽取干员
|
||||
def _get_operator_card(add: float):
|
||||
prts_config = draw_config.prts
|
||||
star = get_star([6, 5, 4, 3], [prts_config.PRTS_SIX_P + add, prts_config.PRTS_FIVE_P, prts_config.PRTS_FOUR_P, prts_config.PRTS_THREE_P])
|
||||
star = get_star([6, 5, 4, 3], [PRTS_SIX_P + add, PRTS_FIVE_P, PRTS_FOUR_P, PRTS_THREE_P])
|
||||
if _CURRENT_POOL_TITLE:
|
||||
zooms = [x.zoom for x in UP_OPERATOR if x.star == star]
|
||||
zoom = 0
|
||||
@@ -89,11 +92,12 @@ def _get_operator_card(add: float):
|
||||
else:
|
||||
weight = z
|
||||
up_operator_name = ""
|
||||
# UPs
|
||||
# UP
|
||||
try:
|
||||
if 0 < zoom:
|
||||
if random.random() < zoom:
|
||||
up_operators = [x.operators for x in UP_OPERATOR if x.star == star and x.zoom < 1][0]
|
||||
up_operator_name = random.choice(up_operators)
|
||||
# print(up_operator_name)
|
||||
acquire_operator = [x for x in ALL_OPERATOR if x.name == up_operator_name][0]
|
||||
else:
|
||||
all_star_operators = [x for x in ALL_OPERATOR if x.star == star
|
||||
|
||||
+27
-19
@@ -1,28 +1,36 @@
|
||||
from nonebot.rule import Rule
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from .config import draw_config
|
||||
from .config import (
|
||||
GENSHIN_FLAG,
|
||||
PRTS_FLAG,
|
||||
PRETTY_FLAG,
|
||||
GUARDIAN_FLAG,
|
||||
PCR_FLAG,
|
||||
AZUR_FLAG,
|
||||
FGO_FLAG,
|
||||
ONMYOJI_FLAG,
|
||||
)
|
||||
|
||||
|
||||
def is_switch(game_name: str) -> Rule:
|
||||
|
||||
async def _is_switch(bot: Bot, event: MessageEvent, state: T_State) -> bool:
|
||||
if game_name == 'prts':
|
||||
return draw_config.PRTS_FLAG
|
||||
if game_name == 'genshin':
|
||||
return draw_config.GENSHIN_FLAG
|
||||
if game_name == 'pretty':
|
||||
return draw_config.PRETTY_FLAG
|
||||
if game_name == 'guardian':
|
||||
return draw_config.GUARDIAN_FLAG
|
||||
if game_name == 'pcr':
|
||||
return draw_config.PCR_FLAG
|
||||
if game_name == 'azur':
|
||||
return draw_config.AZUR_FLAG
|
||||
if game_name == 'fgo':
|
||||
return draw_config.FGO_FLAG
|
||||
if game_name == 'onmyoji':
|
||||
return draw_config.ONMYOJI_FLAG
|
||||
if game_name == "prts":
|
||||
return PRTS_FLAG
|
||||
if game_name == "genshin":
|
||||
return GENSHIN_FLAG
|
||||
if game_name == "pretty":
|
||||
return PRETTY_FLAG
|
||||
if game_name == "guardian":
|
||||
return GUARDIAN_FLAG
|
||||
if game_name == "pcr":
|
||||
return PCR_FLAG
|
||||
if game_name == "azur":
|
||||
return AZUR_FLAG
|
||||
if game_name == "fgo":
|
||||
return FGO_FLAG
|
||||
if game_name == "onmyoji":
|
||||
return ONMYOJI_FLAG
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from typing import Tuple
|
||||
from .config import DRAW_DATA_PATH
|
||||
from .config import DRAW_PATH
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from bs4 import BeautifulSoup
|
||||
from .util import download_img
|
||||
from urllib.parse import unquote
|
||||
from services.log import logger
|
||||
from .util import remove_prohibited_str
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from nonebot.log import logger
|
||||
from httpx import ConnectTimeout, CloseError
|
||||
import bs4
|
||||
import re
|
||||
try:
|
||||
@@ -18,16 +18,15 @@ except ModuleNotFoundError:
|
||||
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
|
||||
|
||||
|
||||
async def update_info(url: str, game_name: str, info_list: list = None) -> Tuple[dict, int]:
|
||||
info_path = DRAW_DATA_PATH / f"{game_name}.json"
|
||||
async def update_info(url: str, game_name: str, info_list: list = None) -> 'dict, int':
|
||||
try:
|
||||
with info_path.open('r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + f'{game_name}.json', 'r', encoding='utf8') as f:
|
||||
data = json.load(f)
|
||||
except (ValueError, FileNotFoundError):
|
||||
data = {}
|
||||
try:
|
||||
response = await AsyncHttpx.get(url, timeout=7)
|
||||
soup = BeautifulSoup(response.text, 'lxml')
|
||||
text = (await AsyncHttpx.get(url)).text
|
||||
soup = BeautifulSoup(text, 'lxml')
|
||||
_tbody = get_tbody(soup, game_name, url)
|
||||
trs = _tbody.find_all('tr')
|
||||
att_dict, start_index, index = init_attr(game_name)
|
||||
@@ -59,10 +58,13 @@ async def update_info(url: str, game_name: str, info_list: list = None) -> Tuple
|
||||
data[name] = member_dict
|
||||
logger.info(f'{name} is update...')
|
||||
data = await _last_check(data, game_name)
|
||||
except TimeoutError:
|
||||
except (TimeoutError, ConnectTimeout, CloseError):
|
||||
logger.warning(f'更新 {game_name} 超时...')
|
||||
return {}, 999
|
||||
with info_path.open('w', encoding='utf8') as wf:
|
||||
except Exception as e:
|
||||
logger.error(f"更新 {game_name} 未知错误 {type(e)}:{e}")
|
||||
return {}, 998
|
||||
with open(DRAW_PATH + f'{game_name}.json', 'w', encoding='utf8') as wf:
|
||||
wf.write(json.dumps(data, ensure_ascii=False, indent=4))
|
||||
return data, 200
|
||||
|
||||
@@ -97,25 +99,21 @@ def _find_last_tag(element: bs4.element.Tag, attr: str, game_name: str) -> str:
|
||||
|
||||
# 获取大图(小图快爬)
|
||||
async def _modify_avatar_url(game_name: str, char_name: str):
|
||||
if game_name == 'prts':
|
||||
res = await AsyncHttpx.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7)
|
||||
soup = BeautifulSoup(res.text, 'lxml')
|
||||
try:
|
||||
img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2]
|
||||
except KeyError:
|
||||
img_url = str(soup.find('img', {'class': 'img-bg'})['src'])
|
||||
return img_url
|
||||
# if game_name == 'prts':
|
||||
# async with session.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7) as res:
|
||||
# soup = BeautifulSoup(await res.text(), 'lxml')
|
||||
# try:
|
||||
# img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2]
|
||||
# except KeyError:
|
||||
# img_url = str(soup.find('img', {'class': 'img-bg'})['src'])
|
||||
# return img_url
|
||||
if game_name == 'genshin':
|
||||
return None
|
||||
if game_name == 'pretty_card':
|
||||
res = await AsyncHttpx.get(f'https://wiki.biligame.com/umamusume/{char_name}', timeout=7)
|
||||
soup = BeautifulSoup(res.text, 'lxml')
|
||||
try:
|
||||
img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src')
|
||||
return img_url
|
||||
except AttributeError:
|
||||
logger.warning("pretty_card 获取大图像失败")
|
||||
return None
|
||||
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/umamusume/{char_name}')).text
|
||||
soup = BeautifulSoup(text, 'lxml')
|
||||
img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src')
|
||||
return img_url
|
||||
if game_name == 'guardian':
|
||||
# 未上传图片太多,换成像素图
|
||||
# async with session.get(f'https://wiki.biligame.com/gt/{char_name}', timeout=7) as res:
|
||||
@@ -126,7 +124,7 @@ async def _modify_avatar_url(game_name: str, char_name: str):
|
||||
# except KeyError:
|
||||
# img_url = str(soup.find('img', {'class': 'img-kk'})['src'])
|
||||
# except TypeError:
|
||||
# print(f'{char_name} 图片还未上传,跳过...')
|
||||
# logger.info(f'{char_name} 图片还未上传,跳过...')
|
||||
# img_url = ''
|
||||
# return img_url
|
||||
return None
|
||||
@@ -135,17 +133,18 @@ async def _modify_avatar_url(game_name: str, char_name: str):
|
||||
# 数据最后处理(是否需要额外数据或处理数据)
|
||||
async def _last_check(data: dict, game_name: str):
|
||||
# if game_name == 'prts':
|
||||
# url = 'https://wiki.biligame.com/arknights/'
|
||||
# tasks = []
|
||||
# for key in data.keys():
|
||||
# tasks.append(asyncio.ensure_future(_async_update_prts_extra_info(key, session)))
|
||||
# tasks.append(asyncio.ensure_future(_async_update_prts_extra_info(url, key, session)))
|
||||
# asyResult = await asyncio.gather(*tasks)
|
||||
# for x in asyResult:
|
||||
# for key in x.keys():
|
||||
# data[key]['获取途径'] = x[key]['获取途径']
|
||||
if game_name == 'genshin':
|
||||
for key in data.keys():
|
||||
res = await AsyncHttpx.get(f'https://wiki.biligame.com/ys/{key}', timeout=7)
|
||||
soup = BeautifulSoup(res.text, 'lxml')
|
||||
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/ys/{key}')).text
|
||||
soup = BeautifulSoup(text, 'lxml')
|
||||
_trs = ''
|
||||
for table in soup.find_all('table', {'class': 'wikitable'}):
|
||||
if str(table).find('常驻/限定') != -1:
|
||||
@@ -180,13 +179,10 @@ async def _last_check(data: dict, game_name: str):
|
||||
|
||||
# 对抓取每行数据是否需要额外处理?
|
||||
def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.element.Tag):
|
||||
if game_name == "genshin_arms":
|
||||
if key == "稀有度":
|
||||
member_dict["稀有度"] = td.find("img")["alt"].split('.')[0]
|
||||
if game_name == 'prts':
|
||||
if key == '获取途径':
|
||||
msg = re.search('<td.*?>([\\s\\S]*)</td>', str(td)).group(1).strip()
|
||||
msg = msg[:-1] if msg and msg[-1] == '\n' else msg
|
||||
msg = msg[:-1] if msg[-1] == '\n' else msg
|
||||
if msg.find('<a') != -1:
|
||||
for a in td.find_all('a'):
|
||||
msg = msg.replace(str(a), a.text)
|
||||
@@ -194,13 +190,6 @@ def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.elem
|
||||
if game_name == 'pretty':
|
||||
if key == '初始星级':
|
||||
member_dict['初始星级'] = len(td.find_all('img'))
|
||||
if game_name == 'pretty_card':
|
||||
if key == '获取方式':
|
||||
obtain = []
|
||||
for x in str(td.text).replace('\n', '').strip().split('、'):
|
||||
if x:
|
||||
obtain.append(x)
|
||||
member_dict['获取方式'] = obtain
|
||||
if game_name == 'guardian':
|
||||
if key == '头像':
|
||||
member_dict['星级'] = str(td.find('span').find('img')['alt'])[-5]
|
||||
@@ -265,7 +254,7 @@ def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
|
||||
return _tbody
|
||||
|
||||
|
||||
# async def _async_update_prts_extra_info(key: str, session: aiohttp.ClientSession):
|
||||
# async def _async_update_prts_extra_info(url: str, key: str, session: aiohttp.ClientSession):
|
||||
# for i in range(10):
|
||||
# try:
|
||||
# async with session.get(f'https://wiki.biligame.com/arknights/{key}', timeout=7) as res:
|
||||
@@ -285,11 +274,11 @@ def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
|
||||
# if r:
|
||||
# text += r.group(1) + ' '
|
||||
# obtain[i] = obtain[i].split('<a')[0] + text[:-1] + obtain[i].split('</a>')[-1]
|
||||
# print(f'明日方舟获取额外信息 {key}...{obtain}')
|
||||
# logger.info(f'明日方舟获取额外信息 {key}...{obtain}')
|
||||
# x = {key: {}}
|
||||
# x[key]['获取途径'] = obtain
|
||||
# return x
|
||||
# except TimeoutError:
|
||||
# print(f'访问 https://wiki.biligame.com/arknights/{key} 第 {i}次 超时...已再次访问')
|
||||
# logger.warning(f'访问{url}{key} 第 {i}次 超时...已再次访问')
|
||||
# return {}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user