Compare commits

...
52 Commits
Author SHA1 Message Date
HibiKier 3c8983e753 Update task_hook.py 2022-02-26 00:11:26 +08:00
HibiKier 1fe41dd823 Update __version__ 2022-02-25 23:21:03 +08:00
HibiKier e8df59203c Update README.md 2022-02-25 23:17:42 +08:00
HibiKier 0f6690606b Update README.md 2022-02-25 22:50:24 +08:00
HibiKier a0115309dd Merge pull request #124 from Nova-Noir/main
Fixed error in custom_welcome_msg and message_builder
2022-02-24 16:12:39 +08:00
HibiKier ca18d45786 Update message_builder.py 2022-02-24 16:12:25 +08:00
NovaNo1r 76df21036a Fixed error in custom_welcome_msg and message_builder 2022-02-23 21:45:53 -08:00
HibiKier c674d581b7 Update README.md 2022-02-23 13:52:10 +08:00
HibiKier fc53c3c487 Update _data_source.py 2022-02-23 13:51:19 +08:00
HibiKier 7a4e31df80 Update __init__.py 2022-02-23 13:49:57 +08:00
HibiKier f1d308d559 Update __init__.py 2022-02-23 13:49:21 +08:00
HibiKier b7914bac05 Update README.md 2022-02-21 19:05:42 +08:00
HibiKier 8c40d88cc4 Update .gitignore 2022-02-21 18:20:43 +08:00
HibiKier b4ed6dcb5d Delete server_ip.py 2022-02-21 18:18:30 +08:00
HibiKier 0d3bd8a89c fix bug 2022-02-21 15:59:17 +08:00
HibiKier 87f0189abd Update README.md 2022-02-20 11:39:00 +08:00
HibiKier 1c17ac1f9d Update __init__.py 2022-02-20 11:06:32 +08:00
HibiKier f038763041 fix bug 2022-02-20 11:06:04 +08:00
HibiKier eaf6d54757 Update README.md 2022-02-19 23:24:21 +08:00
HibiKier d7368c83bc Update query_resource.py 2022-02-19 20:12:51 +08:00
HibiKier 4011620da1 Update README.md 2022-02-19 20:06:53 +08:00
HibiKier 6e0b91531e Update __version__ 2022-02-19 20:05:36 +08:00
HibiKier b8ca1d68aa Update update_info.json 2022-02-19 20:04:19 +08:00
HibiKier 2b9cda40a0 Update query_resource.py 2022-02-19 20:03:40 +08:00
HibiKier d8983bdcbf Update README.md 2022-02-19 18:32:09 +08:00
HibiKier 14bce52f2f Update README.md 2022-02-19 18:31:41 +08:00
HibiKier a7b0f7da68 Update README.md 2022-02-19 18:29:40 +08:00
HibiKier 7dd68cf1ef fit nonebot.beta2 2022-02-19 18:20:19 +08:00
HibiKier ab443a21ec Merge pull request #122 from AkashiCoin/main
fix: 修复远古时期残留的epic推送问题
2022-02-19 15:54:59 +08:00
HibiKier ed7e8a8a4c Merge pull request #109 from SAGIRI-kawaii/main
优化BuildImage.circle()锯齿问题
2022-02-19 15:54:14 +08:00
HibiKier a1435e2fc4 Merge branch 'main' into main 2022-02-19 15:53:47 +08:00
AkashiCoin 44a80f89da fix: 修复远古时期残留的epic推送问题 2022-02-19 14:57:23 +08:00
HibiKier 164f6af30c Merge pull request #119 from evlic/fixEPIC
epic restful 替换
2022-02-18 16:22:16 +08:00
evlic 9093a79101 epic restful 替换 2022-02-16 13:31:24 +08:00
HibiKier 14cce89a18 Update README.md 2022-02-11 13:16:48 +08:00
HibiKier 4bce20a0a9 Update data_source.py 2022-02-11 13:16:10 +08:00
HibiKier f32d8b4eff Update __version__ 2022-02-10 11:58:22 +08:00
HibiKier 685f2b8c53 Update README.md 2022-02-10 11:57:41 +08:00
HibiKier 1e63ca2549 Update buy.py 2022-02-10 11:55:36 +08:00
HibiKier c1bc4eff2b Update README.md 2022-02-09 23:02:14 +08:00
HibiKier bc903d3813 Update __init__.py 2022-02-09 22:28:49 +08:00
HibiKier 80fc17b610 Update __version__ 2022-02-09 21:44:09 +08:00
HibiKier 0efb2bbc60 update v0.1 2022-02-09 20:05:49 +08:00
SAGIRI-kawaii 95ad533b87 优化BuildImage.circle()锯齿问题 2022-01-24 23:52:57 +08:00
HibiKier b6e3240df9 Update README.md 2022-01-16 19:22:03 +08:00
HibiKier 5ae41e1d38 Update __init__.py 2022-01-16 18:37:14 +08:00
HibiKier 8022ae1fb1 Update README.md 2022-01-16 15:20:48 +08:00
HibiKier 0163fc1d88 Update draw_image.py 2022-01-16 15:16:19 +08:00
HibiKier 5d9ab40e35 Update __version__ 2022-01-16 15:00:16 +08:00
HibiKier b1ca7930bb Update README.md 2022-01-16 14:54:31 +08:00
HibiKier 40111261ed Update README.md 2022-01-16 14:54:16 +08:00
HibiKier 4cb91b47e6 update v0.0.9.0 2022-01-16 14:52:50 +08:00
226 changed files with 8726 additions and 6381 deletions
+2 -1
View File
@@ -139,9 +139,10 @@ dmypy.json
cython_debug/ cython_debug/
test.py test.py
server.py server_ip.py
member_activity_handle.py member_activity_handle.py
Yu-Gi-Oh/ Yu-Gi-Oh/
search_image/ search_image/
black_word/ black_word/
csgo/ csgo/
fantasy_card/
+114 -9
View File
@@ -18,6 +18,10 @@
## 声明 ## 声明
此项目仅用于学习交流,请勿用于非法用途 此项目仅用于学习交流,请勿用于非法用途
## Gitee
# [Gitee](https://gitee.com/two_Dimension/zhenxun_bot)
## 未完成的文档 ## 未完成的文档
# [传送门](https://hibikier.github.io/zhenxun_bot/) # [传送门](https://hibikier.github.io/zhenxun_bot/)
@@ -25,16 +29,16 @@
## 真寻的帮助 ## 真寻的帮助
请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令' 请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令'
## 普通帮助图片
![x](https://github.com/HibiKier/zhenxun_bot/blob/0.0.8.2/docs_image/3238573864-836268675-E2FFBB2AC143EAF4DDDF150438508721.png)
## 提供符合真寻标准的插件仓库 ## 提供符合真寻标准的插件仓库
[AkashiCoin/nonebot_plugins_zhenxun_bot](https://github.com/AkashiCoin/nonebot_plugins_zhenxun_bot) [AkashiCoin/nonebot_plugins_zhenxun_bot](https://github.com/AkashiCoin/nonebot_plugins_zhenxun_bot)
## 来点优点? ## 来点优点?
一.作为bot:
* 实现了许多功能,且提供了大量功能管理命令
* __..... 更多详细请通过`传送门`查看文档!__
二.作为框架?: * 实现了许多功能,且提供了大量功能管理命令
* 通过Config配置项将所有插件配置统计保存至config.yaml,利于统一用户修改 * 通过Config配置项将所有插件配置统计保存至config.yaml,利于统一用户修改
* 方便增删插件,原生nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息` * 方便增删插件,原生nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
* 提供了cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`__plugin_cd_limit__` * 提供了cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`__plugin_cd_limit__`
@@ -67,6 +71,8 @@
- [x] 原神资源查询 (借鉴[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件) - [x] 原神资源查询 (借鉴[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件)
- [x] 原神便笺查询 - [x] 原神便笺查询
- [x] 原神玩家查询 - [x] 原神玩家查询
- [x] 原神树脂提醒
- [x] 原神签到/自动签到
- [x] 金币红包 - [x] 金币红包
- [x] 微博热搜 - [x] 微博热搜
- [x] B站主播/UP/番剧订阅 - [x] B站主播/UP/番剧订阅
@@ -147,6 +153,7 @@
- [x] 清理临时数据 - [x] 清理临时数据
- [x] 增删群认证 - [x] 增删群认证
- [x] 同意/拒绝好友/群聊请求 - [x] 同意/拒绝好友/群聊请求
- [x] 配置重载
#### 超级用户的被动技能 #### 超级用户的被动技能
- [x] 邀请入群提醒(别人邀请真寻入群) - [x] 邀请入群提醒(别人邀请真寻入群)
@@ -171,6 +178,7 @@
- [x] 群管理员监控,自动为新晋管理员增加权限,为失去群管理员的用户删除权限 - [x] 群管理员监控,自动为新晋管理员增加权限,为失去群管理员的用户删除权限
- [x] 群权限系统 - [x] 群权限系统
- [x] 定时更新权限 - [x] 定时更新权限
- [x] 自动配置重载
</details> </details>
## 详细配置请前往文档,以下为最简部署和配置,如果你有基础并学习过nonebot2的话 ## 详细配置请前往文档,以下为最简部署和配置,如果你有基础并学习过nonebot2的话
@@ -183,7 +191,7 @@
# 配置gocq # 配置gocq
在 https://github.com/Mrs4s/go-cqhttp 下载Releases最新版本,运行后选择反向代理, 在 https://github.com/Mrs4s/go-cqhttp 下载Releases最新版本,运行后选择反向代理,
后将gocq的配置文件config.yml中的universal改为universal: ws://127.0.0.1:8080/cqhttp/ws 后将gocq的配置文件config.yml中的universal改为universal: ws://127.0.0.1:8080/onebot/v11/ws
# 获取代码 # 获取代码
git clone https://github.com/HibiKier/zhenxun_bot.git git clone https://github.com/HibiKier/zhenxun_bot.git
@@ -192,12 +200,14 @@ git clone https://github.com/HibiKier/zhenxun_bot.git
cd zhenxun_bot cd zhenxun_bot
# 安装依赖 # 安装依赖
pip install -r requirements.txt pip install poetry # 安装 poetry
poetry install # 安装依赖
# 进行基础配置 # 进行基础配置
####请查看 配置 部分#### ####请查看 配置 部分####
# 开始运行 # 开始运行
poetry shell # 进入虚拟环境
python bot.py python bot.py
``` ```
@@ -217,11 +227,107 @@ 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)
## 更新 ## 更新
### 2021/1/5 \[v0.0.7.2] ### 2022/2/25 \[v0.1.4]
* PIX提供配置MAX_ONCE_NUM2FORWARD:当单次发送图片超过指定张数且在群聊时,将转为合并消息
* 优化抽卡
* 修复点歌无法正确发送
* 修复我有一个朋友有时文本会包含CQ码
* 修复群欢消息被动控制文本未删除 [@pull/124](https://github.com/HibiKier/zhenxun_bot/pull/124)
* message_builder.image不再提供参数:abspath
### 2022/2/23
* 插件状态将从已加载插件模块中读取
* 修复b站订阅插件订阅失败问题
* 修复重启命令无法使用
### 2022/2/21 \[v0.1.3.2]
* 群权限为-1时,超级用户发送的命令依旧生效
* 当群权限为-1时,被动技能也将不会发送
* 修复功能开关,b站转发解析,复读 ignore无法使用
* 修复色图下载文件名与路径错误
* 修复被动技能提醒有时无法删除控制文本
### 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]
* 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币 * 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币
* 商店插件将作为内置插件移动至basic_plugins * 商店插件将作为内置插件移动至basic_plugins
@@ -277,7 +383,6 @@ __..... 更多更新信息请查看文档__
## Todo ## Todo
- [ ] docker容器
- [ ] web管理 - [ ] web管理
## 感谢 ## 感谢
@@ -292,5 +397,5 @@ __..... 更多更新信息请查看文档__
[H-K-Y / Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot) :原神bot,这是一个基于nonebot和HoshinoBot的原神娱乐及信息查询插件 [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机器人框架的鲁迅说插件 [NothAmor / nonebot2_luxun_says](https://github.com/NothAmor/nonebot2_luxun_says) :基于nonebot2机器人框架的鲁迅说插件
[Kyomotoi / AnimeThesaurus](https://github.com/Kyomotoi/AnimeThesaurus) :一个~~特二刺螈~~(文爱)的适用于任何bot的词库 [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查询插件 [KimigaiiWuyi / GenshinUID]("https://github.com/KimigaiiWuyi/GenshinUID") :一个基于HoshinoBot/NoneBot2的原神UID查询插件
+1 -1
View File
@@ -1 +1 @@
__version__: v0.0.8.0 __version__: v0.1.4
@@ -1,319 +1,323 @@
from typing import List from typing import List
from nonebot.adapters.cqhttp.message import MessageSegment from nonebot.adapters.onebot.v11.message import MessageSegment
from services.log import logger from services.log import logger
from configs.path_config import DATA_PATH from configs.path_config import DATA_PATH
from utils.message_builder import image from utils.message_builder import image
from utils.utils import get_local_proxy, get_bot from utils.utils import get_bot, get_matchers
from pathlib import Path from pathlib import Path
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from datetime import datetime from datetime import datetime
from services.db_context import db from services.db_context import db
from models.level_user import LevelUser from models.level_user import LevelUser
from configs.config import Config from configs.config import Config
from utils.manager import group_manager, plugins2settings_manager, plugins_manager from utils.manager import group_manager, plugins2settings_manager, plugins_manager
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
import asyncio import asyncio
import time import time
import os import os
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
async def group_current_status(group_id: int) -> str: async def group_current_status(group_id: int) -> str:
""" """
获取当前所有通知的开关 获取当前所有通知的开关
:param group_id: 群号 :param group_id: 群号
""" """
rst = "[被动技能 状态]\n" rst = "[被动技能 状态]\n"
_data = group_manager.get_task_data() _data = group_manager.get_task_data()
for task in _data.keys(): for task in _data.keys():
rst += f'{_data[task]}: {"√" if await group_manager.check_group_task_status(group_id, task) else "×"}\n' rst += f'{_data[task]}: {"√" if await group_manager.check_group_task_status(group_id, task) else "×"}\n'
return rst.strip() return rst.strip()
custom_welcome_msg_json = ( custom_welcome_msg_json = (
Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json" Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json"
) )
async def custom_group_welcome( async def custom_group_welcome(
msg: str, imgs: List[str], user_id: int, group_id: int msg: str, imgs: List[str], user_id: int, group_id: int
) -> str: ) -> str:
""" """
替换群欢迎消息 替换群欢迎消息
:param msg: 欢迎消息文本 :param msg: 欢迎消息文本
:param imgs: 欢迎消息图片,只取第一张 :param imgs: 欢迎消息图片,只取第一张
:param user_id: 用户id,用于log记录 :param user_id: 用户id,用于log记录
:param group_id: 群号 :param group_id: 群号
""" """
img_result = "" img_result = ""
img = imgs[0] if imgs else "" img = imgs[0] if imgs else ""
result = "" result = ""
if os.path.exists(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg"): if (DATA_PATH / f"custom_welcome_msg/{group_id}.jpg").exists():
os.remove(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg") (DATA_PATH / f"custom_welcome_msg/{group_id}.jpg").unlink()
if not custom_welcome_msg_json.exists(): if not custom_welcome_msg_json.exists():
custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True) custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True)
data = {} data = {}
else: else:
try: try:
data = json.load(open(custom_welcome_msg_json, "r")) data = json.load(open(custom_welcome_msg_json, "r"))
except FileNotFoundError: except FileNotFoundError:
data = {} data = {}
try: try:
if msg: if msg:
data[str(group_id)] = str(msg) data[str(group_id)] = str(msg)
json.dump( json.dump(
data, open(custom_welcome_msg_json, "w"), indent=4, ensure_ascii=False data, open(custom_welcome_msg_json, "w"), indent=4, ensure_ascii=False
) )
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}") logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}")
result += msg result += msg
if img: if img:
await AsyncHttpx.download_file( await AsyncHttpx.download_file(
img, DATA_PATH + f"custom_welcome_msg/{group_id}.jpg" img, DATA_PATH / "custom_welcome_msg" / f"{group_id}.jpg"
) )
img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg") img_result = image(DATA_PATH / "custom_welcome_msg" / f"{group_id}.jpg")
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片") logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
except Exception as e: except Exception as e:
logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}") logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}")
return "替换群消息失败.." return "替换群消息失败.."
return f"替换群欢迎消息成功:\n{result}" + img_result return f"替换群欢迎消息成功:\n{result}" + img_result
task_data = None task_data = None
async def change_group_switch(cmd: str, group_id: int, is_super: bool = False): async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
global task_data global task_data
""" """
修改群功能状态 修改群功能状态
:param cmd: 功能名称 :param cmd: 功能名称
:param group_id: 群号 :param group_id: 群号
:param is_super: 是否位超级用户,超级用户用于私聊开关功能状态 :param is_super: 是否位超级用户,超级用户用于私聊开关功能状态
""" """
if not task_data: if not task_data:
task_data = group_manager.get_task_data() task_data = group_manager.get_task_data()
group_help_file = Path(DATA_PATH) / "group_help" / f"{group_id}.png" group_help_file = DATA_PATH / "group_help" / f"{group_id}.png"
status = cmd[:2] status = cmd[:2]
cmd = cmd[2:] cmd = cmd[2:]
type_ = "plugin" type_ = "plugin"
modules = plugins2settings_manager.get_plugin_module(cmd, True) modules = plugins2settings_manager.get_plugin_module(cmd, True)
if cmd == "全部被动": if cmd == "全部被动":
for task in task_data: for task in task_data:
if status == "开启": if status == "开启":
if not await group_manager.check_group_task_status(group_id, task): if not await group_manager.check_group_task_status(group_id, task):
await group_manager.open_group_task(group_id, task) await group_manager.open_group_task(group_id, task)
else: else:
if await group_manager.check_group_task_status(group_id, task): if await group_manager.check_group_task_status(group_id, task):
await group_manager.close_group_task(group_id, task) await group_manager.close_group_task(group_id, task)
if group_help_file.exists(): if group_help_file.exists():
group_help_file.unlink() group_help_file.unlink()
return f"已 {status} 全部被动技能!" return f"已 {status} 全部被动技能!"
if cmd == "全部功能": if cmd == "全部功能":
for f in plugins2settings_manager.get_data(): for f in plugins2settings_manager.get_data():
if status == "开启": if status == "开启":
group_manager.unblock_plugin(f, group_id) group_manager.unblock_plugin(f, group_id)
else: else:
group_manager.block_plugin(f, group_id) group_manager.block_plugin(f, group_id)
return f"已 {status} 全部功能!" return f"已 {status} 全部功能!"
if cmd in [task_data[x] for x in task_data.keys()]: if cmd in [task_data[x] for x in task_data.keys()]:
type_ = "task" type_ = "task"
modules = [x for x in task_data.keys() if task_data[x] == cmd] modules = [x for x in task_data.keys() if task_data[x] == cmd]
for module in modules: for module in modules:
if is_super: if is_super:
module = f"{module}:super" module = f"{module}:super"
if status == "开启": if status == "开启":
if type_ == "task": if type_ == "task":
if await group_manager.check_group_task_status(group_id, module): if await group_manager.check_group_task_status(group_id, module):
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启." return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
await group_manager.open_group_task(group_id, module) await group_manager.open_group_task(group_id, module)
else: else:
if group_manager.get_plugin_status(module, group_id): if group_manager.get_plugin_status(module, group_id):
return f"功能 {cmd} 正处于开启状态!不要重复开启." return f"功能 {cmd} 正处于开启状态!不要重复开启."
group_manager.unblock_plugin(module, group_id) group_manager.unblock_plugin(module, group_id)
else: else:
if type_ == "task": if type_ == "task":
if not await group_manager.check_group_task_status(group_id, module): if not await group_manager.check_group_task_status(group_id, module):
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭." return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
await group_manager.close_group_task(group_id, module) await group_manager.close_group_task(group_id, module)
else: else:
if not group_manager.get_plugin_status(module, group_id): if not group_manager.get_plugin_status(module, group_id):
return f"功能 {cmd} 正处于关闭状态!不要重复关闭." return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
group_manager.block_plugin(module, group_id) group_manager.block_plugin(module, group_id)
if group_help_file.exists(): if group_help_file.exists():
group_help_file.unlink() group_help_file.unlink()
if is_super: if is_super:
for file in os.listdir(Path(DATA_PATH) / "group_help"): for file in os.listdir(DATA_PATH / "group_help"):
file = Path(DATA_PATH) / "group_help" / file file = DATA_PATH / "group_help" / file
file.unlink() file.unlink()
else: else:
_help_image = Path(DATA_PATH) / "group_help" / f"{group_id}.png" _help_image = DATA_PATH / "group_help" / f"{group_id}.png"
if _help_image.exists(): if _help_image.exists():
_help_image.unlink() _help_image.unlink()
return f"{status} {cmd} 功能!" return f"{status} {cmd} 功能!"
def set_plugin_status(cmd: str, block_type: str = "all"): def set_plugin_status(cmd: str, block_type: str = "all"):
""" """
设置插件功能状态(超级用户使用) 设置插件功能状态(超级用户使用)
:param cmd: 功能名称 :param cmd: 功能名称
:param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊 :param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊
""" """
status = cmd[:2] status = cmd[:2]
cmd = cmd[2:] cmd = cmd[2:]
module = plugins2settings_manager.get_plugin_module(cmd) module = plugins2settings_manager.get_plugin_module(cmd)
if status == "开启": if status == "开启":
plugins_manager.unblock_plugin(module) plugins_manager.unblock_plugin(module)
else: else:
plugins_manager.block_plugin(module, block_type=block_type) plugins_manager.block_plugin(module, block_type=block_type)
for file in os.listdir(Path(DATA_PATH) / "group_help"): for file in os.listdir(DATA_PATH / "group_help"):
file = Path(DATA_PATH) / "group_help" / file file = DATA_PATH / "group_help" / file
file.unlink() file.unlink()
async def get_plugin_status(): async def get_plugin_status():
""" """
获取功能状态 获取功能状态
""" """
return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status) return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status)
def _get_plugin_status() -> MessageSegment: def _get_plugin_status() -> MessageSegment:
""" """
合成功能状态图片 合成功能状态图片
""" """
rst = "\t功能\n" rst = "\t功能\n"
flag_str = "状态".rjust(4) + "\n" flag_str = "状态".rjust(4) + "\n"
for module in plugins_manager.get_data(): tmp_name = []
flag = plugins_manager.get_plugin_block_type(module) for matcher in get_matchers():
flag = flag.upper() + " CLOSE" if flag else "OPEN" if matcher.plugin_name not in tmp_name:
try: tmp_name.append(matcher.plugin_name)
plugin_name = plugins_manager.get(module)["plugin_name"] module = matcher.plugin_name
if ( flag = plugins_manager.get_plugin_block_type(module)
"[Hidden]" in plugin_name flag = flag.upper() + " CLOSE" if flag else "OPEN"
or "[Admin]" in plugin_name try:
or "[Superuser]" in plugin_name plugin_name = plugins_manager.get(module)["plugin_name"]
): if (
continue "[Hidden]" in plugin_name
rst += f"{plugin_name}" or "[Admin]" in plugin_name
except KeyError: or "[Superuser]" in plugin_name
rst += f"{module}" ):
if plugins_manager.get(module)["error"]: continue
rst += "[ERROR]" rst += f"{plugin_name}"
rst += "\n" except KeyError:
flag_str += f"{flag}\n" rst += f"{module}"
height = len(rst.split("\n")) * 24 if plugins_manager.get(module)["error"]:
a = BuildImage(250, height, font_size=20) rst += "[ERROR]"
a.text((10, 10), rst) rst += "\n"
b = BuildImage(200, height, font_size=20) flag_str += f"{flag}\n"
b.text((10, 10), flag_str) height = len(rst.split("\n")) * 24
A = BuildImage(500, height) a = BuildImage(250, height, font_size=20)
A.paste(a) a.text((10, 10), rst)
A.paste(b, (270, 0)) b = BuildImage(200, height, font_size=20)
return image(b64=A.pic2bs4()) b.text((10, 10), flag_str)
A = BuildImage(500, height)
A.paste(a)
async def update_member_info(group_id: int, remind_superuser: bool = False) -> bool: A.paste(b, (270, 0))
""" return image(b64=A.pic2bs4())
更新群成员信息
:param group_id: 群号
:param remind_superuser: 失败信息提醒超级用户 async def update_member_info(group_id: int, remind_superuser: bool = False) -> bool:
""" """
bot = get_bot() 更新群成员信息
_group_user_list = await bot.get_group_member_list(group_id=group_id) :param group_id: 群号
_error_member_list = [] :param remind_superuser: 失败信息提醒超级用户
_exist_member_list = [] """
# try: bot = get_bot()
for user_info in _group_user_list: _group_user_list = await bot.get_group_member_list(group_id=group_id)
if user_info["card"] == "": _error_member_list = []
nickname = user_info["nickname"] _exist_member_list = []
else: # try:
nickname = user_info["card"] for user_info in _group_user_list:
async with db.transaction(): if user_info["card"] == "":
# 更新权限 nickname = user_info["nickname"]
if ( else:
user_info["role"] nickname = user_info["card"]
in [ async with db.transaction():
"owner", # 更新权限
"admin", if (
] user_info["role"]
and not await LevelUser.is_group_flag(user_info["user_id"], group_id) in [
): "owner",
await LevelUser.set_level( "admin",
user_info["user_id"], ]
user_info["group_id"], and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"), ):
) await LevelUser.set_level(
if str(user_info["user_id"]) in bot.config.superusers: user_info["user_id"],
await LevelUser.set_level( user_info["group_id"],
user_info["user_id"], user_info["group_id"], 9 Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"),
) )
user = await GroupInfoUser.get_member_info( if str(user_info["user_id"]) in bot.config.superusers:
user_info["user_id"], user_info["group_id"] await LevelUser.set_level(
) user_info["user_id"], user_info["group_id"], 9
if user: )
if user.user_name != nickname: user = await GroupInfoUser.get_member_info(
await user.update(user_name=nickname).apply() user_info["user_id"], user_info["group_id"]
logger.info( )
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功" if user:
) if user.user_name != nickname:
_exist_member_list.append(int(user_info["user_id"])) await user.update(user_name=nickname).apply()
continue logger.info(
join_time = datetime.strptime( f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功"
time.strftime( )
"%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"]) _exist_member_list.append(int(user_info["user_id"]))
), continue
"%Y-%m-%d %H:%M:%S", join_time = datetime.strptime(
) time.strftime(
if await GroupInfoUser.add_member_info( "%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])
user_info["user_id"], ),
user_info["group_id"], "%Y-%m-%d %H:%M:%S",
nickname, )
join_time, if await GroupInfoUser.add_member_info(
): user_info["user_id"],
_exist_member_list.append(int(user_info["user_id"])) user_info["group_id"],
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功") nickname,
else: join_time,
_error_member_list.append( ):
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n" _exist_member_list.append(int(user_info["user_id"]))
) logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
_del_member_list = list( else:
set(_exist_member_list).difference( _error_member_list.append(
set(await GroupInfoUser.get_group_member_id_list(group_id)) f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n"
) )
) _del_member_list = list(
if _del_member_list: set(_exist_member_list).difference(
for del_user in _del_member_list: set(await GroupInfoUser.get_group_member_id_list(group_id))
if await GroupInfoUser.delete_member_info(del_user, group_id): )
logger.info(f"退群用户{del_user} 所属{group_id} 已删除") )
else: if _del_member_list:
logger.info(f"退群用户{del_user} 所属{group_id} 删除失败") for del_user in _del_member_list:
if _error_member_list and remind_superuser: if await GroupInfoUser.delete_member_info(del_user, group_id):
result = "" logger.info(f"退群用户{del_user} 所属{group_id} 已删除")
for error_user in _error_member_list: else:
result += error_user logger.info(f"退群用户{del_user} 所属{group_id} 删除失败")
await bot.send_private_msg( if _error_member_list and remind_superuser:
user_id=int(list(bot.config.superusers)[0]), message=result[:-1] result = ""
) for error_user in _error_member_list:
return True result += error_user
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
def set_group_bot_status(group_id: int, status: bool) -> str: )
""" return True
设置群聊bot开关状态
:param group_id: 群号
:param status: 状态 def set_group_bot_status(group_id: int, status: bool) -> str:
""" """
if status: 设置群聊bot开关状态
if group_manager.check_group_bot_status(group_id): :param group_id: 群号
return "我还醒着呢!" :param status: 状态
group_manager.turn_on_group_bot_status(group_id) """
return "呜..醒来了..." if status:
else: if group_manager.check_group_bot_status(group_id):
group_manager.shutdown_group_bot_status(group_id) return "我还醒着呢!"
# for x in group_manager.get_task_data(): group_manager.turn_on_group_bot_status(group_id)
# group_manager.close_group_task(group_id, x) return "呜..醒来了..."
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,7 +1,6 @@
from nonebot import on_notice from nonebot import on_notice
from services.log import logger from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupAdminNoticeEvent from nonebot.adapters.onebot.v11 import GroupAdminNoticeEvent
from nonebot.typing import T_State
from models.level_user import LevelUser from models.level_user import LevelUser
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from configs.config import Config from configs.config import Config
@@ -16,7 +15,7 @@ admin_notice = on_notice(priority=5)
@admin_notice.handle() @admin_notice.handle()
async def _(bot: Bot, event: GroupAdminNoticeEvent, state: T_State): async def _(event: GroupAdminNoticeEvent):
try: try:
nickname = ( nickname = (
await GroupInfoUser.get_member_info(event.user_id, event.group_id) await GroupInfoUser.get_member_info(event.user_id, event.group_id)
@@ -1,9 +1,9 @@
from nonebot import on_command from nonebot import on_command
from utils.utils import get_message_text, get_message_imgs from utils.utils import get_message_img
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent from nonebot.params import CommandArg
from .data_source import custom_group_welcome from ._data_source import custom_group_welcome
from nonebot.adapters.cqhttp.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
from configs.config import Config from configs.config import Config
from services.log import logger from services.log import logger
@@ -35,14 +35,14 @@ custom_welcome = on_command(
@custom_welcome.handle() @custom_welcome.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
try: try:
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
imgs = get_message_imgs(event.json()) img = get_message_img(event.json())
if not msg and not imgs: if not msg and not img:
await custom_welcome.finish(__plugin_usage__) await custom_welcome.finish(__plugin_usage__)
await custom_welcome.send( await custom_welcome.send(
await custom_group_welcome(msg, imgs, event.user_id, event.group_id), await custom_group_welcome(msg, img, event.user_id, event.group_id),
at_sender=True, at_sender=True,
) )
logger.info(f"USER {event.user_id} GROUP {event.group_id} 自定义群欢迎消息:{msg}") logger.info(f"USER {event.user_id} GROUP {event.group_id} 自定义群欢迎消息:{msg}")
+2 -5
View File
@@ -1,5 +1,4 @@
from nonebot.adapters.cqhttp import Bot, Event from nonebot.adapters.onebot.v11 import Event
from nonebot.typing import T_State
from utils.manager import group_manager, plugins2settings_manager from utils.manager import group_manager, plugins2settings_manager
from utils.utils import get_message_text from utils.utils import get_message_text
from services.log import logger from services.log import logger
@@ -7,12 +6,10 @@ from services.log import logger
cmd = [] cmd = []
def switch_rule(bot: Bot, event: Event, state: T_State) -> bool: def switch_rule(event: Event) -> bool:
""" """
检测文本是否是关闭功能命令 检测文本是否是关闭功能命令
:param bot: pass
:param event: pass :param event: pass
:param state: pass
""" """
global cmd global cmd
try: try:
+16 -17
View File
@@ -1,7 +1,7 @@
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent, GROUP
from nonebot import on_command, on_message, on_regex from nonebot import on_command, on_message, on_regex
from nonebot.typing import T_State from nonebot.params import RegexGroup
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent, GROUP from ._data_source import (
from .data_source import (
change_group_switch, change_group_switch,
set_plugin_status, set_plugin_status,
get_plugin_status, get_plugin_status,
@@ -12,8 +12,8 @@ from services.log import logger
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
from utils.utils import get_message_text, is_number from utils.utils import get_message_text, is_number
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from typing import Tuple, Any
from .rule import switch_rule from .rule import switch_rule
import re
__zx_plugin_name__ = "群功能开关 [Admin]" __zx_plugin_name__ = "群功能开关 [Admin]"
@@ -65,7 +65,7 @@ group_status = on_regex("^(休息吧|醒来)$", permission=GROUP, priority=5, bl
@switch_rule_matcher.handle() @switch_rule_matcher.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent):
_cmd = get_message_text(event.json()).split()[0] _cmd = get_message_text(event.json()).split()[0]
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
await switch_rule_matcher.send(await change_group_switch(_cmd, event.group_id)) await switch_rule_matcher.send(await change_group_switch(_cmd, event.group_id))
@@ -77,7 +77,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
if is_number(block_type): if is_number(block_type):
if not int(block_type) in [ if not int(block_type) in [
g["group_id"] g["group_id"]
for g in await bot.get_group_list(self_id=int(bot.self_id)) for g in await bot.get_group_list()
]: ]:
await switch_rule_matcher.finish(f"{NICKNAME}未加入群聊:{block_type}") await switch_rule_matcher.finish(f"{NICKNAME}未加入群聊:{block_type}")
await change_group_switch(_cmd, int(block_type), True) await change_group_switch(_cmd, int(block_type), True)
@@ -104,22 +104,21 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@plugins_status.handle() @plugins_status.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
await plugins_status.send(await get_plugin_status()) await plugins_status.send(await get_plugin_status())
@group_task_status.handle() @group_task_status.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
await group_task_status.send(await group_current_status(event.group_id)) await group_task_status.send(await group_current_status(event.group_id))
@group_status.handle() @group_status.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent, reg_group: Tuple[Any, ...] = RegexGroup()):
r = re.search("^(休息吧|醒来)$", get_message_text(event.json())) cmd = reg_group[0]
if r: if cmd == "休息吧":
if r.group(1) == "休息吧": msg = set_group_bot_status(event.group_id, False)
msg = set_group_bot_status(event.group_id, False) else:
else: msg = set_group_bot_status(event.group_id, True)
msg = set_group_bot_status(event.group_id, True) await group_status.send(msg)
await group_status.send(msg) logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用总开关命令:{cmd}")
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 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 services.log import logger
from models.group_info import GroupInfo from models.group_info import GroupInfo
from asyncpg.exceptions import ConnectionDoesNotExistError, UndefinedColumnError from asyncpg.exceptions import ConnectionDoesNotExistError, UndefinedColumnError
@@ -1,7 +1,6 @@
from nonebot import on_command, on_notice from nonebot import on_command, on_notice
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, GROUP, GroupIncreaseNoticeEvent
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, GROUP, GroupIncreaseNoticeEvent from ._data_source import update_member_info
from .data_source import update_member_info
__zx_plugin_name__ = "更新群组成员列表 [Admin]" __zx_plugin_name__ = "更新群组成员列表 [Admin]"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -25,7 +24,7 @@ refresh_member_group = on_command(
@refresh_member_group.handle() @refresh_member_group.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
if await update_member_info(event.group_id): if await update_member_info(event.group_id):
await refresh_member_group.finish("更新群员信息成功!", at_sender=True) await refresh_member_group.finish("更新群员信息成功!", at_sender=True)
else: else:
@@ -36,6 +35,6 @@ group_increase_handle = on_notice(priority=1, block=False)
@group_increase_handle.handle() @group_increase_handle.handle()
async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict): async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
if event.user_id == int(bot.self_id): if event.user_id == int(bot.self_id):
await update_member_info(event.group_id) await update_member_info(event.group_id)
+1 -1
View File
@@ -1,7 +1,7 @@
from nonebot import on_command from nonebot import on_command
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters import Bot from nonebot.adapters import Bot
from nonebot.adapters.cqhttp import GroupMessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent
from utils.message_builder import image from utils.message_builder import image
from .data_source import create_help_image, admin_help_image from .data_source import create_help_image, admin_help_image
+5 -6
View File
@@ -3,8 +3,7 @@ from configs.path_config import IMAGE_PATH
from services.log import logger from services.log import logger
from utils.utils import get_matchers from utils.utils import get_matchers
from utils.manager import group_manager from utils.manager import group_manager
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.onebot.v11 import Bot
from pathlib import Path
from nonebot import Driver from nonebot import Driver
import asyncio import asyncio
import nonebot import nonebot
@@ -12,9 +11,9 @@ import nonebot
driver: Driver = nonebot.get_driver() driver: Driver = nonebot.get_driver()
background = Path(IMAGE_PATH) / "background" / "0.png" background = IMAGE_PATH / "background" / "0.png"
admin_help_image = Path(IMAGE_PATH) / 'admin_help_img.png' admin_help_image = IMAGE_PATH / 'admin_help_img.png'
@driver.on_bot_connect @driver.on_bot_connect
@@ -42,7 +41,7 @@ def _create_help_image():
width = 0 width = 0
_plugin_level = {} _plugin_level = {}
for matcher in _matchers: for matcher in _matchers:
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
_module = _plugin.module _module = _plugin.module
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
@@ -71,7 +70,7 @@ def _create_help_image():
x = len(f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)) * 23 x = len(f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)) * 23
width = width if width > x else x width = width if width > x else x
except AttributeError: except AttributeError:
logger.warning(f"获取管理插件 {matcher.module}: {plugin_name} 设置失败...") logger.warning(f"获取管理插件 {matcher.plugin_name}: {plugin_name} 设置失败...")
help_str = "* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" \ help_str = "* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" \
"[权限等级] 管理员帮助:\n\n" "[权限等级] 管理员帮助:\n\n"
x = list(_plugin_level.keys()) x = list(_plugin_level.keys())
+13 -15
View File
@@ -4,7 +4,7 @@ from nonebot import on_message
from services.log import logger from services.log import logger
from models.group_info import GroupInfo from models.group_info import GroupInfo
from models.friend_user import FriendUser from models.friend_user import FriendUser
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
from utils.manager import group_manager from utils.manager import group_manager
from pathlib import Path from pathlib import Path
@@ -57,12 +57,11 @@ async def _():
gl = await bot.get_group_list() gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl] gl = [g["group_id"] for g in gl]
for g in gl: for g in gl:
if await group_manager.check_group_task_status(g, 'zwa'): result = image("zao.jpg", "zhenxun")
result = image("zao.jpg", "zhenxun") try:
try: await bot.send_group_msg(group_id=g, message="[[_task|zwa]]早上好" + result)
await bot.send_group_msg(group_id=g, message="早上好" + result) except ActionFailed:
except ActionFailed: logger.warning(f"{g} 群被禁言中,无法发送早安")
logger.warning(f"{g} 群被禁言中,无法发送早安")
except Exception as e: except Exception as e:
logger.error(f"早晚安错误 e:{e}") logger.error(f"早晚安错误 e:{e}")
@@ -79,14 +78,13 @@ async def _():
gl = await bot.get_group_list() gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl] gl = [g["group_id"] for g in gl]
for g in gl: for g in gl:
if await group_manager.check_group_task_status(g, 'zwa'): result = image("sleep.jpg", "zhenxun")
result = image("sleep.jpg", "zhenxun") try:
try: await bot.send_group_msg(
await bot.send_group_msg( group_id=g, message=f"[[_task|zwa]]{NICKNAME}要睡觉了,你们也要早点睡呀" + result
group_id=g, message=f"{NICKNAME}要睡觉了,你们也要早点睡呀" + result )
) except ActionFailed:
except ActionFailed: logger.warning(f"{g} 群被禁言中,无法发送晚安")
logger.warning(f"{g} 群被禁言中,无法发送晚安")
except Exception as e: except Exception as e:
logger.error(f"早晚安错误 e:{e}") logger.error(f"早晚安错误 e:{e}")
+47 -98
View File
@@ -1,12 +1,13 @@
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent, MessageEvent, Message, Bot
from nonebot.params import CommandArg, Command
from nonebot import on_command from nonebot import on_command
from models.ban_user import BanUser from models.ban_user import BanUser
from models.level_user import LevelUser from models.level_user import LevelUser
from nonebot.typing import T_State from typing import Tuple
from nonebot.adapters.cqhttp import Bot from utils.utils import get_message_at, is_number
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 configs.config import NICKNAME, Config
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from .data_source import parse_ban_time, a_ban
from services.log import logger from services.log import logger
@@ -61,62 +62,35 @@ super_ban = on_command('b了', permission=SUPERUSER, priority=5, block=True)
@ban.handle() @ban.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
cmd = cmd[0]
result = "" result = ""
qq = get_message_at(event.json()) qq = get_message_at(event.json())
if qq: if qq:
qq = qq[0] qq = qq[0]
user_name = await bot.get_group_member_info(group_id=event.group_id, user_id=qq) user_name = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
user_name = user_name['card'] if user_name['card'] else user_name['nickname'] user_name = user_name['card'] or user_name['nickname']
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if msg: time = parse_ban_time(msg)
msg = msg.split() if isinstance(time, str):
if len(msg) == 2: await ban.finish(time, at_sender=True)
if not is_number(msg[0].strip()) or not is_number(msg[1].strip()): if cmd in [".ban", "/ban"]:
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 ( if (
await LevelUser.get_user_level(event.user_id, event.group_id) await LevelUser.get_user_level(event.user_id, event.group_id)
<= await LevelUser.get_user_level(qq, event.group_id) <= await LevelUser.get_user_level(qq, event.group_id)
and str(event.user_id) not in bot.config.superusers and str(event.user_id) not in bot.config.superusers
): ):
await ban.finish( await ban.finish(
f"您的权限等级比对方低或相等, {NICKNAME}不能为您使用此功能!", f"您的权限等级比对方低或相等, {NICKNAME}不能为您使用此功能!",
at_sender=True, at_sender=True,
) )
if await BanUser.ban( result = await a_ban(qq, time, user_name, event)
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: else:
if ( if (
await BanUser.check_ban_level( await BanUser.check_ban_level(
qq, await LevelUser.get_user_level(event.user_id, event.group_id) qq, await LevelUser.get_user_level(event.user_id, event.group_id)
) )
and str(event.user_id) not in bot.config.superusers and str(event.user_id) not in bot.config.superusers
): ):
await ban.finish( await ban.finish(
f"ban掉 {user_name} 的管理员权限比您高,无法进行unban", at_sender=True f"ban掉 {user_name} 的管理员权限比您高,无法进行unban", at_sender=True
@@ -130,78 +104,53 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
result = f"{user_name} 不在黑名单!" result = f"{user_name} 不在黑名单!"
else: else:
await ban.finish("艾特人了吗??", at_sender=True) await ban.finish("艾特人了吗??", at_sender=True)
await ban.finish(result, at_sender=True) await ban.send(result, at_sender=True)
@ban.handle() @ban.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(bot: Bot, event: PrivateMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
if str(event.user_id) in bot.config.superusers: cmd = cmd[0]
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
msg = msg.split() if msg:
if is_number(msg[0]): if str(event.user_id) in bot.config.superusers:
qq = int(msg[0]) if is_number(arg.extract_plain_text().strip().split()[0]):
if state["_prefix"]["raw_command"] in [".ban", "/ban"]: qq = int(msg[0])
hour = 0 msg = msg[1:]
minute = 0 if cmd in [".ban", "/ban"]:
if len(msg) > 1 and is_number(msg[1]): time = parse_ban_time(msg)
hour = int(msg[1]) if isinstance(time, str):
if len(msg) > 2 and is_number(msg[2]): await ban.finish(time)
minute = int(msg[2]) result = await a_ban(qq, time, str(qq), event, 9)
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"将在 ∞ 分钟后解封"
await ban.send(result)
else: else:
time = await BanUser.check_ban_time(qq) if await BanUser.unban(qq):
if is_number(time): logger.info(
time = abs(int(time)) f"USER {event.user_id} 将 USER {qq} 解禁"
if time < 60: )
time = str(time) + " 秒" result = f"已经把 {qq} 从黑名单中删除了!"
else:
time = str(int(time / 60)) + " 分钟"
else: else:
time += " 分钟" result = f"{qq} 不在黑名单!"
await ban.send(f"{qq} 已在黑名单!预计 {time}后解封")
else:
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) await ban.send(result)
else: else:
await ban.finish('qq号必须是数字!\n格式:.ban [qq] [hour]? [minute]?', at_sender=True) await ban.finish('qq号必须是数字!\n格式:.ban [qq] [hour]? [minute]?', at_sender=True)
@super_ban.handle() @super_ban.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
qq = get_message_at(event.json()) qq = get_message_at(event.json())
else: else:
qq = get_message_text(event.json()) qq = arg.extract_plain_text().strip()
if not is_number(qq): if not is_number(qq):
await super_ban.finish("对象qq必须为纯数字...") await super_ban.finish("对象qq必须为纯数字...")
qq = [qq] qq = [qq]
if qq: if qq:
qq = qq[0] qq = qq[0]
user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq) user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
user_name = user['card'] if user['card'] else user['nickname'] user_name = user['card'] or user['nickname']
if not await BanUser.ban(qq, 10, 99999999): if not await BanUser.ban(qq, 10, 99999999):
await BanUser.unban(qq) await BanUser.unban(qq)
await BanUser.ban(qq, 10, 99999999) await BanUser.ban(qq, 10, 99999999)
await ban.send(f"已将 {user_name} 拉入黑名单!") await ban.send(f"已将 {user_name} 拉入黑名单!")
else: else:
await super_ban.send('需要艾特被super ban的对象..') await super_ban.send('需要添加被super ban的对象,可以使用at或者指定qq..')
+69
View File
@@ -0,0 +1,69 @@
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
+11 -11
View File
@@ -1,13 +1,14 @@
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent
from nonebot import on_command from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
import asyncio from nonebot.params import CommandArg
from utils.utils import get_message_text, get_message_imgs from utils.utils import get_message_img
from services.log import logger from services.log import logger
from utils.message_builder import image from utils.message_builder import image
from utils.manager import group_manager from utils.manager import group_manager
from configs.config import Config from configs.config import Config
import asyncio
__zx_plugin_name__ = "广播 [Superuser]" __zx_plugin_name__ = "广播 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -33,14 +34,13 @@ broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True)
@broadcast.handle() @broadcast.handle()
async def _(bot: Bot, event: Event, state: T_State): async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
imgs = get_message_imgs(event.json()) img_list = get_message_img(event.json())
rst = "" rst = ""
for img in imgs: for img in img_list:
rst += image(img) rst += image(img)
sid = bot.self_id gl = await bot.get_group_list()
gl = await bot.get_group_list(self_id=sid)
gl = [ gl = [
g["group_id"] g["group_id"]
for g in gl for g in gl
@@ -56,7 +56,7 @@ async def _(bot: Bot, event: Event, state: T_State):
await broadcast.send(f"已播报至 {int(cnt / g_cnt * 100)}% 的群聊") await broadcast.send(f"已播报至 {int(cnt / g_cnt * 100)}% 的群聊")
x += 0.25 x += 0.25
try: try:
await bot.send_group_msg(self_id=sid, group_id=g, message=msg + rst) await bot.send_group_msg(group_id=g, message=msg + rst)
logger.info(f"GROUP {g} 投递广播成功") logger.info(f"GROUP {g} 投递广播成功")
except Exception as e: except Exception as e:
logger.error(f"GROUP {g} 投递广播失败:{type(e)}") logger.error(f"GROUP {g} 投递广播失败:{type(e)}")
+25 -30
View File
@@ -4,12 +4,12 @@ from utils.message_builder import image
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from datetime import datetime from datetime import datetime
from services.log import logger from services.log import logger
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
GroupIncreaseNoticeEvent, GroupIncreaseNoticeEvent,
GroupDecreaseNoticeEvent, GroupDecreaseNoticeEvent,
) )
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from utils.manager import group_manager, plugins2settings_manager, requests_manager from utils.manager import group_manager, plugins2settings_manager, requests_manager
from configs.config import NICKNAME from configs.config import NICKNAME
from models.group_info import GroupInfo from models.group_info import GroupInfo
@@ -66,7 +66,7 @@ add_group = on_request(priority=1, block=False)
@group_increase_handle.handle() @group_increase_handle.handle()
async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict): async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
if event.user_id == int(bot.self_id): if event.user_id == int(bot.self_id):
group = await GroupInfo.get_group_info(event.group_id) group = await GroupInfo.get_group_info(event.group_id)
# 群聊不存在或被强制拉群,退出该群 # 群聊不存在或被强制拉群,退出该群
@@ -112,9 +112,7 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败") logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败")
# 群欢迎消息 # 群欢迎消息
if await group_manager.check_group_task_status( if _flmt.check(event.group_id):
event.group_id, "group_welcome"
) and _flmt.check(event.group_id):
_flmt.start_cd(event.group_id) _flmt.start_cd(event.group_id)
msg = "" msg = ""
img = "" img = ""
@@ -129,23 +127,25 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
if msg.find("[at]") != -1: if msg.find("[at]") != -1:
msg = msg.replace("[at]", "") msg = msg.replace("[at]", "")
at_flag = True at_flag = True
if os.path.exists(DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"): if (DATA_PATH / "custom_welcome_msg" / f"{event.group_id}.jpg").exists():
img = image( img = image(
abspath=DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg" DATA_PATH / "custom_welcome_msg" / f"{event.group_id}.jpg"
) )
if msg or img: if msg or img:
msg = msg.strip() + img
msg = "\n" + msg if at_flag else msg
await group_increase_handle.send( await group_increase_handle.send(
"\n" + msg.strip() + img, at_sender=at_flag "[[_task|group_welcome]]" + msg, at_sender=at_flag
) )
else: else:
await group_increase_handle.send( 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() @group_decrease_handle.handle()
async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict): async def _(bot: Bot, event: GroupDecreaseNoticeEvent):
# 被踢出群 # 被踢出群
if event.sub_type == "kick_me": if event.sub_type == "kick_me":
group_id = event.group_id group_id = event.group_id
@@ -180,21 +180,16 @@ async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict):
logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除成功") logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除成功")
else: else:
logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除失败") logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除失败")
if await group_manager.check_group_task_status( rst = ""
event.group_id, "refund_group_remind" if event.sub_type == "leave":
): rst = f"{user_name}离开了我们..."
rst = "" if event.sub_type == "kick":
if event.sub_type == "leave": operator = await bot.get_group_member_info(
rst = f"{user_name}离开了我们..." user_id=event.operator_id, group_id=event.group_id
if event.sub_type == "kick": )
operator = await bot.get_group_member_info( operator_name = operator["card"] if operator["card"] else operator["nickname"]
user_id=event.operator_id, group_id=event.group_id rst = f"{user_name} 被 {operator_name} 送走了."
) try:
operator_name = ( await group_decrease_handle.send(f"[[_task|refund_group_remind]]{rst}")
operator["card"] if operator["card"] else operator["nickname"] except ActionFailed:
) return
rst = f"{user_name} 被 {operator_name} 送走了."
try:
await group_decrease_handle.send(f"{rst}")
except ActionFailed:
return
+9 -9
View File
@@ -1,24 +1,24 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent GroupMessageEvent,
Message
) )
from nonebot.params import CommandArg
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.rule import to_me from nonebot.rule import to_me
from configs.path_config import IMAGE_PATH, DATA_PATH from configs.path_config import IMAGE_PATH, DATA_PATH
from utils.message_builder import image from utils.message_builder import image
from .data_source import create_help_img, get_plugin_help from .data_source import create_help_img, get_plugin_help
from utils.utils import get_message_text
from pathlib import Path
import os import os
__zx_plugin_name__ = "帮助" __zx_plugin_name__ = "帮助"
group_help_path = Path(DATA_PATH) / "group_help" group_help_path = DATA_PATH / "group_help"
help_image = Path(IMAGE_PATH) / "help.png" help_image = IMAGE_PATH / "help.png"
simple_help_image = Path(IMAGE_PATH) / "simple_help.png" simple_help_image = IMAGE_PATH / "simple_help.png"
if help_image.exists(): if help_image.exists():
help_image.unlink() help_image.unlink()
if simple_help_image.exists(): if simple_help_image.exists():
@@ -44,8 +44,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@simple_help.handle() @simple_help.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
is_super = False is_super = False
if msg: if msg:
if '-super' in msg: if '-super' in msg:
+12 -12
View File
@@ -16,9 +16,9 @@ import nonebot
import os import os
random_bk_path = Path(IMAGE_PATH) / "background" / "help" / "simple_help" random_bk_path = IMAGE_PATH / "background" / "help" / "simple_help"
background = Path(IMAGE_PATH) / "background" / "0.png" background = IMAGE_PATH / "background" / "0.png"
async def create_help_img( async def create_help_img(
@@ -55,7 +55,7 @@ def _create_help_img(
# 插件分类 # 插件分类
for matcher in _matchers: for matcher in _matchers:
plugin_name = None plugin_name = None
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
_module = _plugin.module _module = _plugin.module
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
@@ -74,10 +74,10 @@ def _create_help_img(
plugin_type = ("normal",) plugin_type = ("normal",)
text_type = 0 text_type = 0
if plugins2settings_manager.get( if plugins2settings_manager.get(
matcher.module matcher.plugin_name
) and plugins2settings_manager[matcher.module].get("plugin_type"): ) and plugins2settings_manager[matcher.plugin_name].get("plugin_type"):
plugin_type = tuple( plugin_type = tuple(
plugins2settings_manager.get_plugin_data(matcher.module)[ plugins2settings_manager.get_plugin_data(matcher.plugin_name)[
"plugin_type" "plugin_type"
] ]
) )
@@ -111,7 +111,7 @@ def _create_help_img(
logger.warning(f"{type(e)}: {e}") logger.warning(f"{type(e)}: {e}")
else: else:
matchers_data[plugin_type][plugin_name] = { matchers_data[plugin_type][plugin_name] = {
"module": matcher.module, "modules": matcher.plugin_name,
"des": plugin_des, "des": plugin_des,
"cmd": plugin_cmd, "cmd": plugin_cmd,
"text_type": text_type, "text_type": text_type,
@@ -129,7 +129,7 @@ def _create_help_img(
_des_tmp[plugin_des] = plugin_name _des_tmp[plugin_des] = plugin_name
except AttributeError as e: except AttributeError as e:
if plugin_name not in _plugin_name_tmp: if plugin_name not in _plugin_name_tmp:
logger.warning(f"获取功能 {matcher.module}: {plugin_name} 设置失败...e:{e}") logger.warning(f"获取功能 {matcher.plugin_name}: {plugin_name} 设置失败...e:{e}")
if plugin_name not in _plugin_name_tmp: if plugin_name not in _plugin_name_tmp:
_plugin_name_tmp.append(plugin_name) _plugin_name_tmp.append(plugin_name)
help_img_list = [] help_img_list = []
@@ -147,16 +147,16 @@ def _create_help_img(
# 禁用flag # 禁用flag
flag = True flag = True
if plugins_manager.get_plugin_status( if plugins_manager.get_plugin_status(
matchers_data[type_][k]["module"], "all" matchers_data[type_][k]["modules"], "all"
): ):
flag = False flag = False
if group_id: if group_id:
flag = flag and plugins_manager.get_plugin_status( flag = flag and plugins_manager.get_plugin_status(
matchers_data[type_][k]["module"], "group" matchers_data[type_][k]["modules"], "group"
) )
simple_help_str += ( simple_help_str += (
f"{i+1}.{k}<|_|~|>" f"{i+1}.{k}<|_|~|>"
f"{group_manager.get_plugin_status(matchers_data[type_][k]['module'], group_id) if group_id else '_'}|" f"{group_manager.get_plugin_status(matchers_data[type_][k]['modules'], group_id) if group_id else '_'}|"
f"{flag}\n" f"{flag}\n"
) )
if matchers_data[type_][k]["text_type"] == 1: 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( bk = BuildImage(
width, width,
height, height,
background=Path(IMAGE_PATH) / "background" / "1.png", background=IMAGE_PATH / "background" / "1.png",
) )
A.paste(bk, alpha=True) A.paste(bk, alpha=True)
A.text((int(width * 0.048), int(height * 0.21)), result) A.text((int(width * 0.048), int(height * 0.21)), result)
+48 -48
View File
@@ -1,48 +1,48 @@
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent
from utils.manager import plugins2block_manager, StaticData from utils.manager import plugins2block_manager, StaticData
import time import time
class StatusMessageManager(StaticData): class StatusMessageManager(StaticData):
def __init__(self): def __init__(self):
super().__init__(None) super().__init__(None)
def add(self, id_: int): def add(self, id_: int):
self._data[id_] = time.time() self._data[id_] = time.time()
def delete(self, id_: int): def delete(self, id_: int):
if self._data.get(id_): if self._data.get(id_):
del self._data[id_] del self._data[id_]
def check(self, id_: int, t: int = 30) -> bool: def check(self, id_: int, t: int = 30) -> bool:
if self._data.get(id_): if self._data.get(id_):
if time.time() - self._data[id_] > t: if time.time() - self._data[id_] > t:
del self._data[id_] del self._data[id_]
return True return True
return False return False
return True return True
status_message_manager = StatusMessageManager() status_message_manager = StatusMessageManager()
def set_block_limit_false(event, module): def set_block_limit_false(event, module):
""" """
设置用户block为false 设置用户block为false
:param event: event :param event: event
:param module: 插件模块 :param module: 插件模块
""" """
if plugins2block_manager.check_plugin_block_status(module): if plugins2block_manager.check_plugin_block_status(module):
plugin_block_data = plugins2block_manager.get_plugin_block_data(module) plugin_block_data = plugins2block_manager.get_plugin_block_data(module)
check_type = plugin_block_data["check_type"] check_type = plugin_block_data["check_type"]
limit_type = plugin_block_data["limit_type"] limit_type = plugin_block_data["limit_type"]
if not ( if not (
(isinstance(event, GroupMessageEvent) and check_type == "private") (isinstance(event, GroupMessageEvent) and check_type == "private")
or (isinstance(event, PrivateMessageEvent) and check_type == "group") or (isinstance(event, PrivateMessageEvent) and check_type == "group")
): ):
block_type_ = event.user_id block_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent): if limit_type == "group" and isinstance(event, GroupMessageEvent):
block_type_ = event.group_id block_type_ = event.group_id
plugins2block_manager.set_false(block_type_, module) plugins2block_manager.set_false(block_type_, module)
+56 -77
View File
@@ -1,6 +1,6 @@
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from models.friend_user import FriendUser from models.friend_user import FriendUser
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from models.bag_user import BagUser from models.bag_user import BagUser
@@ -11,19 +11,19 @@ from utils.manager import (
plugins_manager, plugins_manager,
plugins2cd_manager, plugins2cd_manager,
plugins2block_manager, plugins2block_manager,
plugins2count_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 nonebot.typing import T_State
from typing import Optional from typing import Optional
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent, GroupMessageEvent,
PokeNotifyEvent, PokeNotifyEvent,
PrivateMessageEvent, PrivateMessageEvent,
Message, Message,
Event Event,
) )
from configs.config import Config from configs.config import Config
from models.ban_user import BanUser from models.ban_user import BanUser
@@ -43,29 +43,34 @@ ignore_rst_module = ["ai", "poke", "dialogue"]
# 权限检测 # 权限检测
@run_preprocessor @run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
module = matcher.module module = matcher.plugin_name
plugins2info_dict = plugins2settings_manager.get_data() plugins2info_dict = plugins2settings_manager.get_data()
# 功能的金币检测 ####################################### # 功能的金币检测 #######################################
# 功能的金币检测 ####################################### # 功能的金币检测 #######################################
# 功能的金币检测 ####################################### # 功能的金币检测 #######################################
cost_gold = 0 cost_gold = 0
if isinstance(event, GroupMessageEvent) and plugins2settings_manager.get_plugin_data(module).get('cost_gold'): if isinstance(
cost_gold = plugins2settings_manager.get_plugin_data(module).get('cost_gold') event, GroupMessageEvent
) and plugins2settings_manager.get_plugin_data(module).get("cost_gold"):
cost_gold = plugins2settings_manager.get_plugin_data(module).get("cost_gold")
if await BagUser.get_gold(event.user_id, event.group_id) < cost_gold: if await BagUser.get_gold(event.user_id, event.group_id) < cost_gold:
await send_msg(f"金币不足..该功能需要{cost_gold}金币..", bot, event) await send_msg(f"金币不足..该功能需要{cost_gold}金币..", bot, event)
raise IgnoredException(f"{module} 金币限制...") raise IgnoredException(f"{module} 金币限制...")
# 当插件不阻塞超级用户时,超级用户提前扣除金币 # 当插件不阻塞超级用户时,超级用户提前扣除金币
if str(event.user_id) in bot.config.superusers and not plugins2info_dict[module]["limit_superuser"]: if (
str(event.user_id) in bot.config.superusers
and not plugins2info_dict[module]["limit_superuser"]
):
await BagUser.spend_gold(event.user_id, event.group_id, cost_gold) await BagUser.spend_gold(event.user_id, event.group_id, cost_gold)
try: try:
if ( if (
(not isinstance(event, MessageEvent) and module != "poke") (not isinstance(event, MessageEvent) and module != "poke")
or await BanUser.is_ban(event.user_id) or await BanUser.is_ban(event.user_id)
and str(event.user_id) not in bot.config.superusers and str(event.user_id) not in bot.config.superusers
) or ( ) or (
str(event.user_id) in bot.config.superusers str(event.user_id) in bot.config.superusers
and plugins2info_dict.get(module) and plugins2info_dict.get(module)
and not plugins2info_dict[module]["limit_superuser"] and not plugins2info_dict[module]["limit_superuser"]
): ):
return return
except AttributeError: except AttributeError:
@@ -76,16 +81,19 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
_module = _plugin.module _module = _plugin.module
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
if ( if (
"[superuser]" in plugin_name.lower() "[superuser]" in plugin_name.lower()
and str(event.user_id) in bot.config.superusers and str(event.user_id) in bot.config.superusers
): ):
return return
except AttributeError: except AttributeError:
pass pass
# 群黑名单检测 群总开关检测 # 群黑名单检测 群总开关检测
if isinstance(event, GroupMessageEvent) or matcher.module == "poke": if isinstance(event, GroupMessageEvent) or matcher.plugin_name == "poke":
try: try:
if group_manager.get_group_level(event.group_id) < 0: if (
group_manager.get_group_level(event.group_id) < 0
and str(event.user_id) not in bot.config.superusers
):
raise IgnoredException("群黑名单") raise IgnoredException("群黑名单")
if not group_manager.check_group_bot_status(event.group_id): if not group_manager.check_group_bot_status(event.group_id):
try: try:
@@ -99,12 +107,12 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
# 个人权限 # 个人权限
if ( if (
not await LevelUser.check_level( not await LevelUser.check_level(
event.user_id, event.user_id,
event.group_id, event.group_id,
admin_manager.get_plugin_level(module), admin_manager.get_plugin_level(module),
) )
and admin_manager.get_plugin_level(module) > 0 and admin_manager.get_plugin_level(module) > 0
): ):
try: try:
if _flmt.check(event.user_id): if _flmt.check(event.user_id):
@@ -112,7 +120,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
await bot.send_group_msg( await bot.send_group_msg(
group_id=event.group_id, group_id=event.group_id,
message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:" message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:"
f"{admin_manager.get_plugin_level(module)}", f"{admin_manager.get_plugin_level(module)}",
) )
except ActionFailed: except ActionFailed:
pass pass
@@ -122,7 +130,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
raise IgnoredException("权限不足") raise IgnoredException("权限不足")
else: else:
if not await LevelUser.check_level( if not await LevelUser.check_level(
event.user_id, 0, admin_manager.get_plugin_level(module) event.user_id, 0, admin_manager.get_plugin_level(module)
): ):
try: try:
await bot.send_private_msg( await bot.send_private_msg(
@@ -138,12 +146,12 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if module in plugins2info_dict.keys() and matcher.priority not in [1, 9]: if module in plugins2info_dict.keys() and matcher.priority not in [1, 9]:
# 戳一戳单独判断 # 戳一戳单独判断
if isinstance(event, GroupMessageEvent) or ( if isinstance(event, GroupMessageEvent) or (
isinstance(event, PokeNotifyEvent) and event.group_id isinstance(event, PokeNotifyEvent) and event.group_id
): ):
if status_message_manager.get(event.group_id) is None: if status_message_manager.get(event.group_id) is None:
status_message_manager.delete(event.group_id) status_message_manager.delete(event.group_id)
if plugins2info_dict[module]["level"] > group_manager.get_group_level( if plugins2info_dict[module]["level"] > group_manager.get_group_level(
event.group_id event.group_id
): ):
try: try:
if _flmt_g.check(event.user_id) and module not in ignore_rst_module: if _flmt_g.check(event.user_id) and module not in ignore_rst_module:
@@ -161,7 +169,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if not group_manager.get_plugin_status(module, event.group_id): if not group_manager.get_plugin_status(module, event.group_id):
try: try:
if module not in ignore_rst_module and _flmt_s.check( if module not in ignore_rst_module and _flmt_s.check(
event.group_id event.group_id
): ):
_flmt_s.start_cd(event.group_id) _flmt_s.start_cd(event.group_id)
await bot.send_group_msg( await bot.send_group_msg(
@@ -177,8 +185,8 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if not group_manager.get_plugin_status(f"{module}:super", event.group_id): if not group_manager.get_plugin_status(f"{module}:super", event.group_id):
try: try:
if ( if (
_flmt_s.check(event.group_id) _flmt_s.check(event.group_id)
and module not in ignore_rst_module and module not in ignore_rst_module
): ):
_flmt_s.start_cd(event.group_id) _flmt_s.start_cd(event.group_id)
await bot.send_group_msg( await bot.send_group_msg(
@@ -194,8 +202,8 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if not plugins_manager.get_plugin_status(module, block_type="group"): if not plugins_manager.get_plugin_status(module, block_type="group"):
try: try:
if ( if (
_flmt_c.check(event.group_id) _flmt_c.check(event.group_id)
and module not in ignore_rst_module and module not in ignore_rst_module
): ):
_flmt_c.start_cd(event.group_id) _flmt_c.start_cd(event.group_id)
await bot.send_group_msg( await bot.send_group_msg(
@@ -225,14 +233,14 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
# 维护 # 维护
if not plugins_manager.get_plugin_status(module, block_type="all"): if not plugins_manager.get_plugin_status(module, block_type="all"):
if isinstance( if isinstance(
event, GroupMessageEvent event, GroupMessageEvent
) and group_manager.check_group_is_white(event.group_id): ) and group_manager.check_group_is_white(event.group_id):
return return
try: try:
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
if ( if (
_flmt_c.check(event.group_id) _flmt_c.check(event.group_id)
and module not in ignore_rst_module and module not in ignore_rst_module
): ):
_flmt_c.start_cd(event.group_id) _flmt_c.start_cd(event.group_id)
await bot.send_group_msg( await bot.send_group_msg(
@@ -260,7 +268,6 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
# 以下为限制检测 ####################################################### # 以下为限制检测 #######################################################
# 以下为限制检测 ####################################################### # 以下为限制检测 #######################################################
# 以下为限制检测 ####################################################### # 以下为限制检测 #######################################################
# Cd # Cd
if plugins2cd_manager.check_plugin_cd_status(module): if plugins2cd_manager.check_plugin_cd_status(module):
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module) plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
@@ -268,36 +275,9 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
limit_type = plugin_cd_data["limit_type"] limit_type = plugin_cd_data["limit_type"]
rst = plugin_cd_data["rst"] rst = plugin_cd_data["rst"]
if ( if (
(isinstance(event, PrivateMessageEvent) and check_type == "private") (isinstance(event, PrivateMessageEvent) and check_type == "private")
or (isinstance(event, GroupMessageEvent) and check_type == "group") or (isinstance(event, GroupMessageEvent) and check_type == "group")
or plugins2cd_manager.get_plugin_data(module).get("check_type") == "all" 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)
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 cd_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent): if limit_type == "group" and isinstance(event, GroupMessageEvent):
@@ -316,9 +296,9 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
limit_type = plugin_block_data["limit_type"] limit_type = plugin_block_data["limit_type"]
rst = plugin_block_data["rst"] rst = plugin_block_data["rst"]
if ( if (
(isinstance(event, PrivateMessageEvent) and check_type == "private") (isinstance(event, PrivateMessageEvent) and check_type == "private")
or (isinstance(event, GroupMessageEvent) and check_type == "group") or (isinstance(event, GroupMessageEvent) and check_type == "group")
or check_type == "all" or check_type == "all"
): ):
block_type_ = event.user_id block_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent): if limit_type == "group" and isinstance(event, GroupMessageEvent):
@@ -332,8 +312,8 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
plugins2block_manager.set_true(block_type_, module) plugins2block_manager.set_true(block_type_, module)
# Count # Count
if ( if (
plugins2count_manager.check_plugin_count_status(module) plugins2count_manager.check_plugin_count_status(module)
and event.user_id not in bot.config.superusers and event.user_id not in bot.config.superusers
): ):
plugin_count_data = plugins2count_manager.get_plugin_count_data(module) plugin_count_data = plugins2count_manager.get_plugin_count_data(module)
limit_type = plugin_count_data["limit_type"] limit_type = plugin_count_data["limit_type"]
@@ -382,15 +362,15 @@ async def _(
event: Event, event: Event,
state: T_State, state: T_State,
): ):
if not isinstance(event, MessageEvent) and matcher.module != "poke": if not isinstance(event, MessageEvent) and matcher.plugin_name != "poke":
return return
module = matcher.module module = matcher.plugin_name
set_block_limit_false(event, module) set_block_limit_false(event, module)
async def init_rst(rst: str, event: MessageEvent): async def init_rst(rst: str, event: MessageEvent):
if "[uname]" in rst: if "[uname]" in rst:
uname = event.sender.card if event.sender.card else event.sender.nickname uname = event.sender.card or event.sender.nickname
rst = rst.replace("[uname]", uname) rst = rst.replace("[uname]", uname)
if "[nickname]" in rst: if "[nickname]" in rst:
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
@@ -403,4 +383,3 @@ async def init_rst(rst: str, event: MessageEvent):
if "[at]" in rst and isinstance(event, GroupMessageEvent): if "[at]" in rst and isinstance(event, GroupMessageEvent):
rst = rst.replace("[at]", str(at(event.user_id))) rst = rst.replace("[at]", str(at(event.user_id)))
return rst return rst
+3 -3
View File
@@ -1,8 +1,8 @@
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.message import run_preprocessor, IgnoredException from nonebot.message import run_preprocessor, IgnoredException
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent, GroupMessageEvent,
@@ -83,4 +83,4 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
) )
except ActionFailed: except ActionFailed:
pass pass
raise IgnoredException("用户处于黑名单中") raise IgnoredException("用户处于黑名单中")
+2 -2
View File
@@ -1,8 +1,8 @@
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.message import run_preprocessor, IgnoredException from nonebot.message import run_preprocessor, IgnoredException
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent, GroupMessageEvent,
+3 -4
View File
@@ -1,8 +1,8 @@
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.message import run_preprocessor, IgnoredException from nonebot.message import run_preprocessor, IgnoredException
from nonebot.typing import T_State from nonebot.typing import T_State
from .utils import status_message_manager from ._utils import status_message_manager
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
MessageEvent, MessageEvent,
PrivateMessageEvent, 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): async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if not isinstance(event, MessageEvent): if not isinstance(event, MessageEvent):
return return
if matcher.type == "message" and matcher.module == "ai": if matcher.type == "message" and matcher.plugin_name == "ai":
if ( if (
isinstance(event, GroupMessageEvent) isinstance(event, GroupMessageEvent)
and not status_message_manager.check(event.group_id) and not status_message_manager.check(event.group_id)
@@ -35,7 +35,6 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
isinstance(event, PrivateMessageEvent) isinstance(event, PrivateMessageEvent)
and not status_message_manager.check(event.user_id) and not status_message_manager.check(event.user_id)
): ):
print(status_message_manager)
status_message_manager.delete(event.user_id) status_message_manager.delete(event.user_id)
raise IgnoredException("有命令就别说话了") raise IgnoredException("有命令就别说话了")
+47
View File
@@ -0,0 +1,47 @@
from nonebot.exception import MockApiException
from nonebot.adapters.onebot.v11 import Bot, Message
from utils.manager import group_manager
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_type"] == "group")
or api == "send_group_msg"
)
and (
(
r := re.search(
"^\[\[_task\|(.*)]]",
data["message"].strip()
if isinstance(data["message"], str)
else str(data["message"]["text"]).strip(),
)
)
or (
r := re.search(
"^&#91;&#91;_task\|(.*)&#93;&#93;",
data["message"].strip()
if isinstance(data["message"], str)
else str(data["message"]["text"]).strip(),
)
)
)
and r.group(1) in group_manager.get_task_data().keys()
):
task = r.group(1)
group_id = data["group_id"]
if group_manager.get_group_level(
group_id
) < 0 or not await group_manager.check_group_task_status(group_id, task):
raise MockApiException(f"被动技能 {task} 处于关闭状态...")
else:
msg = str(data["message"]).strip()
msg = msg.replace(f"&#91;&#91;_task|{task}&#93;&#93;", "").replace(
f"[[_task|{task}]]", ""
)
data["message"] = Message(msg)
+2 -2
View File
@@ -2,7 +2,7 @@ from nonebot.matcher import Matcher
from nonebot.message import run_postprocessor from nonebot.message import run_postprocessor
from typing import Optional from typing import Optional
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, Event from nonebot.adapters.onebot.v11 import Bot, Event
from utils.manager import withdraw_message_manager from utils.manager import withdraw_message_manager
import asyncio import asyncio
@@ -25,4 +25,4 @@ async def _(
async def _withdraw_message(bot: Bot, id_: int, time: int): async def _withdraw_message(bot: Bot, id_: int, time: int):
await asyncio.sleep(time) await asyncio.sleep(time)
await bot.delete_msg(message_id=id_, self_id=int(bot.self_id)) await bot.delete_msg(message_id=id_)
+2 -3
View File
@@ -11,8 +11,7 @@ from .init_plugins_limit import (
) )
from .init import init from .init import init
from .check_plugin_status import check_plugin_status from .check_plugin_status import check_plugin_status
from utils.manager import admin_manager from nonebot.adapters.onebot.v11 import Bot
from nonebot.adapters.cqhttp import Bot
from configs.path_config import DATA_PATH from configs.path_config import DATA_PATH
from services.log import logger from services.log import logger
from pathlib import Path from pathlib import Path
@@ -34,7 +33,7 @@ def _():
初始化数据 初始化数据
""" """
_flag = False _flag = False
config_file = Path(DATA_PATH) / "configs" / "plugins2config.yaml" config_file = DATA_PATH / "configs" / "plugins2config.yaml"
if not config_file.exists(): if not config_file.exists():
_flag = True _flag = True
init() init()
@@ -1,5 +1,5 @@
from utils.manager import plugins_manager from utils.manager import plugins_manager
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.onebot.v11 import Bot
async def check_plugin_status(bot: Bot): async def check_plugin_status(bot: Bot):
@@ -15,14 +15,14 @@ def init_plugins_config(data_path):
""" """
初始化插件数据配置 初始化插件数据配置
""" """
plugins2config_file = Path(data_path) / "configs" / "plugins2config.yaml" plugins2config_file = data_path / "configs" / "plugins2config.yaml"
plugins2config_file.parent.mkdir(parents=True, exist_ok=True) plugins2config_file.parent.mkdir(parents=True, exist_ok=True)
_data = {} _data = {}
if plugins2config_file.exists(): if plugins2config_file.exists():
_data = _yaml.load(open(plugins2config_file, "r", encoding="utf8")) _data = _yaml.load(open(plugins2config_file, "r", encoding="utf8"))
_matchers = get_matchers() _matchers = get_matchers()
for matcher in _matchers: for matcher in _matchers:
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
@@ -39,16 +39,16 @@ def init_plugins_config(data_path):
if ( if (
plugin_version is None plugin_version is None
or ( or (
_data.get(matcher.module) _data.get(matcher.plugin_name)
and _data[matcher.module].keys() != plugin_configs.keys() and _data[matcher.plugin_name].keys() != plugin_configs.keys()
) )
or plugin_version > plugins_manager.get(matcher.module)["version"] or plugin_version > plugins_manager.get(matcher.plugin_name)["version"]
or matcher.module not in _data.keys() or matcher.plugin_name not in _data.keys()
): ):
for key in plugin_configs: for key in plugin_configs:
if isinstance(plugin_configs[key], dict): if isinstance(plugin_configs[key], dict):
Config.add_plugin_config( Config.add_plugin_config(
matcher.module, matcher.plugin_name,
key, key,
plugin_configs[key].get("value"), plugin_configs[key].get("value"),
help_=plugin_configs[key].get("help"), help_=plugin_configs[key].get("help"),
@@ -56,12 +56,12 @@ def init_plugins_config(data_path):
_override=True, _override=True,
) )
else: else:
Config.add_plugin_config(matcher.module, key, plugin_configs[key]) Config.add_plugin_config(matcher.plugin_name, key, plugin_configs[key])
else: else:
plugin_configs = _data[matcher.module] plugin_configs = _data[matcher.plugin_name]
for key in plugin_configs: for key in plugin_configs:
Config.add_plugin_config( Config.add_plugin_config(
matcher.module, matcher.plugin_name,
key, key,
plugin_configs[key]["value"], plugin_configs[key]["value"],
help_=plugin_configs[key]["help"], help_=plugin_configs[key]["help"],
@@ -99,7 +99,10 @@ def init_plugins_config(data_path):
if _data.get(plugin) and k in _data[plugin].keys(): if _data.get(plugin) and k in _data[plugin].keys():
Config.set_config(plugin, k, _data[plugin][k]) Config.set_config(plugin, k, _data[plugin][k])
if level2module := Config.get_level2module(plugin, k): if level2module := Config.get_level2module(plugin, k):
admin_manager.set_admin_level(level2module, _data[plugin][k]) try:
admin_manager.set_admin_level(level2module, _data[plugin][k])
except KeyError:
logger.warning(f"{level2module} 设置权限等级失败:{_data[plugin][k]}")
_tmp_data[plugin][k] = Config.get_config(plugin, k) _tmp_data[plugin][k] = Config.get_config(plugin, k)
Config.save() Config.save()
temp_file = Path() / "configs" / "temp_config.yaml" temp_file = Path() / "configs" / "temp_config.yaml"
@@ -17,27 +17,27 @@ def init_plugins_data(data_path):
""" """
初始化插件数据信息 初始化插件数据信息
""" """
plugin2data_file = Path(data_path) / "manager" / "plugin_manager.json" plugin2data_file = data_path / "manager" / "plugin_manager.json"
plugin2data_file.parent.mkdir(parents=True, exist_ok=True) plugin2data_file.parent.mkdir(parents=True, exist_ok=True)
_data = {} _data = {}
if plugin2data_file.exists(): if plugin2data_file.exists():
_data = json.load(open(plugin2data_file, "r", encoding="utf8")) _data = json.load(open(plugin2data_file, "r", encoding="utf8"))
_matchers = get_matchers() _matchers = get_matchers()
for matcher in _matchers: for matcher in _matchers:
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
if matcher.module not in _data.keys(): if matcher.plugin_name not in _data.keys():
plugins_manager.add_plugin_data( plugins_manager.add_plugin_data(
matcher.module, matcher.module, error=True matcher.plugin_name, matcher.plugin_name, error=True
) )
else: else:
plugins_manager.set_module_data(matcher.module, "error", True) plugins_manager.set_module_data(matcher.plugin_name, "error", True)
plugin_data = plugins_manager.get(matcher.module) plugin_data = plugins_manager.get(matcher.plugin_name)
if plugin_data: if plugin_data:
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "version", plugin_data.get("version") matcher.plugin_name, "version", plugin_data.get("version")
) )
else: else:
try: try:
@@ -47,36 +47,36 @@ def init_plugins_data(data_path):
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
except AttributeError: except AttributeError:
plugin_name = matcher.module plugin_name = matcher.plugin_name
try: try:
plugin_author = _module.__getattribute__("__plugin_author__") plugin_author = _module.__getattribute__("__plugin_author__")
except AttributeError: except AttributeError:
plugin_author = None plugin_author = None
if matcher.module in plugins_manager.keys(): if matcher.plugin_name in plugins_manager.keys():
plugins_manager.set_module_data(matcher.module, "error", False) plugins_manager.set_module_data(matcher.plugin_name, "error", False)
if matcher.module not in plugins_manager.keys(): if matcher.plugin_name not in plugins_manager.keys():
plugins_manager.add_plugin_data( plugins_manager.add_plugin_data(
matcher.module, matcher.plugin_name,
plugin_name=plugin_name, plugin_name=plugin_name,
author=plugin_author, author=plugin_author,
version=plugin_version, version=plugin_version,
) )
elif plugins_manager[matcher.module]["version"] is None or ( elif plugins_manager[matcher.plugin_name]["version"] is None or (
plugin_version is not None plugin_version is not None
and plugin_version > plugins_manager[matcher.module]["version"] and plugin_version > plugins_manager[matcher.plugin_name]["version"]
): ):
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "plugin_name", plugin_name matcher.plugin_name, "plugin_name", plugin_name
) )
plugins_manager.set_module_data(matcher.module, "author", plugin_author) plugins_manager.set_module_data(matcher.plugin_name, "author", plugin_author)
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "version", plugin_version matcher.plugin_name, "version", plugin_version
) )
if matcher.module in _data.keys(): if matcher.plugin_name in _data.keys():
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "error", _data[matcher.module]["error"] matcher.plugin_name, "error", _data[matcher.plugin_name]["error"]
) )
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "plugin_name", _data[matcher.module]["plugin_name"] matcher.plugin_name, "plugin_name", _data[matcher.plugin_name]["plugin_name"]
) )
plugins_manager.save() plugins_manager.save()
@@ -17,18 +17,18 @@ def init_plugins_cd_limit(data_path):
""" """
加载 cd 限制 加载 cd 限制
""" """
plugins2cd_file = Path(data_path) / "configs" / "plugins2cd.yaml" plugins2cd_file = data_path / "configs" / "plugins2cd.yaml"
plugins2cd_file.parent.mkdir(exist_ok=True, parents=True) plugins2cd_file.parent.mkdir(exist_ok=True, parents=True)
_data = {} _data = {}
_matchers = get_matchers() _matchers = get_matchers()
for matcher in _matchers: for matcher in _matchers:
if not plugins2cd_manager.get_plugin_cd_data(matcher.module): if not plugins2cd_manager.get_plugin_cd_data(matcher.plugin_name):
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
plugin_cd_limit = _module.__getattribute__("__plugin_cd_limit__") plugin_cd_limit = _module.__getattribute__("__plugin_cd_limit__")
plugins2cd_manager.add_cd_limit( plugins2cd_manager.add_cd_limit(
matcher.module, data_dict=plugin_cd_limit matcher.plugin_name, data_dict=plugin_cd_limit
) )
except AttributeError: except AttributeError:
pass pass
@@ -65,18 +65,18 @@ def init_plugins_block_limit(data_path):
""" """
加载阻塞限制 加载阻塞限制
""" """
plugins2block_file = Path(data_path) / "configs" / "plugins2block.yaml" plugins2block_file = data_path / "configs" / "plugins2block.yaml"
plugins2block_file.parent.mkdir(exist_ok=True, parents=True) plugins2block_file.parent.mkdir(exist_ok=True, parents=True)
_data = {} _data = {}
_matchers = get_matchers() _matchers = get_matchers()
for matcher in _matchers: for matcher in _matchers:
if not plugins2block_manager.get_plugin_block_data(matcher.module): if not plugins2block_manager.get_plugin_block_data(matcher.plugin_name):
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
plugin_block_limit = _module.__getattribute__("__plugin_block_limit__") plugin_block_limit = _module.__getattribute__("__plugin_block_limit__")
plugins2block_manager.add_block_limit( plugins2block_manager.add_block_limit(
matcher.module, data_dict=plugin_block_limit matcher.plugin_name, data_dict=plugin_block_limit
) )
except AttributeError: except AttributeError:
pass pass
@@ -113,18 +113,18 @@ def init_plugins_count_limit(data_path):
""" """
加载次数限制 加载次数限制
""" """
plugins2count_file = Path(data_path) / "configs" / "plugins2count.yaml" plugins2count_file = data_path / "configs" / "plugins2count.yaml"
plugins2count_file.parent.mkdir(exist_ok=True, parents=True) plugins2count_file.parent.mkdir(exist_ok=True, parents=True)
_data = {} _data = {}
_matchers = get_matchers() _matchers = get_matchers()
for matcher in _matchers: for matcher in _matchers:
if not plugins2count_manager.get_plugin_count_data(matcher.module): if not plugins2count_manager.get_plugin_count_data(matcher.plugin_name):
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
plugin_count_limit = _module.__getattribute__("__plugin_count_limit__") plugin_count_limit = _module.__getattribute__("__plugin_count_limit__")
plugins2count_manager.add_count_limit( plugins2count_manager.add_count_limit(
matcher.module, data_dict=plugin_count_limit matcher.plugin_name, data_dict=plugin_count_limit
) )
except AttributeError: except AttributeError:
pass pass
@@ -11,13 +11,13 @@ def init_plugins_resources():
""" """
_tmp = [] _tmp = []
for matcher in get_matchers(): for matcher in get_matchers():
if matcher.module not in _tmp: if matcher.plugin_name not in _tmp:
_tmp.append(matcher.module) _tmp.append(matcher.plugin_name)
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
logger.warning(f"插件 {matcher.module} 加载失败...,资源控制未加载...") logger.warning(f"插件 {matcher.plugin_name} 加载失败...,资源控制未加载...")
else: else:
try: try:
resources = _module.__getattribute__("__plugin_resources__") resources = _module.__getattribute__("__plugin_resources__")
@@ -26,7 +26,7 @@ def init_plugins_resources():
else: else:
path = Path(_module.__getattribute__("__file__")).parent path = Path(_module.__getattribute__("__file__")).parent
for resource in resources.keys(): for resource in resources.keys():
resources_manager.add_resource(matcher.module, (path / resource).absolute(), resources[resource]) resources_manager.add_resource(matcher.plugin_name, path / resource, resources[resource])
resources_manager.save() resources_manager.save()
resources_manager.start_move() resources_manager.start_move()
@@ -14,7 +14,7 @@ def init_plugins_settings(data_path: str):
""" """
初始化插件设置,从插件中获取 __zx_plugin_name__,__plugin_cmd__,__plugin_settings__ 初始化插件设置,从插件中获取 __zx_plugin_name__,__plugin_cmd__,__plugin_settings__
""" """
plugins2settings_file = Path(data_path) / "configs" / "plugins2settings.yaml" plugins2settings_file = data_path / "configs" / "plugins2settings.yaml"
plugins2settings_file.parent.mkdir(exist_ok=True, parents=True) plugins2settings_file.parent.mkdir(exist_ok=True, parents=True)
_matchers = get_matchers() _matchers = get_matchers()
_tmp_module = {} _tmp_module = {}
@@ -29,12 +29,12 @@ def init_plugins_settings(data_path: str):
logger.warning(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}") logger.warning(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}")
_tmp_module[x] = "" _tmp_module[x] = ""
for matcher in _matchers: for matcher in _matchers:
if matcher.module not in plugins2settings_manager.keys(): if matcher.plugin_name not in plugins2settings_manager.keys():
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
logger.warning(f"插件 {matcher.module} 加载失败...,插件控制未加载.") logger.warning(f"插件 {matcher.plugin_name} 加载失败...,插件控制未加载.")
else: else:
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
@@ -51,23 +51,23 @@ def init_plugins_settings(data_path: str):
if level is None: if level is None:
level = 5 level = 5
admin_manager.add_admin_plugin_settings( admin_manager.add_admin_plugin_settings(
matcher.module, cmd, level matcher.plugin_name, cmd, level
) )
if ( if (
"[hidden]" in plugin_name.lower() "[hidden]" in plugin_name.lower()
or "[admin]" in plugin_name.lower() or "[admin]" in plugin_name.lower()
or "[superuser]" in plugin_name.lower() or "[superuser]" in plugin_name.lower()
or matcher.module in plugins2settings_manager.keys() or matcher.plugin_name in plugins2settings_manager.keys()
): ):
continue continue
except AttributeError: except AttributeError:
if matcher.module not in _tmp: if matcher.plugin_name not in _tmp:
logger.warning( logger.warning(
f"获取插件 {matcher.module} __zx_plugin_name__ 失败...,插件控制未加载." f"获取插件 {matcher.plugin_name} __zx_plugin_name__ 失败...,插件控制未加载."
) )
else: else:
try: try:
_tmp_module[matcher.module] = plugin_name _tmp_module[matcher.plugin_name] = plugin_name
plugin_settings = _module.__getattribute__( plugin_settings = _module.__getattribute__(
"__plugin_settings__" "__plugin_settings__"
) )
@@ -79,13 +79,13 @@ def init_plugins_settings(data_path: str):
): ):
plugin_settings["cmd"].append(plugin_name) plugin_settings["cmd"].append(plugin_name)
if plugins2settings_manager.get( if plugins2settings_manager.get(
matcher.module matcher.plugin_name
) and plugins2settings_manager[matcher.module].get( ) and plugins2settings_manager[matcher.plugin_name].get(
"plugin_type" "plugin_type"
): ):
plugin_type = tuple( plugin_type = tuple(
plugins2settings_manager.get_plugin_data( plugins2settings_manager.get_plugin_data(
matcher.module matcher.plugin_name
)["plugin_type"] )["plugin_type"]
) )
else: else:
@@ -95,15 +95,15 @@ def init_plugins_settings(data_path: str):
) )
except AttributeError: except AttributeError:
plugin_type = ("normal",) plugin_type = ("normal",)
if plugin_settings and matcher.module: if plugin_settings and matcher.plugin_name:
plugins2settings_manager.add_plugin_settings( plugins2settings_manager.add_plugin_settings(
matcher.module, matcher.plugin_name,
plugin_type=plugin_type, plugin_type=plugin_type,
**plugin_settings, **plugin_settings,
) )
except AttributeError: except AttributeError:
pass pass
_tmp.append(matcher.module) _tmp.append(matcher.plugin_name)
_tmp_data = {"PluginSettings": plugins2settings_manager.get_data()} _tmp_data = {"PluginSettings": plugins2settings_manager.get_data()}
with open(plugins2settings_file, "w", encoding="utf8") as wf: with open(plugins2settings_file, "w", encoding="utf8") as wf:
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True) yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
+5 -5
View File
@@ -1,5 +1,5 @@
from nonebot import on_request, on_message from nonebot import on_request, on_message
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
FriendRequestEvent, FriendRequestEvent,
GroupRequestEvent, GroupRequestEvent,
@@ -8,7 +8,7 @@ from nonebot.adapters.cqhttp import (
from models.friend_user import FriendUser from models.friend_user import FriendUser
from datetime import datetime from datetime import datetime
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from utils.manager import requests_manager from utils.manager import requests_manager
from models.group_info import GroupInfo from models.group_info import GroupInfo
from utils.utils import scheduler from utils.utils import scheduler
@@ -31,7 +31,7 @@ exists_data = {"private": {}, "group": {}}
@friend_req.handle() @friend_req.handle()
async def _(bot: Bot, event: FriendRequestEvent, state: dict): async def _(bot: Bot, event: FriendRequestEvent):
global exists_data global exists_data
if exists_data["private"].get(event.user_id): if exists_data["private"].get(event.user_id):
if time.time() - exists_data["private"][event.user_id] < 60 * 5: if time.time() - exists_data["private"][event.user_id] < 60 * 5:
@@ -66,7 +66,7 @@ async def _(bot: Bot, event: FriendRequestEvent, state: dict):
@group_req.handle() @group_req.handle()
async def _(bot: Bot, event: GroupRequestEvent, state: dict): async def _(bot: Bot, event: GroupRequestEvent):
global exists_data global exists_data
if event.sub_type == "invite": if event.sub_type == "invite":
if str(event.user_id) in bot.config.superusers: if str(event.user_id) in bot.config.superusers:
@@ -125,7 +125,7 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
@x.handle() @x.handle()
async def _(bot: Bot, event: MessageEvent, state: dict): async def _(event: MessageEvent):
await asyncio.sleep(0.1) await asyncio.sleep(0.1)
r = re.search(r'groupcode="(.*?)"', str(event.get_message())) r = re.search(r'groupcode="(.*?)"', str(event.get_message()))
if r: if r:
+9 -10
View File
@@ -1,15 +1,14 @@
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, PrivateMessageEvent, Message
from nonebot import on_command from nonebot import on_command
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, PrivateMessageEvent
from nonebot.rule import to_me from nonebot.rule import to_me
from utils.utils import get_message_text
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from models.friend_user import FriendUser from models.friend_user import FriendUser
import random
from models.ban_user import BanUser from models.ban_user import BanUser
from services.log import logger from services.log import logger
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
from nonebot.params import CommandArg
import random
__zx_plugin_name__ = "昵称系统" __zx_plugin_name__ = "昵称系统"
__plugin_usage__ = f""" __plugin_usage__ = f"""
@@ -48,8 +47,8 @@ cancel_nickname = on_command("取消昵称", rule=to_me(), priority=5, block=Tru
@nickname.handle() @nickname.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if not msg: if not msg:
await nickname.finish("叫你空白?叫你虚空?叫你无名??", at_sender=True) await nickname.finish("叫你空白?叫你虚空?叫你无名??", at_sender=True)
if len(msg) > 10: if len(msg) > 10:
@@ -103,7 +102,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
@my_nickname.handle() @my_nickname.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
try: try:
nickname_ = await GroupInfoUser.get_group_member_nickname( nickname_ = await GroupInfoUser.get_group_member_nickname(
event.user_id, event.group_id event.user_id, event.group_id
@@ -124,7 +123,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
) )
) )
else: else:
nickname_ = event.sender.card if event.sender.card else event.sender.nickname nickname_ = event.sender.card or event.sender.nickname
await my_nickname.send( await my_nickname.send(
random.choice( random.choice(
["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"] ["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"]
@@ -158,7 +157,7 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
@cancel_nickname.handle() @cancel_nickname.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
nickname_ = await GroupInfoUser.get_group_member_nickname( nickname_ = await GroupInfoUser.get_group_member_nickname(
event.user_id, event.group_id event.user_id, event.group_id
) )
@@ -181,7 +180,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
@cancel_nickname.handle() @cancel_nickname.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(event: PrivateMessageEvent):
nickname_ = await FriendUser.get_friend_nickname(event.user_id) nickname_ = await FriendUser.get_friend_nickname(event.user_id)
if nickname_: if nickname_:
await cancel_nickname.send( await cancel_nickname.send(
+102 -6
View File
@@ -1,14 +1,19 @@
from asyncpg.exceptions import (
DuplicateColumnError,
UndefinedColumnError,
PostgresSyntaxError,
)
from nonebot import Driver from nonebot import Driver
from services.db_context import db from services.db_context import db
from asyncpg.exceptions import DuplicateColumnError
from models.group_info import GroupInfo from models.group_info import GroupInfo
from nonebot.adapters.cqhttp import Bot from models.bag_user import BagUser
from nonebot.adapters.onebot.v11 import Bot
from services.log import logger from services.log import logger
from configs.path_config import TEXT_PATH from configs.path_config import TEXT_PATH
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from typing import List
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
from utils.utils import scheduler from utils.utils import scheduler
from pathlib import Path
import nonebot import nonebot
try: try:
@@ -26,7 +31,7 @@ async def update_city():
部分插件需要中国省份城市 部分插件需要中国省份城市
这里直接更新,避免插件内代码重复 这里直接更新,避免插件内代码重复
""" """
china_city = Path(TEXT_PATH) / "china_city.json" china_city = TEXT_PATH / "china_city.json"
data = {} data = {}
if not china_city.exists(): if not china_city.exists():
try: try:
@@ -61,15 +66,86 @@ async def _():
""" """
数据库表结构变换 数据库表结构变换
""" """
_flag = []
sql_str = [ sql_str = [
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag (
"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"
), # 新增原神群号绑定字段
] ]
for sql in sql_str: for sql in sql_str:
try: try:
flag = sql[1]
sql = sql[0]
query = db.text(sql) query = db.text(sql)
await db.first(query) await db.first(query)
except DuplicateColumnError: logger.info(f"完成sql操作:{sql}")
_flag.append(flag)
except (DuplicateColumnError, UndefinedColumnError):
pass 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 @driver.on_bot_connect
@@ -105,6 +181,26 @@ async def _(bot: Bot):
logger.info(f"移除不存在的群聊信息:{group_id}") 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( @scheduler.scheduled_job(
"cron", "cron",
+26 -18
View File
@@ -1,12 +1,13 @@
from nonebot import on_command from nonebot import on_command
from services.log import logger from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
from nonebot.typing import T_State from nonebot.params import CommandArg
from utils.utils import get_message_text, is_number from utils.utils import is_number
from models.bag_user import BagUser from models.bag_user import BagUser
from services.db_context import db from services.db_context import db
from nonebot.adapters.cqhttp.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
from models.goods_info import GoodsInfo from models.goods_info import GoodsInfo
import time
__zx_plugin_name__ = "商店 - 购买道具" __zx_plugin_name__ = "商店 - 购买道具"
@@ -20,7 +21,7 @@ usage:
""".strip() """.strip()
__plugin_des__ = "商店 - 购买道具" __plugin_des__ = "商店 - 购买道具"
__plugin_cmd__ = ["购买 [序号或名称] ?[数量=1]"] __plugin_cmd__ = ["购买 [序号或名称] ?[数量=1]"]
__plugin_type__ = ('商店',) __plugin_type__ = ("商店",)
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
@@ -29,36 +30,43 @@ __plugin_settings__ = {
"limit_superuser": False, "limit_superuser": False,
"cmd": ["商店", "购买道具"], "cmd": ["商店", "购买道具"],
} }
__plugin_cd_limit__ = {"cd": 3}
buy = on_command("购买", aliases={"购买道具"}, priority=5, block=True, permission=GROUP) buy = on_command("购买", aliases={"购买道具"}, priority=5, block=True, permission=GROUP)
@buy.handle() @buy.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
goods = None goods = None
if get_message_text(event.json()) in ["神秘药水"]: if arg.extract_plain_text().strip() in ["神秘药水"]:
await buy.finish("你们看看就好啦,这是不可能卖给你们的~", at_sender=True) await buy.finish("你们看看就好啦,这是不可能卖给你们的~", at_sender=True)
goods_lst = await GoodsInfo.get_all_goods() goods_list = [
goods_name_lst = [x.goods_name for x in goods_lst] x
msg = get_message_text(event.json()).split() 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()
num = 1 num = 1
if len(msg) > 1: if len(msg) > 1:
if is_number(msg[1]) and int(msg[1]) > 0: if is_number(msg[1]) and int(msg[1]) > 0:
num = int(msg[1]) num = int(msg[1])
else: else:
await buy.finish("购买的数量要是数字且大于0!", at_sender=True) await buy.finish("购买的数量要是数字且大于0!", at_sender=True)
# print(msg, num)
if is_number(msg[0]): if is_number(msg[0]):
msg = int(msg[0]) msg = int(msg[0])
if msg > len(goods_lst) or msg < 1: if msg > len(goods_name_list) or msg < 1:
await buy.finish("请输入正确的商品id!", at_sender=True) await buy.finish("请输入正确的商品id!", at_sender=True)
goods = goods_lst[msg - 1] goods = goods_list[msg - 1]
else: else:
if msg[0] in goods_name_lst: if msg[0] in goods_name_list:
for i in range(len(goods_name_lst)): for i in range(len(goods_name_list)):
if msg[0] == goods_name_lst[i]: if msg[0] == goods_name_list[i]:
goods = goods_lst[i] goods = goods_list[i]
break break
else: else:
await buy.finish("请输入正确的商品名称!") await buy.finish("请输入正确的商品名称!")
@@ -69,7 +77,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await BagUser.get_gold(event.user_id, event.group_id) await BagUser.get_gold(event.user_id, event.group_id)
) < goods.goods_price * num * goods.goods_discount: ) < goods.goods_price * num * goods.goods_discount:
await buy.finish("您的金币好像不太够哦", at_sender=True) await buy.finish("您的金币好像不太够哦", at_sender=True)
if await BagUser.buy_props(event.user_id, event.group_id, goods, num): if await BagUser.buy_property(event.user_id, event.group_id, goods, num):
await buy.send( await buy.send(
f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!", f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!",
at_sender=True, at_sender=True,
+8 -8
View File
@@ -1,11 +1,11 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
from nonebot.typing import T_State from nonebot.params import CommandArg
from nonebot.adapters.cqhttp.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
from utils.data_utils import init_rank from utils.data_utils import init_rank
from models.bag_user import BagUser from models.bag_user import BagUser
from utils.message_builder import image from utils.message_builder import image
from utils.utils import get_message_text, is_number from utils.utils import is_number
__zx_plugin_name__ = "商店 - 我的金币" __zx_plugin_name__ = "商店 - 我的金币"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -33,13 +33,13 @@ gold_rank = on_command("金币排行", priority=5, block=True, permission=GROUP)
@my_gold.handle() @my_gold.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
await my_gold.finish(await BagUser.get_my_total_gold(event.user_id, event.group_id)) await my_gold.finish(await BagUser.get_user_total_gold(event.user_id, event.group_id))
@gold_rank.handle() @gold_rank.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
num = get_message_text(event.json()) num = arg.extract_plain_text().strip()
if is_number(num) and 51 > int(num) > 10: if is_number(num) and 51 > int(num) > 10:
num = int(num) num = int(num)
else: else:
+6 -17
View File
@@ -1,9 +1,8 @@
from nonebot import on_command from nonebot import on_command
from services.log import logger from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent
from nonebot.typing import T_State
from models.bag_user import BagUser from models.bag_user import BagUser
from nonebot.adapters.cqhttp.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
__zx_plugin_name__ = "商店 - 我的道具" __zx_plugin_name__ = "商店 - 我的道具"
@@ -30,22 +29,12 @@ my_props = on_command("我的道具", priority=5, block=True, permission=GROUP)
@my_props.handle() @my_props.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
props = await BagUser.get_props(event.user_id, event.group_id) props = await BagUser.get_property(event.user_id, event.group_id)
if props: if props:
pname_list = []
pnum_list = []
rst = "" rst = ""
props = props[:-1].split(",") for i, p in enumerate(props.keys()):
for p in props: rst += f"{i+1}.{p}\t×{props[p]}\n"
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) await my_props.send("\n" + rst[:-1], at_sender=True)
logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具") logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具")
else: else:
+13 -13
View File
@@ -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 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 configs.path_config import IMAGE_PATH
from utils.message_builder import image 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 nonebot.permission import SUPERUSER
from utils.utils import get_message_text, is_number from utils.utils import is_number
from nonebot.params import CommandArg
from nonebot.plugin import export from nonebot.plugin import export
from services.log import logger from services.log import logger
import os import os
@@ -53,7 +53,7 @@ __plugin_block_limit__ = {
# 导出方法供其他插件使用 # 导出方法供其他插件使用
export = export() export = export()
export.registered_goods = registered_goods export.register_goods = register_goods
export.delete_goods = delete_goods export.delete_goods = delete_goods
export.update_goods = update_goods export.update_goods = update_goods
@@ -67,20 +67,20 @@ shop_update_goods = on_command("修改商品", priority=5, permission=SUPERUSER,
@shop_help.handle() @shop_help.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _():
await shop_help.send(image(b64=await create_shop_help())) await shop_help.send(image(b64=await create_shop_help()))
@shop_add_goods.handle() @shop_add_goods.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if msg: if msg:
data = parse_goods_info(msg) data = parse_goods_info(msg)
if isinstance(data, str): if isinstance(data, str):
await shop_add_goods.finish(data) await shop_add_goods.finish(data)
if not data.get("name") or not data.get("price") or not data.get("des"): if not data.get("name") or not data.get("price") or not data.get("des"):
await shop_add_goods.finish("name:price:des 参数不可缺少!") await shop_add_goods.finish("name:price:des 参数不可缺少!")
if await registered_goods(**data): if await register_goods(**data):
await shop_add_goods.send(f"添加商品 {data['name']} 成功!\n" await shop_add_goods.send(f"添加商品 {data['name']} 成功!\n"
f"名称:{data['name']}\n" f"名称:{data['name']}\n"
f"价格:{data['price']}金币\n" f"价格:{data['price']}金币\n"
@@ -94,8 +94,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@shop_del_goods.handle() @shop_del_goods.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if msg: if msg:
name = "" name = ""
id_ = 0 id_ = 0
@@ -115,8 +115,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@shop_update_goods.handle() @shop_update_goods.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if msg: if msg:
data = parse_goods_info(msg) data = parse_goods_info(msg)
if isinstance(data, str): if isinstance(data, str):
+13 -25
View File
@@ -20,36 +20,24 @@ async def init_default_shop_goods():
""" """
导入内置的三个商品 导入内置的三个商品
""" """
async def sign_card(**kwargs):
async def sign_card_1(**kwargs):
user_id = kwargs['user_id'] user_id = kwargs['user_id']
group_id = kwargs['group_id'] group_id = kwargs['group_id']
prob = kwargs["prob"]
user = await SignGroupUser.ensure(user_id, group_id) user = await SignGroupUser.ensure(user_id, group_id)
await user.update(add_probability=0.1).apply() await user.update(add_probability=prob).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"): if Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"):
await registered_goods( await register_goods(
"好感度双倍加持卡Ⅰ", 30, "下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)" "好感度双倍加持卡Ⅰ", 30, "下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)"
) )
use.registered_use("好感度双倍加持卡Ⅰ", sign_card_1) use.register_use("好感度双倍加持卡Ⅰ", sign_card, **{"prob": 0.1})
await registered_goods("好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)") await register_goods("好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)")
use.registered_use("好感度双倍加持卡Ⅱ", sign_card_2) use.register_use("好感度双倍加持卡Ⅱ", sign_card, **{"prob": 0.2})
await registered_goods( await register_goods(
"好感度双倍加持卡Ⅲ", 250, "下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)" "好感度双倍加持卡Ⅲ", 250, "下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)"
) )
use.registered_use("好感度双倍加持卡Ⅲ", sign_card_3) use.register_use("好感度双倍加持卡Ⅲ", sign_card, **{"prob": 0.3})
# 创建商店界面 # 创建商店界面
@@ -136,7 +124,7 @@ async def create_shop_help() -> str:
return shop.pic2bs4() return shop.pic2bs4()
async def registered_goods( async def register_goods(
name: str, name: str,
price: int, price: int,
des: str, des: str,
@@ -229,11 +217,12 @@ async def update_goods(**kwargs) -> "str, str, int":
tmp += f'折扣:{discount} --> {kwargs["discount"]}\n' tmp += f'折扣:{discount} --> {kwargs["discount"]}\n'
discount = kwargs["discount"] discount = kwargs["discount"]
if kwargs.get("limit_time"): if kwargs.get("limit_time"):
kwargs["limit_time"] = float(kwargs["limit_time"])
new_time = time.strftime( new_time = time.strftime(
"%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M:%S",
time.localtime(time.time() + int(kwargs["limit_time"] * 60 * 60)), time.localtime(time.time() + kwargs["limit_time"] * 60 * 60),
) )
tmp += f"折扣至: {new_time}\n" tmp += f"限时至: {new_time}\n"
limit_time = kwargs["limit_time"] limit_time = kwargs["limit_time"]
return ( return (
await GoodsInfo.update_goods( await GoodsInfo.update_goods(
@@ -261,7 +250,6 @@ def parse_goods_info(msg: str) -> Union[dict, str]:
sp = x.split(":", maxsplit=1) sp = x.split(":", maxsplit=1)
if str(sp[1]).strip(): if str(sp[1]).strip():
sp[1] = sp[1].strip() sp[1] = sp[1].strip()
print(sp)
if sp[0] == "name": if sp[0] == "name":
data["name"] = sp[1] data["name"] = sp[1]
elif sp[0] == "price": elif sp[0] == "price":
+35 -30
View File
@@ -1,13 +1,13 @@
from nonebot import on_command from nonebot import on_command
from services.log import logger from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
from nonebot.typing import T_State from nonebot.params import CommandArg
from utils.utils import is_number, get_message_text from utils.utils import is_number
from models.bag_user import BagUser from models.bag_user import BagUser
from nonebot.adapters.cqhttp.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
from services.db_context import db from services.db_context import db
from nonebot.plugin import export from nonebot.plugin import export
from .data_source import effect, registered_use from .data_source import effect, register_use, func_manager
__zx_plugin_name__ = "商店 - 使用道具" __zx_plugin_name__ = "商店 - 使用道具"
@@ -15,7 +15,7 @@ __plugin_usage__ = """
usage: usage:
普通的使用道具 普通的使用道具
指令: 指令:
使用道具 [序号或道具名称] 使用道具 [序号或道具名称] ?[数量]=1
* 序号以 ”我的道具“ 为准 * * 序号以 ”我的道具“ 为准 *
""".strip() """.strip()
__plugin_des__ = "商店 - 使用道具" __plugin_des__ = "商店 - 使用道具"
@@ -32,45 +32,50 @@ __plugin_settings__ = {
# 导出方法供其他插件使用 # 导出方法供其他插件使用
export = export() export = export()
export.registered_use = registered_use export.register_use = register_use
use_props = on_command("使用道具", priority=5, block=True, permission=GROUP) use_props = on_command("使用道具", priority=5, block=True, permission=GROUP)
@use_props.handle() @use_props.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if msg in ["", "帮助"]: num = 1
await use_props.finish(__plugin_usage__) msg_sp = msg.split()
props = await BagUser.get_props(event.user_id, event.group_id) if len(msg_sp) > 1 and is_number(msg_sp[-1]) and int(msg_sp[-1]) > 0:
if props: num = int(msg.split()[-1])
msg = " ".join(msg.split()[:-1])
property_ = await BagUser.get_property(event.user_id, event.group_id)
if property_:
async with db.transaction(): 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 is_number(msg):
if 0 < int(msg) <= len(pname_list): if 0 < int(msg) <= len(property_):
name = pname_list[int(msg) - 1] name = list(property_.keys())[int(msg) - 1]
else: else:
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True) await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
else: else:
if msg not in pname_list: if msg not in property_.keys():
await use_props.finish("道具名称错误!", at_sender=True) await use_props.finish("道具名称错误!", at_sender=True)
name = msg name = msg
if await BagUser.del_props( _user_prop_count = property_[name]
event.user_id, event.group_id, name if num > _user_prop_count:
) and await effect(event.user_id, event.group_id, name): await use_props.finish(f"道具数量不足,无法使用{num}次!")
await use_props.send(f"使用道具 {name} 成功!", at_sender=True) 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)
logger.info( logger.info(
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 成功" f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次成功"
) )
else: else:
await use_props.send(f"使用道具 {name} 失败!", at_sender=True) await use_props.send(f"使用道具 {name} {num} 次失败!", at_sender=True)
logger.info( logger.info(
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 失败" f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次失败"
) )
else: else:
await use_props.send("您的背包里没有任何的道具噢~", at_sender=True) await use_props.send("您的背包里没有任何的道具噢", at_sender=True)
+99 -23
View File
@@ -1,45 +1,121 @@
import asyncio from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment
from services.log import logger from services.log import logger
from nonebot.adapters.onebot.v11 import Bot
_use_func_data = {} from typing import Optional, Union
import asyncio
async def effect(user_id: int, group_id: int, goods_name: str) -> bool: 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]]:
""" """
商品生效 商品生效
:param user_id: 用户id :param bot: Bot
:param group_id: 群号 :param event: GroupMessageEvent
:param goods_name: 商品名称 :param goods_name: 商品名称
:param num: 使用数量
:return: 使用是否成功 :return: 使用是否成功
""" """
# 优先使用注册的商品插件 # 优先使用注册的商品插件
try: try:
if _use_func_data.get(goods_name): if func_manager.exists(goods_name):
_kwargs = _use_func_data[goods_name]["kwargs"] _kwargs = func_manager.get_kwargs(goods_name)
_kwargs["goods_name"] = goods_name return await func_manager.use(
_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, **_kwargs,
) "_bot": bot,
else: "event": event,
_use_func_data[goods_name]["func"]( "group_id": event.group_id,
**_kwargs, "user_id": event.user_id,
) "num": num,
return True "goods_name": goods_name,
}
)
except Exception as e: except Exception as e:
logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}") logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}")
return False return None
def registered_use(goods_name: str, func, **kwargs): def register_use(goods_name: str, func, **kwargs):
""" """
注册商品使用方法 注册商品使用方法
:param goods_name: 商品名称 :param goods_name: 商品名称
:param func: 使用函数 :param func: 使用函数
:param kwargs: kwargs :param kwargs: kwargs
""" """
if goods_name in _use_func_data.keys(): if func_manager.exists(goods_name):
raise ValueError("该商品使用函数已被注册!") raise ValueError("该商品使用函数已被注册!")
_use_func_data[goods_name] = {"func": func, "kwargs": kwargs} # 发送使用成功信息
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} 的使用函数")
+20 -25
View File
@@ -1,9 +1,10 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import Bot, Message
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message from nonebot.params import Command, CommandArg
from typing import Tuple
from nonebot.rule import to_me from nonebot.rule import to_me
from utils.utils import get_message_text, is_number from utils.utils import is_number
from utils.manager import requests_manager from utils.manager import requests_manager
from utils.message_builder import image from utils.message_builder import image
from models.group_info import GroupInfo from models.group_info import GroupInfo
@@ -57,37 +58,30 @@ cls_request = on_command("查看所有请求", permission=SUPERUSER, priority=1,
@cls_group.handle() @cls_group.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot):
gl = await bot.get_group_list(self_id=int(bot.self_id)) gl = await bot.get_group_list()
msg = ["{group_id} {group_name}".format_map(g) for g in gl] msg = ["{group_id} {group_name}".format_map(g) for g in gl]
msg = "\n".join(msg) msg = "\n".join(msg)
msg = f"bot:{bot.self_id}\n| 群号 | 群名 | 共{len(gl)}个群\n" + msg msg = f"bot:{bot.self_id}\n| 群号 | 群名 | 共{len(gl)}个群\n" + msg
await bot.send_private_msg( await cls_group.send(msg)
self_id=int(bot.self_id),
user_id=int(list(bot.config.superusers)[0]),
message=msg,
)
@cls_friend.handle() @cls_friend.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot):
gl = await bot.get_friend_list(self_id=int(bot.self_id)) gl = await bot.get_friend_list()
msg = ["{user_id} {nickname}".format_map(g) for g in gl] msg = ["{user_id} {nickname}".format_map(g) for g in gl]
msg = "\n".join(msg) msg = "\n".join(msg)
msg = f"| QQ号 | 昵称 | 共{len(gl)}个好友\n" + msg msg = f"| QQ号 | 昵称 | 共{len(gl)}个好友\n" + msg
await bot.send_private_msg( await cls_friend.send(msg)
self_id=int(bot.self_id),
user_id=int(list(bot.config.superusers)[0]),
message=msg,
)
@friend_handle.handle() @friend_handle.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
id_ = get_message_text(event.json()) cmd = cmd[0]
id_ = arg.extract_plain_text().strip()
if is_number(id_): if is_number(id_):
id_ = int(id_) id_ = int(id_)
if state["_prefix"]["raw_command"][:2] == "同意": if cmd[:2] == "同意":
if await requests_manager.approve(bot, id_, "private"): if await requests_manager.approve(bot, id_, "private"):
await friend_handle.send("同意好友请求成功..") await friend_handle.send("同意好友请求成功..")
else: else:
@@ -102,11 +96,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@group_handle.handle() @group_handle.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
id_ = get_message_text(event.json()) cmd = cmd[0]
id_ = arg.extract_plain_text().strip()
if is_number(id_): if is_number(id_):
id_ = int(id_) id_ = int(id_)
if state["_prefix"]["raw_command"][:2] == "同意": if cmd[:2] == "同意":
rid = await requests_manager.approve(bot, id_, "group") rid = await requests_manager.approve(bot, id_, "group")
if rid: if rid:
await friend_handle.send("同意群聊请求成功..") await friend_handle.send("同意群聊请求成功..")
@@ -133,7 +128,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@cls_request.handle() @cls_request.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
_str = "" _str = ""
for type_ in ["private", "group"]: for type_ in ["private", "group"]:
msg = await requests_manager.show(type_) msg = await requests_manager.show(type_)
@@ -147,6 +142,6 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@clear_request.handle() @clear_request.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
requests_manager.clear() requests_manager.clear()
await cls_request.send("已清空所有好友/群聊请求..") await cls_request.send("已清空所有好友/群聊请求..")
+9 -10
View File
@@ -1,7 +1,5 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER 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 configs.path_config import TEMP_PATH
from nonebot.rule import to_me from nonebot.rule import to_me
from utils.utils import scheduler from utils.utils import scheduler
@@ -35,7 +33,7 @@ resources_manager.add_temp_dir(TEMP_PATH)
@clear_data.handle() @clear_data.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
await clear_data.send("开始清理临时数据....") await clear_data.send("开始清理临时数据....")
size = await asyncio.get_event_loop().run_in_executor(None, _clear_data) size = await asyncio.get_event_loop().run_in_executor(None, _clear_data)
await clear_data.send("共清理了 {:.2f}MB 的数据...".format(size / 1024 / 1024)) await clear_data.send("共清理了 {:.2f}MB 的数据...".format(size / 1024 / 1024))
@@ -47,13 +45,14 @@ def _clear_data() -> float:
if dir_.exists(): if dir_.exists():
for file in os.listdir(dir_): for file in os.listdir(dir_):
file = dir_ / file file = dir_ / file
try: if file.is_file():
if time.time() - os.path.getatime(file) > 300: try:
file_size = os.path.getsize(file) if time.time() - os.path.getatime(file) > 300:
file.unlink() file_size = os.path.getsize(file)
size += file_size file.unlink()
except Exception as e: size += file_size
logger.error(f"清理临时数据错误...{type(e)}:{e}") except Exception as e:
logger.error(f"清理临时数据错误...{type(e)}:{e}")
return float(size) return float(size)
-74
View File
@@ -1,74 +0,0 @@
# 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
+4 -5
View File
@@ -1,10 +1,9 @@
from nonebot.adapters.onebot.v11 import Message
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER 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 nonebot.rule import to_me
from services.db_context import db from services.db_context import db
from utils.utils import get_message_text from nonebot.params import CommandArg
from services.log import logger from services.log import logger
__zx_plugin_name__ = "执行sql [Superuser]" __zx_plugin_name__ = "执行sql [Superuser]"
@@ -26,8 +25,8 @@ exec_ = on_command("exec", rule=to_me(), permission=SUPERUSER, priority=1, block
@exec_.handle() @exec_.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(arg: Message = CommandArg()):
sql = get_message_text(event.json()) sql = arg.extract_plain_text().strip()
async with db.transaction(): async with db.transaction():
try: try:
query = db.text(sql) query = db.text(sql)
+23 -19
View File
@@ -1,14 +1,16 @@
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GROUP, GroupMessageEvent, Message
from nonebot import on_command, on_regex from nonebot import on_command, on_regex
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GROUP, GroupMessageEvent
from nonebot.rule import to_me from nonebot.rule import to_me
from utils.utils import get_message_text, is_number from utils.utils import is_number
from utils.manager import group_manager, plugins2settings_manager from utils.manager import group_manager, plugins2settings_manager
from models.group_info import GroupInfo from models.group_info import GroupInfo
from services.log import logger from services.log import logger
from configs.config import NICKNAME from configs.config import NICKNAME
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.params import Command, CommandArg
from typing import Tuple
__zx_plugin_name__ = "管理群操作 [Superuser]" __zx_plugin_name__ = "管理群操作 [Superuser]"
@@ -65,8 +67,8 @@ group_auth = on_command(
@del_group.handle() @del_group.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, arg: Message = CommandArg()):
group_id = get_message_text(event.json()) group_id = arg.extract_plain_text().strip()
if group_id: if group_id:
if is_number(group_id): if is_number(group_id):
try: try:
@@ -84,8 +86,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@add_group_level.handle() @add_group_level.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
group_id = 0 group_id = 0
level = 0 level = 0
if not msg: if not msg:
@@ -109,7 +111,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@my_group_level.handle() @my_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
level = group_manager.get_group_level(event.group_id) level = group_manager.get_group_level(event.group_id)
tmp = "" tmp = ""
data = plugins2settings_manager.get_data() data = plugins2settings_manager.get_data()
@@ -125,17 +127,18 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
@what_up_group_level.handle() @what_up_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _():
await what_up_group_level.finish( await what_up_group_level.finish(
f"[此功能用于防止内鬼,如果引起不便那真是抱歉了]\n" f"目前提高群权限的方法:\n" f"\t1.管理员修改权限" f"[此功能用于防止内鬼,如果引起不便那真是抱歉了]\n" f"目前提高群权限的方法:\n" f"\t1.管理员修改权限"
) )
@manager_group_whitelist.handle() @manager_group_whitelist.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
msg = get_message_text(event.json()).split() cmd = cmd[0]
msg = arg.extract_plain_text().strip()
all_group = [ all_group = [
g["group_id"] for g in await bot.get_group_list(self_id=int(bot.self_id)) g["group_id"] for g in await bot.get_group_list()
] ]
group_list = [] group_list = []
for group in msg: for group in msg:
@@ -143,20 +146,20 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
group_list.append(int(group)) group_list.append(int(group))
if group_list: if group_list:
for group in group_list: for group in group_list:
if state["_prefix"]["raw_command"] in ["添加群白名单"]: if cmd in ["添加群白名单"]:
group_manager.add_group_white_list(group) group_manager.add_group_white_list(group)
else: else:
group_manager.delete_group_white_list(group) group_manager.delete_group_white_list(group)
group_list = [str(x) for x in group_list] group_list = [str(x) for x in group_list]
await manager_group_whitelist.send( await manager_group_whitelist.send(
"已成功将 " + "\n".join(group_list) + " " + state["_prefix"]["raw_command"] "已成功将 " + "\n".join(group_list) + " " + cmd
) )
else: else:
await manager_group_whitelist.send(f"添加失败,请检查{NICKNAME}是否已加入这些群聊或重复添加/删除群白单名") await manager_group_whitelist.send(f"添加失败,请检查{NICKNAME}是否已加入这些群聊或重复添加/删除群白单名")
@show_group_whitelist.handle() @show_group_whitelist.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
x = group_manager.get_group_white_list() x = group_manager.get_group_white_list()
x = [str(g) for g in x] x = [str(g) for g in x]
if x: if x:
@@ -166,13 +169,14 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@group_auth.handle() @group_auth.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
msg = get_message_text(event.json()).split() cmd = cmd[0]
msg = arg.extract_plain_text().strip().split()
for group_id in msg: for group_id in msg:
if not is_number(group_id): if not is_number(group_id):
await group_auth.send(f"{group_id}非纯数字,已跳过该项..") await group_auth.send(f"{group_id}非纯数字,已跳过该项..")
group_id = int(group_id) group_id = int(group_id)
if state["_prefix"]["raw_command"][:2] == "添加": if cmd[:2] == "添加":
if await GroupInfo.get_group_info(group_id): if await GroupInfo.get_group_info(group_id):
await GroupInfo.set_group_flag(group_id, 1) await GroupInfo.set_group_flag(group_id, 1)
else: else:
@@ -196,5 +200,5 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
if await GroupInfo.get_group_info(group_id): if await GroupInfo.get_group_info(group_id):
await GroupInfo.set_group_flag(group_id, 0) await GroupInfo.set_group_flag(group_id, 0)
await group_auth.send( await group_auth.send(
f'已为 {group_id} {state["_prefix"]["raw_command"][:2]}群认证..' f'已为 {group_id} {cmd[:2]}群认证..'
) )
+31 -3
View File
@@ -7,8 +7,9 @@ from utils.manager import (
plugins2block_manager, plugins2block_manager,
group_manager, group_manager,
) )
from nonebot.typing import T_State from configs.config import Config
from nonebot.adapters.cqhttp import Bot, MessageEvent from services.log import logger
from utils.utils import scheduler
__zx_plugin_name__ = "重载插件配置 [Superuser]" __zx_plugin_name__ = "重载插件配置 [Superuser]"
@@ -28,6 +29,18 @@ __plugin_cmd__ = [
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __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( reload_plugins_manager = on_command(
@@ -36,9 +49,24 @@ reload_plugins_manager = on_command(
@reload_plugins_manager.handle() @reload_plugins_manager.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
plugins2settings_manager.reload() plugins2settings_manager.reload()
plugins2cd_manager.reload() plugins2cd_manager.reload()
plugins2block_manager.reload() plugins2block_manager.reload()
group_manager.reload() group_manager.reload()
Config.reload()
await reload_plugins_manager.send("重载完成...") 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,11 +1,12 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from models.level_user import LevelUser from models.level_user import LevelUser
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, Message from utils.utils import get_message_at, is_number
from utils.utils import get_message_at, get_message_text, is_number
from services.log import logger from services.log import logger
from utils.message_builder import at from utils.message_builder import at
from nonebot.params import Command, CommandArg
from typing import Tuple
__zx_plugin_name__ = "用户权限管理 [Superuser]" __zx_plugin_name__ = "用户权限管理 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -36,11 +37,12 @@ super_cmd = on_command(
@super_cmd.handle() @super_cmd.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
cmd = cmd[0]
group_id = -1 group_id = -1
level = 0 level = 0
try: try:
args = get_message_text(event.json()).split() args = arg.extract_plain_text().strip().split()
qq = get_message_at(event.json()) qq = get_message_at(event.json())
flag = -1 flag = -1
if not qq: if not qq:
@@ -65,7 +67,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
qq = qq[0] qq = qq[0]
group_id = event.group_id group_id = event.group_id
flag = 2 flag = 2
if state["_prefix"]["raw_command"][:2] == "添加": if cmd[:2] == "添加":
if await LevelUser.set_level(qq, group_id, level, 1): if await LevelUser.set_level(qq, group_id, level, 1):
result = "添加管理成功, 权限: " + str(level) result = "添加管理成功, 权限: " + str(level)
else: else:
+8 -6
View File
@@ -1,11 +1,12 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.rule import to_me from nonebot.rule import to_me
from utils.utils import get_message_text, is_number from utils.utils import is_number
from services.log import logger from services.log import logger
from utils.manager import group_manager from utils.manager import group_manager
from nonebot.params import Command, CommandArg
from typing import Tuple
__zx_plugin_name__ = "超级用户被动开关 [Superuser]" __zx_plugin_name__ = "超级用户被动开关 [Superuser]"
@@ -34,8 +35,9 @@ oc_gb = on_command(
@oc_gb.handle() @oc_gb.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
group = get_message_text(event.json()) cmd = cmd[0]
group = arg.extract_plain_text().strip()
if group: if group:
if is_number(group): if is_number(group):
group = int(group) group = int(group)
@@ -44,7 +46,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
break break
else: else:
await oc_gb.finish("没有加入这个群...", at_sender=True) await oc_gb.finish("没有加入这个群...", at_sender=True)
if state["_prefix"]["raw_command"] == "开启广播通知": if cmd == "开启广播通知":
logger.info(f"USER {event.user_id} 开启了 GROUP {group} 的广播") logger.info(f"USER {event.user_id} 开启了 GROUP {group} 的广播")
await oc_gb.finish(await group_manager.open_group_task(group, "broadcast",), at_sender=True) await oc_gb.finish(await group_manager.open_group_task(group, "broadcast",), at_sender=True)
else: else:
@@ -1,7 +1,5 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER 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 nonebot.rule import to_me
from utils.utils import get_bot from utils.utils import get_bot
from services.log import logger from services.log import logger
@@ -34,7 +32,7 @@ update_friend_info = on_command(
@update_group_info.handle() @update_group_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
bot = get_bot() bot = get_bot()
gl = await bot.get_group_list() gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl] gl = [g["group_id"] for g in gl]
@@ -57,7 +55,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@update_friend_info.handle() @update_friend_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
num = 0 num = 0
rst = "" rst = ""
fl = await get_bot().get_friend_list() fl = await get_bot().get_friend_list()
+2 -5
View File
@@ -1,18 +1,15 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.rule import to_me from nonebot.rule import to_me
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.message_builder import image from utils.message_builder import image
from .data_source import create_help_image from .data_source import create_help_image
from pathlib import Path
__zx_plugin_name__ = '超级用户帮助 [Superuser]' __zx_plugin_name__ = '超级用户帮助 [Superuser]'
superuser_help_image = Path(IMAGE_PATH) / 'superuser_help.png' superuser_help_image = IMAGE_PATH / 'superuser_help.png'
if superuser_help_image.exists(): if superuser_help_image.exists():
superuser_help_image.unlink() superuser_help_image.unlink()
@@ -23,7 +20,7 @@ super_help = on_command(
@super_help.handle() @super_help.handle()
async def _(bot: Bot, event: Event, state: T_State): async def _():
if not superuser_help_image.exists(): if not superuser_help_image.exists():
await create_help_image() await create_help_image()
x = image(superuser_help_image) x = image(superuser_help_image)
+5 -6
View File
@@ -2,8 +2,7 @@ from utils.image_utils import BuildImage
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from services.log import logger from services.log import logger
from utils.utils import get_matchers from utils.utils import get_matchers
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.onebot.v11 import Bot
from pathlib import Path
from nonebot import Driver from nonebot import Driver
import asyncio import asyncio
import nonebot import nonebot
@@ -11,9 +10,9 @@ import nonebot
driver: Driver = nonebot.get_driver() driver: Driver = nonebot.get_driver()
background = Path(IMAGE_PATH) / "background" / "0.png" background = IMAGE_PATH / "background" / "0.png"
superuser_help_image = Path(IMAGE_PATH) / "superuser_help.png" superuser_help_image = IMAGE_PATH / "superuser_help.png"
@driver.on_bot_connect @driver.on_bot_connect
@@ -36,7 +35,7 @@ def _create_help_image():
for matcher in _matchers: for matcher in _matchers:
plugin_name = "" plugin_name = ""
try: try:
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
_module = _plugin.module _module = _plugin.module
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
@@ -68,7 +67,7 @@ def _create_help_image():
width = width if width > x else x width = width if width > x else x
except Exception as e: except Exception as e:
logger.warning( logger.warning(
f"获取超级用户插件 {matcher.module}: {plugin_name} 设置失败... {type(e)}:{e}" f"获取超级用户插件 {matcher.plugin_name}: {plugin_name} 设置失败... {type(e)}:{e}"
) )
height = len(help_str.split("\n")) * 33 height = len(help_str.split("\n")) * 33
width += 500 width += 500
+1 -3
View File
@@ -1,6 +1,4 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, Event
from nonebot.typing import T_State
from utils.message_builder import image from utils.message_builder import image
@@ -27,7 +25,7 @@ update_info = on_command("更新信息", aliases={"更新日志"}, priority=5, b
@update_info.handle() @update_info.handle()
async def _(bot: Bot, event: Event, state: T_State): async def _():
img = image("update_info.png") img = image("update_info.png")
if img: if img:
await update_info.finish(image("update_info.png")) await update_info.finish(image("update_info.png"))
+2 -3
View File
@@ -1,11 +1,10 @@
import nonebot import nonebot
from nonebot.adapters.cqhttp import Bot as CQHTTPBot from nonebot.adapters.onebot.v11 import Adapter
from services.db_context import init, disconnect from services.db_context import init, disconnect
nonebot.init() nonebot.init()
driver = nonebot.get_driver() driver = nonebot.get_driver()
driver.register_adapter("cqhttp", CQHTTPBot) driver.register_adapter(Adapter)
config = driver.config config = driver.config
driver.on_startup(init) driver.on_startup(init)
driver.on_shutdown(disconnect) driver.on_shutdown(disconnect)
+25 -21
View File
@@ -1,41 +1,45 @@
from pathlib import Path from pathlib import Path
import os
# 图片路径 # 图片路径
IMAGE_PATH = Path("resources/img/") IMAGE_PATH = Path() / "resources" / "image"
# 音频路径 # 语音路径
VOICE_PATH = Path("resources/voice/") RECORD_PATH = Path() / "resources" / "record"
# 文本路径 # 文本路径
TEXT_PATH = Path("resources/txt/") TEXT_PATH = Path() / "resources" / "text"
# 日志路径 # 日志路径
LOG_PATH = Path("log/") LOG_PATH = Path() / "log"
# 字体路径 # 字体路径
FONT_PATH = Path("resources/ttf/") FONT_PATH = Path() / "resources" / "font"
# 数据路径 # 数据路径
DATA_PATH = Path("data/") DATA_PATH = Path() / "data"
# 临时图片路径 # 临时数据路径
TEMP_PATH = Path("resources/img/temp/") TEMP_PATH = Path() / "resources" / "temp"
def init_path(): def load_path():
global IMAGE_PATH, VOICE_PATH, TEXT_PATH, LOG_PATH, FONT_PATH, DATA_PATH, TEMP_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)
IMAGE_PATH.mkdir(parents=True, exist_ok=True) IMAGE_PATH.mkdir(parents=True, exist_ok=True)
VOICE_PATH.mkdir(parents=True, exist_ok=True) RECORD_PATH.mkdir(parents=True, exist_ok=True)
TEXT_PATH.mkdir(parents=True, exist_ok=True) TEXT_PATH.mkdir(parents=True, exist_ok=True)
LOG_PATH.mkdir(parents=True, exist_ok=True) LOG_PATH.mkdir(parents=True, exist_ok=True)
FONT_PATH.mkdir(parents=True, exist_ok=True) FONT_PATH.mkdir(parents=True, exist_ok=True)
DATA_PATH.mkdir(parents=True, exist_ok=True) DATA_PATH.mkdir(parents=True, exist_ok=True)
TEMP_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()
+14
View File
@@ -153,6 +153,20 @@ class ConfigsManager:
self._data, f, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True 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): def get_admin_level_data(self):
""" """
获取管理插件等级 获取管理插件等级
Binary file not shown.

After

Width:  |  Height:  |  Size: 772 KiB

+59 -74
View File
@@ -1,4 +1,5 @@
from services.db_context import db from services.db_context import db
from typing import Dict
from typing import Optional, List from typing import Optional, List
from services.log import logger from services.log import logger
@@ -7,33 +8,32 @@ class BagUser(db.Model):
__tablename__ = "bag_users" __tablename__ = "bag_users"
id = db.Column(db.Integer(), primary_key=True) id = db.Column(db.Integer(), primary_key=True)
user_qq = db.Column(db.BigInteger(), nullable=False) user_qq = db.Column(db.BigInteger(), nullable=False)
belonging_group = db.Column(db.BigInteger(), nullable=False) group_id = db.Column(db.BigInteger(), nullable=False)
gold = db.Column(db.Integer(), default=100) 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) spend_total_gold = db.Column(db.Integer(), default=0)
get_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) get_today_gold = db.Column(db.Integer(), default=0)
spend_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", "belonging_group", unique=True) _idx1 = db.Index("bag_group_users_idx1", "user_qq", "group_id", unique=True)
@classmethod @classmethod
async def get_my_total_gold(cls, user_qq: int, belonging_group: int) -> str: async def get_user_total_gold(cls, user_qq: int, group_id: int) -> str:
""" """
说明: 说明:
获取金币概况 获取金币概况
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
""" """
query = cls.query.where( 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() user = await query.gino.first()
if not user: if not user:
user = await cls.create( user = await cls.create(
user_qq=user_qq, user_qq=user_qq,
belonging_group=belonging_group, group_id=group_id,
) )
return ( return (
f"当前金币:{user.gold}\n今日获取金币:{user.get_today_gold}\n今日花费金币:{user.spend_today_gold}" f"当前金币:{user.gold}\n今日获取金币:{user.get_today_gold}\n今日花费金币:{user.spend_today_gold}"
@@ -42,62 +42,56 @@ class BagUser(db.Model):
) )
@classmethod @classmethod
async def get_gold(cls, user_qq: int, belonging_group: int) -> int: async def get_gold(cls, user_qq: int, group_id: int) -> int:
""" """
说明: 说明:
获取当前金币 获取当前金币
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
""" """
query = cls.query.where( 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() user = await query.gino.first()
if user: if user:
return user.gold return user.gold
else: else:
await cls.create( await cls.create(
user_qq=user_qq, user_qq=user_qq,
belonging_group=belonging_group, group_id=group_id,
) )
return 100 return 100
@classmethod @classmethod
async def get_props(cls, user_qq: int, belonging_group: int) -> str: async def get_property(cls, user_qq: int, group_id: int) -> Dict[str, int]:
""" """
说明: 说明:
获取当前道具 获取当前道具
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
""" """
query = cls.query.where( 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() user = await query.gino.first()
if user: if user:
return user.props return user.property
else: else:
await cls.create( await cls.create(
user_qq=user_qq, user_qq=user_qq,
belonging_group=belonging_group, group_id=group_id,
) )
return "" return {}
@classmethod @classmethod
async def add_gold(cls, user_qq: int, belonging_group: int, num: int): async def add_gold(cls, user_qq: int, group_id: int, num: int):
""" """
说明: 说明:
增加金币 增加金币
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
:param num: 金币数量 :param num: 金币数量
""" """
query = cls.query.where( 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() query = query.with_for_update()
user = await query.gino.first() user = await query.gino.first()
if user: if user:
@@ -109,25 +103,23 @@ class BagUser(db.Model):
else: else:
await cls.create( await cls.create(
user_qq=user_qq, user_qq=user_qq,
belonging_group=belonging_group, group_id=group_id,
gold=100 + num, gold=100 + num,
get_total_gold=num, get_total_gold=num,
get_today_gold=num, get_today_gold=num,
) )
@classmethod @classmethod
async def spend_gold(cls, user_qq: int, belonging_group: int, num: int): async def spend_gold(cls, user_qq: int, group_id: int, num: int):
""" """
说明: 说明:
花费金币 花费金币
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
:param num: 金币数量 :param num: 金币数量
""" """
query = cls.query.where( 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() query = query.with_for_update()
user = await query.gino.first() user = await query.gino.first()
if user: if user:
@@ -139,91 +131,84 @@ class BagUser(db.Model):
else: else:
await cls.create( await cls.create(
user_qq=user_qq, user_qq=user_qq,
belonging_group=belonging_group, group_id=group_id,
gold=100 - num, gold=100 - num,
spend_total_gold=num, spend_total_gold=num,
spend_today_gold=num, spend_today_gold=num,
) )
@classmethod @classmethod
async def add_props(cls, user_qq: int, belonging_group: int, name: str): async def add_property(cls, user_qq: int, group_id: int, name: str):
""" """
说明: 说明:
增加道具 增加道具
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
:param name: 道具名称 :param name: 道具名称
""" """
query = cls.query.where( 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() query = query.with_for_update()
user = await query.gino.first() user = await query.gino.first()
if user: if user:
await user.update(props=user.props + f"{name},").apply() p = user.property
if p.get(name) is None:
p[name] = 1
else:
p[name] += 1
await user.update(property=p).apply()
else: else:
await cls.create( await cls.create(user_qq=user_qq, group_id=group_id, property={name: 1})
user_qq=user_qq, belonging_group=belonging_group, props=f"{name},"
)
@classmethod @classmethod
async def del_props(cls, user_qq: int, belonging_group: int, name: str) -> bool: async def delete_property(
cls, user_qq: int, group_id: int, name: str, num: int = 1
) -> bool:
""" """
说明: 说明:
使用道具 使用/删除 道具
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 所在群号 :param group_id: 所在群号
:param name: 道具名称 :param name: 道具名称
:param num: 使用个数
""" """
query = cls.query.where( 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() query = query.with_for_update()
user = await query.gino.first() user = await query.gino.first()
if user: if user:
rst = "" property_ = user.property
props = user.props if name in property_:
if props.find(name) != -1: if property_.get(name) == num:
props = props.split(",") del property_[name]
try: else:
index = props.index(name) property_[name] -= num
except ValueError: await user.update(property=property_).apply()
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 True
else: return False
return False
else:
return False
@classmethod @classmethod
async def buy_props( async def buy_property(
cls, user_qq: int, belonging_group: int, goods: "GoodsInfo", goods_num: int cls, user_qq: int, group_id: int, goods: "GoodsInfo", goods_num: int
) -> bool: ) -> bool:
""" """
说明: 说明:
购买道具 购买道具
参数: 参数:
:param user_qq: 用户qq :param user_qq: 用户qq
:param belonging_group: 所在群聊 :param group_id: 所在群聊
:param goods: 商品 :param goods: 商品
:param goods_num: 商品数量 :param goods_num: 商品数量
""" """
try: try:
# 折扣后金币 # 折扣后金币
spend_gold = goods.goods_discount * goods.goods_price * goods_num spend_gold = goods.goods_discount * goods.goods_price * goods_num
await BagUser.spend_gold(user_qq, belonging_group, spend_gold) await BagUser.spend_gold(user_qq, group_id, spend_gold)
for _ in range(goods_num): for _ in range(goods_num):
await BagUser.add_props(user_qq, belonging_group, goods.goods_name) await BagUser.add_property(user_qq, group_id, goods.goods_name)
return True return True
except Exception as e: except Exception as e:
logger.error(f"buy_props 发生错误 {type(e)}:{e}") logger.error(f"buy_property 发生错误 {type(e)}:{e}")
return False return False
@classmethod @classmethod
@@ -237,5 +222,5 @@ class BagUser(db.Model):
if not group_id: if not group_id:
query = await cls.query.gino.all() query = await cls.query.gino.all()
else: else:
query = await cls.query.where((cls.belonging_group == group_id)).gino.all() query = await cls.query.where((cls.group_id == group_id)).gino.all()
return query return query
+32 -30
View File
@@ -10,18 +10,18 @@ class GroupInfoUser(db.Model):
id = db.Column(db.Integer(), primary_key=True) id = db.Column(db.Integer(), primary_key=True)
user_qq = db.Column(db.BigInteger(), nullable=False) user_qq = db.Column(db.BigInteger(), nullable=False)
user_name = db.Column(db.Unicode(), nullable=False) user_name = db.Column(db.Unicode(), nullable=False)
belonging_group = db.Column(db.BigInteger(), nullable=False) group_id = db.Column(db.BigInteger(), nullable=False)
user_join_time = db.Column(db.DateTime(), nullable=False) user_join_time = db.Column(db.DateTime(), nullable=False)
nickname = db.Column(db.Unicode()) nickname = db.Column(db.Unicode())
uid = db.Column(db.BigInteger()) uid = db.Column(db.BigInteger())
_idx1 = db.Index("info_group_users_idx1", "user_qq", "belonging_group", unique=True) _idx1 = db.Index("info_group_users_idx1", "user_qq", "group_id", unique=True)
@classmethod @classmethod
async def add_member_info( async def add_member_info(
cls, cls,
user_qq: int, user_qq: int,
belonging_group: int, group_id: int,
user_name: str, user_name: str,
user_join_time: datetime, user_join_time: datetime,
uid: Optional[int] = None, uid: Optional[int] = None,
@@ -31,20 +31,20 @@ class GroupInfoUser(db.Model):
添加群内用户信息 添加群内用户信息
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 群号 :param group_id: 群号
:param user_name: 用户名称 :param user_name: 用户名称
:param user_join_time: 入群时间 :param user_join_time: 入群时间
:param uid: 用户唯一 id(自动生成) :param uid: 用户唯一 id(自动生成)
""" """
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
try: try:
if not await query.gino.first(): if not await query.gino.first():
await cls.create( await cls.create(
user_qq=user_qq, user_qq=user_qq,
user_name=user_name, user_name=user_name,
belonging_group=belonging_group, group_id=group_id,
user_join_time=user_join_time, user_join_time=user_join_time,
uid=uid uid=uid
) )
@@ -54,31 +54,31 @@ class GroupInfoUser(db.Model):
@classmethod @classmethod
async def get_member_info( async def get_member_info(
cls, user_qq: int, belonging_group: int cls, user_qq: int, group_id: int
) -> "GroupInfoUser": ) -> "GroupInfoUser":
""" """
说明: 说明:
查询群员信息 查询群员信息
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 群号 :param group_id: 群号
""" """
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
return await query.gino.first() return await query.gino.first()
@classmethod @classmethod
async def delete_member_info(cls, user_qq: int, belonging_group: int) -> bool: async def delete_member_info(cls, user_qq: int, group_id: int) -> bool:
""" """
说明: 说明:
删除群员信息 删除群员信息
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 群号 :param group_id: 群号
""" """
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
query = query.with_for_update() query = query.with_for_update()
user = await query.gino.first() user = await query.gino.first()
@@ -87,40 +87,40 @@ class GroupInfoUser(db.Model):
return True return True
else: else:
await cls.delete.where( await cls.delete.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
).gino.status() ).gino.status()
return True return True
except Exception: except Exception:
return False return False
@classmethod @classmethod
async def get_group_member_id_list(cls, belonging_group: int) -> List[int]: async def get_group_member_id_list(cls, group_id: int) -> List[int]:
""" """
说明: 说明:
获取该群所有用户qq 获取该群所有用户qq
参数: 参数:
:param belonging_group: 群号 :param group_id: 群号
""" """
member_list = [] member_list = []
query = cls.query.where((cls.belonging_group == belonging_group)) query = cls.query.where((cls.group_id == group_id))
for user in await query.gino.all(): for user in await query.gino.all():
member_list.append(user.user_qq) member_list.append(user.user_qq)
return member_list return member_list
@classmethod @classmethod
async def set_group_member_nickname( async def set_group_member_nickname(
cls, user_qq: int, belonging_group: int, nickname: str cls, user_qq: int, group_id: int, nickname: str
) -> bool: ) -> bool:
""" """
说明: 说明:
设置群员在该群内的昵称 设置群员在该群内的昵称
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 群号 :param group_id: 群号
:param nickname: 昵称 :param nickname: 昵称
""" """
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
user = await query.with_for_update().gino.first() user = await query.with_for_update().gino.first()
if user: if user:
@@ -131,25 +131,27 @@ class GroupInfoUser(db.Model):
@classmethod @classmethod
async def get_user_all_group(cls, user_qq: int) -> List[int]: 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() query = await cls.query.where(cls.user_qq == user_qq).gino.all()
if query: if query:
query = [x.belonging_group for x in query] query = [x.group_id for x in query]
return query return query
@classmethod @classmethod
async def get_group_member_nickname(cls, user_qq: int, belonging_group: int) -> str: async def get_group_member_nickname(cls, user_qq: int, group_id: int) -> str:
""" """
说明: 说明:
获取用户在该群的昵称 获取用户在该群的昵称
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param belonging_group: 群号 :param group_id: 群号
""" """
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
user = await query.gino.first() user = await query.gino.first()
if user: if user:
@@ -163,12 +165,12 @@ class GroupInfoUser(db.Model):
return "" return ""
@classmethod @classmethod
async def get_group_member_uid(cls, user_qq: int, belonging_group: int) -> Optional[str]: async def get_group_member_uid(cls, user_qq: int, group_id: int) -> Optional[str]:
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
user = await query.gino.first() user = await query.gino.first()
_max_uid = cls.query.where((cls.user_qq == 114514) & (cls.belonging_group == 114514)).with_for_update() _max_uid = cls.query.where((cls.user_qq == 114514) & (cls.group_id == 114514)).with_for_update()
_max_uid_user = await _max_uid.gino.first() _max_uid_user = await _max_uid.gino.first()
_max_uid = _max_uid_user.uid _max_uid = _max_uid_user.uid
if not user or not user.uid: if not user or not user.uid:
@@ -178,9 +180,9 @@ class GroupInfoUser(db.Model):
return x.uid return x.uid
else: else:
if not user: if not user:
await GroupInfoUser.add_member_info(user_qq, belonging_group, '', datetime.min) await GroupInfoUser.add_member_info(user_qq, group_id, '', datetime.min)
user = await cls.query.where( user = await cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
).gino.first() ).gino.first()
await user.update( await user.update(
uid=_max_uid + 1, uid=_max_uid + 1,
+11 -12
View File
@@ -8,8 +8,7 @@ class SignGroupUser(db.Model):
id = db.Column(db.Integer(), primary_key=True) id = db.Column(db.Integer(), primary_key=True)
user_qq = db.Column(db.BigInteger(), nullable=False) user_qq = db.Column(db.BigInteger(), nullable=False)
belonging_group = db.Column(db.BigInteger(), nullable=False) group_id = db.Column(db.BigInteger(), nullable=False)
checkin_count = db.Column(db.Integer(), nullable=False) checkin_count = db.Column(db.Integer(), nullable=False)
checkin_time_last = db.Column(db.DateTime(timezone=True), nullable=False) checkin_time_last = db.Column(db.DateTime(timezone=True), nullable=False)
impression = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False) impression = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False)
@@ -20,29 +19,29 @@ class SignGroupUser(db.Model):
db.Numeric(scale=3, asdecimal=False), nullable=False, default=0 db.Numeric(scale=3, asdecimal=False), nullable=False, default=0
) )
_idx1 = db.Index("sign_group_users_idx1", "user_qq", "belonging_group", unique=True) _idx1 = db.Index("sign_group_users_idx1", "user_qq", "group_id", unique=True)
@classmethod @classmethod
async def ensure( async def ensure(
cls, user_qq: int, belonging_group: int, for_update: bool = False cls, user_qq: int, group_id: int, for_update: bool = False
) -> "SignGroupUser": ) -> "SignGroupUser":
""" """
说明: 说明:
获取签到用户 获取签到用户
参数: 参数:
:param user_qq: 用户qq :param user_qq: 用户qq
:param belonging_group: 所在群聊 :param group_id: 所在群聊
:param for_update: 是否存在修改数据 :param for_update: 是否存在修改数据
""" """
query = cls.query.where( query = cls.query.where(
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group) (cls.user_qq == user_qq) & (cls.group_id == group_id)
) )
if for_update: if for_update:
query = query.with_for_update() query = query.with_for_update()
user = await query.gino.first() user = await query.gino.first()
return user or await cls.create( return user or await cls.create(
user_qq=user_qq, user_qq=user_qq,
belonging_group=belonging_group, group_id=group_id,
checkin_count=0, checkin_count=0,
checkin_time_last=datetime.min, # 从未签到过 checkin_time_last=datetime.min, # 从未签到过
impression=0, impression=0,
@@ -79,22 +78,22 @@ class SignGroupUser(db.Model):
).apply() ).apply()
@classmethod @classmethod
async def get_all_impression(cls, belonging_group: int) -> "list, list, list": async def get_all_impression(cls, group_id: int) -> "list, list, list":
""" """
说明: 说明:
获取该群所有用户 id 及对应 好感度 获取该群所有用户 id 及对应 好感度
参数: 参数:
:param belonging_group: 群号 :param group_id: 群号
""" """
impression_list = [] impression_list = []
user_qq_list = [] user_qq_list = []
user_group = [] user_group = []
if belonging_group: if group_id:
query = cls.query.where(cls.belonging_group == belonging_group) query = cls.query.where(cls.group_id == group_id)
else: else:
query = cls.query query = cls.query
for user in await query.gino.all(): for user in await query.gino.all():
impression_list.append(user.impression) impression_list.append(user.impression)
user_qq_list.append(user.user_qq) user_qq_list.append(user.user_qq)
user_group.append(user.belonging_group) user_group.append(user.group_id)
return user_qq_list, impression_list, user_group return user_qq_list, impression_list, user_group
+1 -3
View File
@@ -1,6 +1,4 @@
from nonebot import on_regex 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 nonebot.rule import to_me
from pathlib import Path from pathlib import Path
@@ -29,7 +27,7 @@ about = on_regex("^关于$", priority=5, block=True, rule=to_me())
@about.handle() @about.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
ver_file = Path() / '__version__' ver_file = Path() / '__version__'
version = None version = None
if ver_file.exists(): if ver_file.exists():
+9 -10
View File
@@ -1,15 +1,14 @@
import random
from nonebot import on_keyword
import os
from utils.message_builder import image from utils.message_builder import image
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from nonebot import on_command from nonebot import on_command
from nonebot.rule import to_me from nonebot.rule import to_me
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import GroupMessageEvent
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent from nonebot.adapters.onebot.v11.permission import GROUP
from nonebot.adapters.cqhttp.permission import GROUP
from utils.utils import FreqLimiter from utils.utils import FreqLimiter
from configs.config import NICKNAME from configs.config import NICKNAME
import random
from nonebot import on_keyword
import os
__zx_plugin_name__ = "基本设置 [Hidden]" __zx_plugin_name__ = "基本设置 [Hidden]"
@@ -25,12 +24,12 @@ config_play_game = on_keyword({"打游戏"}, permission=GROUP, priority=1, block
@config_play_game.handle() @config_play_game.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(event: GroupMessageEvent):
if not _flmt.check(event.group_id): if not _flmt.check(event.group_id):
return return
_flmt.start_cd(event.group_id) _flmt.start_cd(event.group_id)
await config_play_game.finish( await config_play_game.finish(
image(random.choice(os.listdir(IMAGE_PATH + "dayouxi/")), "dayouxi") image(random.choice(os.listdir(IMAGE_PATH / "dayouxi")), "dayouxi")
) )
@@ -40,7 +39,7 @@ self_introduction = on_command(
@self_introduction.handle() @self_introduction.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
if NICKNAME.find('真寻') != -1: if NICKNAME.find('真寻') != -1:
result = ( result = (
"我叫绪山真寻\n" "我叫绪山真寻\n"
@@ -57,6 +56,6 @@ my_wife = on_keyword({"老婆"}, rule=to_me(), priority=5, block=True)
@my_wife.handle() @my_wife.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
await my_wife.finish(image("laopo.jpg", "other")) await my_wife.finish(image("laopo.jpg", "other"))
+17 -22
View File
@@ -1,17 +1,15 @@
from nonebot import on_message from nonebot import on_message
from nonebot.adapters.cqhttp import ( from nonebot.adapters.onebot.v11 import (
Bot, Bot,
GroupMessageEvent, GroupMessageEvent,
Message, Message,
MessageEvent, MessageEvent,
) )
from nonebot.rule import to_me from nonebot.rule import to_me
from nonebot.typing import T_State
from models.friend_user import FriendUser from models.friend_user import FriendUser
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from services.log import logger from services.log import logger
from utils.utils import get_message_text, get_message_imgs from utils.utils import get_message_img, get_message_text
from .data_source import get_chat_result, hello, no_result from .data_source import get_chat_result, hello, no_result
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
@@ -21,40 +19,35 @@ usage:
与{NICKNAME}普普通通的对话吧! 与{NICKNAME}普普通通的对话吧!
""" """
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"cmd": ["Ai", "ai", "AI", "aI"], "cmd": ["Ai", "ai", "AI", "aI"],
} }
__plugin_configs__ = { __plugin_configs__ = {
"TL_KEY": { "TL_KEY": {"value": [], "help": "图灵Key"},
"value": [], "ALAPI_AI_CHECK": {"value": False, "help": "是否检测青云客骂娘回复", "default_value": False},
"help": "图灵Key" "TEXT_FILTER": {
"value": ["鸡", "口交"],
"help": "文本过滤器,将敏感词更改为*",
"default_value": [],
}, },
"ALAPI_AI_CHECK": {
"value": False,
"help": "是否检测青云客骂娘回复",
"default_value": False
}
} }
Config.add_plugin_config( Config.add_plugin_config(
"alapi", "alapi", "ALAPI_TOKEN", None, help_="在 https://admin.alapi.cn/user/login 登录后获取token"
"ALAPI_TOKEN",
None,
help_="在https://admin.alapi.cn/user/login登录后获取token"
) )
ai = on_message(rule=to_me(), priority=8) ai = on_message(rule=to_me(), priority=8)
@ai.handle() @ai.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
imgs = get_message_imgs(event.json()) img = get_message_img(event.json())
if "CQ:xml" in str(event.get_message()): if "CQ:xml" in str(event.get_message()):
return return
# 打招呼 # 打招呼
if (not msg and not imgs) or msg in [ if (not msg and not img) or msg in [
"你好啊", "你好啊",
"你好", "你好",
"在吗", "在吗",
@@ -65,7 +58,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
"在", "在",
]: ]:
await ai.finish(hello()) await ai.finish(hello())
img = imgs[0] if imgs else "" img = img[0] if img else ""
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
nickname = await GroupInfoUser.get_group_member_nickname( nickname = await GroupInfoUser.get_group_member_nickname(
event.user_id, event.group_id event.user_id, event.group_id
@@ -74,7 +67,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
nickname = await FriendUser.get_friend_nickname(event.user_id) nickname = await FriendUser.get_friend_nickname(event.user_id)
if not nickname: if not nickname:
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
nickname = event.sender.card if event.sender.card else event.sender.nickname nickname = event.sender.card or event.sender.nickname
else: else:
nickname = event.sender.nickname nickname = event.sender.nickname
result = await get_chat_result(msg, img, event.user_id, nickname) result = await get_chat_result(msg, img, event.user_id, nickname)
@@ -83,6 +76,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
f"问题:{msg} ---- 回答:{result}" f"问题:{msg} ---- 回答:{result}"
) )
if result: if result:
for t in Config.get_config("ai", "TEXT_FILTER"):
result = result.replace(t, "*")
await ai.finish(Message(result)) await ai.finish(Message(result))
else: else:
await ai.finish(no_result()) await ai.finish(no_result())
+4 -4
View File
@@ -20,7 +20,7 @@ check_url = "https://v2.alapi.cn/api/censor/text"
index = 0 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: 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") content = content.replace("{br}", "\n")
if "提示" in content: if "提示" in content:
content = content[: content.find("提示")] content = content[: content.find("提示")]
if "淘宝" in content: if "淘宝" in content or "taobao.com" in content:
return "" return ""
while True: while True:
r = re.search("{face:(.*)}", content) 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": if img[-4:] == ".gif":
result += image(img, "zai") result += image(img, "zai")
else: 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")
) )
+49 -49
View File
@@ -1,49 +1,49 @@
from nonebot.adapters.cqhttp import MessageSegment from nonebot.adapters.onebot.v11 import MessageSegment
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from utils.message_builder import image from utils.message_builder import image
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from typing import Optional from typing import Optional, Tuple, Union
from configs.config import Config from configs.config import Config
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
async def get_data(url: str, params: Optional[dict] = None) -> "Union[dict, str], int": async def get_data(url: str, params: Optional[dict] = None) -> Tuple[Union[dict, str], int]:
""" """
获取ALAPI数据 获取ALAPI数据
:param url: 请求链接 :param url: 请求链接
:param params: 参数 :param params: 参数
""" """
if not params: if not params:
params = {} params = {}
params["token"] = Config.get_config("alapi", "ALAPI_TOKEN") params["token"] = Config.get_config("alapi", "ALAPI_TOKEN")
try: try:
data = (await AsyncHttpx.get(url, params=params, timeout=5)).json() data = (await AsyncHttpx.get(url, params=params, timeout=5)).json()
if data["code"] == 200: if data["code"] == 200:
if not data["data"]: if not data["data"]:
return "没有搜索到...", 997 return "没有搜索到...", 997
return data, 200 return data, 200
else: else:
return f'发生了错误...code:{data["code"]}', 999 return f'发生了错误...code:{data["code"]}', 999
except TimeoutError: except TimeoutError:
return "超时了....", 998 return "超时了....", 998
def gen_wbtop_pic(data: dict) -> MessageSegment: def gen_wbtop_pic(data: dict) -> MessageSegment:
""" """
生成微博热搜图片 生成微博热搜图片
:param data: 微博热搜数据 :param data: 微博热搜数据
""" """
bk = BuildImage(700, 32 * 50 + 280, 700, 32, color="#797979") bk = BuildImage(700, 32 * 50 + 280, 700, 32, color="#797979")
wbtop_bk = BuildImage(700, 280, background=f"{IMAGE_PATH}/other/webtop.png") wbtop_bk = BuildImage(700, 280, background=f"{IMAGE_PATH}/other/webtop.png")
bk.paste(wbtop_bk) bk.paste(wbtop_bk)
text_bk = BuildImage(700, 32 * 50, 700, 32, color="#797979") text_bk = BuildImage(700, 32 * 50, 700, 32, color="#797979")
for i, data in enumerate(data): for i, data in enumerate(data):
title = f"{i+1}. {data['hot_word']}" title = f"{i+1}. {data['hot_word']}"
hot = data["hot_word_num"] hot = data["hot_word_num"]
img = BuildImage(700, 30, font_size=20) img = BuildImage(700, 30, font_size=20)
w, h = img.getsize(title) w, h = img.getsize(title)
img.text((10, int((30 - h) / 2)), title) img.text((10, int((30 - h) / 2)), title)
img.text((580, int((30 - h) / 2)), hot) img.text((580, int((30 - h) / 2)), hot)
text_bk.paste(img) text_bk.paste(img)
bk.paste(text_bk, (0, 280)) bk.paste(text_bk, (0, 280))
return image(b64=bk.pic2bs4()) return image(b64=bk.pic2bs4())
+6 -7
View File
@@ -1,7 +1,6 @@
from nonebot import on_command from nonebot import on_regex
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from nonebot.typing import T_State from ._data_source import get_data
from .data_source import get_data
from services.log import logger from services.log import logger
__zx_plugin_name__ = "网易云热评" __zx_plugin_name__ = "网易云热评"
@@ -23,8 +22,8 @@ __plugin_settings__ = {
} }
comments_163 = on_command( comments_163 = on_regex(
"网易云热评", aliases={"网易云评论", "到点了", "12点了"}, priority=5, block=True "^(网易云热评|网易云评论|到点了|12点了)$", priority=5, block=True
) )
@@ -32,7 +31,7 @@ comments_163_url = "https://v2.alapi.cn/api/comment"
@comments_163.handle() @comments_163.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent):
data, code = await get_data(comments_163_url) data, code = await get_data(comments_163_url)
if code != 200: if code != 200:
await comments_163.finish(data, at_sender=True) await comments_163.finish(data, at_sender=True)
+5 -6
View File
@@ -1,9 +1,8 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent from nonebot.adapters.onebot.v11 import MessageEvent, Message, GroupMessageEvent
from nonebot.typing import T_State
from utils.message_builder import image from utils.message_builder import image
from utils.utils import get_message_text from nonebot.params import CommandArg
from .data_source import get_data from ._data_source import get_data
from services.log import logger from services.log import logger
__zx_plugin_name__ = "b封面" __zx_plugin_name__ = "b封面"
@@ -32,8 +31,8 @@ cover_url = "https://v2.alapi.cn/api/bilibili/cover"
@cover.handle() @cover.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
params = {"c": msg} params = {"c": msg}
data, code = await get_data(cover_url, params) data, code = await get_data(cover_url, params)
if code != 200: if code != 200:
+5 -8
View File
@@ -1,10 +1,7 @@
from nonebot import on_command from nonebot import on_regex
from services.log import logger from services.log import logger
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from nonebot.typing import T_State from ._data_source import get_data
from utils.http_utils import AsyncHttpx
from configs.config import Config
from .data_source import get_data
__zx_plugin_name__ = "鸡汤" __zx_plugin_name__ = "鸡汤"
@@ -28,11 +25,11 @@ __plugin_settings__ = {
url = "https://v2.alapi.cn/api/soul" url = "https://v2.alapi.cn/api/soul"
jitang = on_command("鸡汤", aliases={"毒鸡汤"}, priority=5, block=True) jitang = on_regex("^毒?鸡汤$", priority=5, block=True)
@jitang.handle() @jitang.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent):
try: try:
data, code = await get_data(url) data, code = await get_data(url)
if code != 200: if code != 200:
+3 -4
View File
@@ -1,8 +1,7 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from services.log import logger from services.log import logger
from .data_source import get_data from ._data_source import get_data
__zx_plugin_name__ = "古诗" __zx_plugin_name__ = "古诗"
__plugin_usage__ = """usage: __plugin_usage__ = """usage:
@@ -27,7 +26,7 @@ poetry_url = "https://v2.alapi.cn/api/shici"
@poetry.handle() @poetry.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent):
data, code = await get_data(poetry_url) data, code = await get_data(poetry_url)
if code != 200: if code != 200:
await poetry.finish(data, at_sender=True) await poetry.finish(data, at_sender=True)
+6 -7
View File
@@ -1,11 +1,10 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
from nonebot.typing import T_State from nonebot.params import CommandArg
from services.log import logger from services.log import logger
from .data_source import get_data, gen_wbtop_pic from ._data_source import get_data, gen_wbtop_pic
from utils.utils import get_message_text, is_number from utils.utils import is_number
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.message_builder import image
from utils.http_utils import AsyncPlaywright from utils.http_utils import AsyncPlaywright
import asyncio import asyncio
@@ -38,9 +37,9 @@ wbtop_data = []
@wbtop.handle() @wbtop.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, arg: Message = CommandArg()):
global wbtop_data global wbtop_data
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if not wbtop_data or not msg: if not wbtop_data or not msg:
data, code = await get_data(wbtop_url) data, code = await get_data(wbtop_url)
if code != 200: if code != 200:
+32 -27
View File
@@ -1,6 +1,6 @@
from nonebot import on_command from nonebot import on_command
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent, Message from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
from .data_source import ( from .data_source import (
add_live_sub, add_live_sub,
delete_sub, delete_sub,
@@ -9,14 +9,15 @@ from .data_source import (
get_media_id, get_media_id,
get_sub_status, get_sub_status,
SubManager, SubManager,
BilibiliSub BilibiliSub,
) )
from models.level_user import LevelUser from models.level_user import LevelUser
from configs.config import Config from configs.config import Config
from utils.utils import get_message_text, is_number, scheduler, get_bot from utils.utils import is_number, scheduler, get_bot
from typing import Optional from typing import Optional
from services.log import logger from services.log import logger
from nonebot import Driver from nonebot import Driver
from nonebot.params import CommandArg, ArgStr
import nonebot import nonebot
__zx_plugin_name__ = "B站订阅" __zx_plugin_name__ = "B站订阅"
@@ -68,18 +69,9 @@ async def _():
sub_manager = SubManager() 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() @add_sub.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()):
msg = get_message_text(event.json()).split() msg = arg.extract_plain_text().strip().split()
if len(msg) < 2: if len(msg) < 2:
await add_sub.finish("参数不完全,请查看订阅帮助...") await add_sub.finish("参数不完全,请查看订阅帮助...")
sub_type = msg[0] sub_type = msg[0]
@@ -120,11 +112,22 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
state["id"] = int(id_) state["id"] = int(id_)
@add_sub.got("sub_type")
@add_sub.got("sub_user")
@add_sub.got("id") @add_sub.got("id")
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(
sub_type = state["sub_type"] event: MessageEvent,
sub_user = state["sub_user"] state: T_State,
id_ = state["id"] id_: str = ArgStr("id"),
sub_type: str = ArgStr("sub_type"),
sub_user: str = ArgStr("sub_user"),
):
if sub_type in ["season", "动漫", "番剧"] and state.get("season_data"):
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"]
id_ = int(id_)
if sub_type in ["主播", "直播"]: if sub_type in ["主播", "直播"]:
await add_sub.send(await add_live_sub(id_, sub_user)) await add_sub.send(await add_live_sub(id_, sub_user))
elif sub_type.lower() in ["up", "用户"]: elif sub_type.lower() in ["up", "用户"]:
@@ -141,8 +144,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@del_sub.handle() @del_sub.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if not is_number(msg): if not is_number(msg):
await del_sub.finish("Id必须为数字!", at_sender=True) await del_sub.finish("Id必须为数字!", at_sender=True)
id_ = ( id_ = (
@@ -162,12 +165,11 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@show_sub_info.handle() @show_sub_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(event: MessageEvent):
id_ = ( if isinstance(event, GroupMessageEvent):
f"{event.user_id}:{event.group_id}" id_ = f"{event.group_id}"
if isinstance(event, GroupMessageEvent) else:
else f"{event.user_id}" id_ = f"{event.user_id}"
)
data = await BilibiliSub.get_sub_data(id_) data = await BilibiliSub.get_sub_data(id_)
live_rst = "" live_rst = ""
up_rst = "" up_rst = ""
@@ -181,6 +183,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
up_rst += f"\tUP:{x.uname}\n" f"\tuid:{x.uid}\n" f"------------------\n" up_rst += f"\tUP:{x.uname}\n" f"\tuid:{x.uid}\n" f"------------------\n"
if x.sub_type == "season": if x.sub_type == "season":
season_rst += ( season_rst += (
f"\t番剧id:{x.sub_id}\n"
f"\t番名:{x.season_name}\n" f"\t番名:{x.season_name}\n"
f"\t当前集数:{x.season_current_episode}\n" f"\t当前集数:{x.season_current_episode}\n"
f"------------------\n" f"------------------\n"
@@ -189,7 +192,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
up_rst = "当前订阅的UP:\n" + up_rst if up_rst else up_rst up_rst = "当前订阅的UP:\n" + up_rst if up_rst else up_rst
season_rst = "当前订阅的番剧:\n" + season_rst if season_rst else season_rst season_rst = "当前订阅的番剧:\n" + season_rst if season_rst else season_rst
if not live_rst and not up_rst and not season_rst: if not live_rst and not up_rst and not season_rst:
live_rst = "您目前没有任何订阅..." live_rst = (
"该群目前没有任何订阅..." if isinstance(event, GroupMessageEvent) else "您目前没有任何订阅..."
)
await show_sub_info.send(live_rst + up_rst + season_rst) await show_sub_info.send(live_rst + up_rst + season_rst)
+11 -6
View File
@@ -8,7 +8,6 @@ from utils.message_builder import image
from bilibili_api.user import User from bilibili_api.user import User
from bilibili_api import user from bilibili_api import user
from typing import Optional from typing import Optional
from pathlib import Path
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from datetime import datetime from datetime import datetime
from utils.browser import get_browser from utils.browser import get_browser
@@ -20,7 +19,7 @@ import random
bilibili_search_url = "https://api.bilibili.com/x/web-interface/search/all/v2" bilibili_search_url = "https://api.bilibili.com/x/web-interface/search/all/v2"
dynamic_path = Path(IMAGE_PATH) / "bilibili_sub" / "dynamic" dynamic_path = IMAGE_PATH / "bilibili_sub" / "dynamic"
dynamic_path.mkdir(exist_ok=True, parents=True) dynamic_path.mkdir(exist_ok=True, parents=True)
@@ -165,7 +164,9 @@ async def get_media_id(keyword: str) -> dict:
for _ in range(3): for _ in range(3):
try: try:
_season_data = {} _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: if response.status_code == 200:
data = response.json() data = response.json()
if data.get("data"): if data.get("data"):
@@ -191,7 +192,6 @@ async def get_sub_status(id_: int, sub_type: str) -> Optional[str]:
获取订阅状态 获取订阅状态
:param id_: 订阅 id :param id_: 订阅 id
:param sub_type: 订阅类型 :param sub_type: 订阅类型
:return:
""" """
try: try:
if sub_type == "live": if sub_type == "live":
@@ -201,7 +201,7 @@ async def get_sub_status(id_: int, sub_type: str) -> Optional[str]:
elif sub_type == "season": elif sub_type == "season":
return await _get_season_status(id_) return await _get_season_status(id_)
except ResponseCodeException: except ResponseCodeException:
return "获取信息失败...请检查订阅Id是否存在或稍后再试..." return f"Id:{id_} 获取信息失败...请检查订阅Id是否存在或稍后再试..."
# except Exception as e: # except Exception as e:
# logger.error(f"获取订阅状态发生预料之外的错误 id_:{id_} {type(e)}:{e}") # logger.error(f"获取订阅状态发生预料之外的错误 id_:{id_} {type(e)}:{e}")
# return "发生了预料之外的错误..请稍后再试或联系管理员....." # return "发生了预料之外的错误..请稍后再试或联系管理员....."
@@ -254,7 +254,12 @@ async def _get_up_status(id_: int) -> Optional[str]:
if dynamic_img: if dynamic_img:
await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time) await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time)
rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n" rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n"
if _user.latest_video_created < latest_video_created and video: if (
latest_video_created
and _user.latest_video_created
and video
and _user.latest_video_created < latest_video_created
):
rst = rst + "-------------\n" if rst else rst rst = rst + "-------------\n" if rst else rst
await BilibiliSub.update_sub_info( await BilibiliSub.update_sub_info(
id_, latest_video_created=latest_video_created id_, latest_video_created=latest_video_created
+1 -2
View File
@@ -1,12 +1,11 @@
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
from pathlib import Path
from bilibili_api import user from bilibili_api import user
from io import BytesIO from io import BytesIO
BORDER_PATH = Path(IMAGE_PATH) / "border" BORDER_PATH = IMAGE_PATH / "border"
BORDER_PATH.mkdir(parents=True, exist_ok=True) BORDER_PATH.mkdir(parents=True, exist_ok=True)
+27 -36
View File
@@ -1,12 +1,12 @@
from nonebot import on_command from nonebot import on_command
from .data_source import get_bt_info from .data_source import get_bt_info
from services.log import logger from services.log import logger
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import PrivateMessageEvent, Message
from nonebot.adapters import Bot from nonebot.adapters.onebot.v11.permission import PRIVATE
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 from asyncio.exceptions import TimeoutError
from utils.utils import is_number
from nonebot.params import CommandArg, ArgStr
from nonebot.typing import T_State
__zx_plugin_name__ = "磁力搜索" __zx_plugin_name__ = "磁力搜索"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -28,9 +28,7 @@ __plugin_settings__ = {
"limit_superuser": False, "limit_superuser": False,
"cmd": ["bt", "磁力搜索", "Bt", "BT"], "cmd": ["bt", "磁力搜索", "Bt", "BT"],
} }
__plugin_block_limit__ = { __plugin_block_limit__ = {"rst": "您有bt任务正在进行,请等待结束."}
"rst": "您有bt任务正在进行,请等待结束."
}
__plugin_configs__ = { __plugin_configs__ = {
"BT_MAX_NUM": { "BT_MAX_NUM": {
"value": 10, "value": 10,
@@ -43,44 +41,37 @@ __plugin_configs__ = {
bt = on_command("bt", permission=PRIVATE, priority=5, block=True) 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() @bt.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(state: T_State, arg: Message = CommandArg()):
mp = get_message_text(event.json()) msg = arg.extract_plain_text().strip().split()
if not mp: if msg:
return keyword = None
mp = mp.split() page = 1
if len(mp) == 2: if n := len(msg):
state["keyword"] = mp[0] keyword = msg[0]
state["page"] = mp[1] if n > 1 and is_number(msg[1]) and int(msg[1]) > 0:
page = int(msg[1])
state["keyword"] = keyword
state["page"] = page
else: else:
state["keyword"] = mp[0] state["page"] = 1
state["page"] = "1"
@bt.got("keyword", prompt="虚空磁力?查什么GKD") @bt.got("keyword", prompt="请输入要查询的内容!")
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(
keyword = state["keyword"] event: PrivateMessageEvent,
page = state["page"] state: T_State,
await bt.send("开始搜索....", at_sender=True) keyword: str = ArgStr("keyword"),
page: str = ArgStr("page"),
):
send_flag = False send_flag = False
try: try:
async for title, itype, create_time, file_size, link in get_bt_info( async for title, type_, create_time, file_size, link in get_bt_info(
keyword, page keyword, page
): ):
await bt.send( await bt.send(
f"标题:{title}\n" f"标题:{title}\n"
f"类型:{itype}\n" f"类型:{type_}\n"
f"创建时间:{create_time}\n" f"创建时间:{create_time}\n"
f"文件大小:{file_size}\n" f"文件大小:{file_size}\n"
f"种子:{link}" f"种子:{link}"
+3 -3
View File
@@ -12,7 +12,7 @@ if platform.system() == "Windows":
url = "http://www.eclzz.world" url = "http://www.eclzz.world"
async def get_bt_info(keyword: str, page: str): async def get_bt_info(keyword: str, page: int):
""" """
获取资源信息 获取资源信息
:param keyword: 关键词 :param keyword: 关键词
@@ -34,11 +34,11 @@ async def get_bt_info(keyword: str, page: str):
.strip() .strip()
) )
spans = divs[2].find_all("span") spans = divs[2].find_all("span")
itype = spans[0].text type_ = spans[0].text
create_time = spans[1].find("b").text create_time = spans[1].find("b").text
file_size = spans[2].find("b").text file_size = spans[2].find("b").text
link = await get_download_link(divs[0].find("a")["href"]) link = await get_download_link(divs[0].find("a")["href"])
yield title, itype, create_time, file_size, link yield title, type_, create_time, file_size, link
async def get_download_link(_url: str) -> str: async def get_download_link(_url: str) -> str:
+4 -3
View File
@@ -1,5 +1,6 @@
from .music_163 import get_song_id, get_song_info from .music_163 import get_song_id, get_song_info
from nonebot.adapters.cqhttp import Bot, Event, GroupMessageEvent from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, Message
from nonebot.params import CommandArg
from nonebot.typing import T_State from nonebot.typing import T_State
from services.log import logger from services.log import logger
from nonebot import on_command from nonebot import on_command
@@ -29,8 +30,8 @@ music = on_command("点歌", priority=5, block=True)
@music.handle() @music.handle()
async def handle_first_receive(bot: Bot, event: Event, state: T_State): async def handle_first_receive(state: T_State, arg: Message = CommandArg()):
args = str(event.get_message()).strip() args = arg.extract_plain_text().strip()
if args: if args:
state["song_name"] = args state["song_name"] = args
+1 -3
View File
@@ -1,7 +1,5 @@
from nonebot import on_command from nonebot import on_command
from .data_source import Check 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.rule import to_me
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from utils.message_builder import image from utils.message_builder import image
@@ -29,5 +27,5 @@ check_ = on_command(
@check_.handle() @check_.handle()
async def _(bot: Bot, event: Event, state: T_State): async def _():
await check_.send(image(b64=await check.show())) await check_.send(image(b64=await check.show()))
+1 -2
View File
@@ -4,7 +4,6 @@ from datetime import datetime
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from pathlib import Path
import asyncio import asyncio
from services.log import logger from services.log import logger
@@ -73,6 +72,6 @@ class Check:
A.transparent(1) A.transparent(1)
A.text((10, 10), rst) A.text((10, 10), rst)
_x = max(width, height) _x = max(width, height)
bk = BuildImage(_x + 100, _x + 100, background=Path(IMAGE_PATH) / "background" / "check" / "0.jpg") bk = BuildImage(_x + 100, _x + 100, background=IMAGE_PATH / "background" / "check" / "0.jpg")
bk.paste(A, alpha=True, center_type='center') bk.paste(A, alpha=True, center_type='center')
return bk.pic2bs4() return bk.pic2bs4()
+6 -8
View File
@@ -1,5 +1,4 @@
from nonebot.adapters.cqhttp import Bot, MessageEvent from nonebot.adapters.onebot.v11 import Bot
from nonebot.typing import T_State
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot import on_command from nonebot import on_command
from .data_source import check_update, get_latest_version_data from .data_source import check_update, get_latest_version_data
@@ -8,6 +7,7 @@ from utils.utils import scheduler, get_bot
from pathlib import Path from pathlib import Path
from configs.config import Config from configs.config import Config
from nonebot.rule import to_me from nonebot.rule import to_me
from nonebot.params import ArgStr
import platform import platform
import os import os
@@ -45,7 +45,7 @@ restart = on_command(
@update_zhenxun.handle() @update_zhenxun.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot):
try: try:
code, error = await check_update(bot) code, error = await check_update(bot)
if error: if error:
@@ -67,14 +67,13 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@restart.handle() @restart.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _():
if str(platform.system()).lower() == "windows": if str(platform.system()).lower() == "windows":
await restart.finish("暂无windows重启脚本...") await restart.finish("暂无windows重启脚本...")
@restart.got("flag", prompt="确定是否重启真寻?(重启失败咱们将失去联系,请谨慎!)") @restart.got("flag", prompt="确定是否重启真寻?(重启失败咱们将失去联系,请谨慎!)")
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(flag: str = ArgStr("flag")):
flag = state["flag"]
if flag.lower() in ["true", "是", "好", "确定", "确定是"]: if flag.lower() in ["true", "是", "好", "确定", "确定是"]:
await restart.send("开始重启真寻..请稍等...") await restart.send("开始重启真寻..请稍等...")
open("is_restart", "w") open("is_restart", "w")
@@ -107,8 +106,7 @@ async def _():
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), user_id=int(list(bot.config.superusers)[0]),
message=f"检测到真寻版本更新\n" message=f"检测到真寻版本更新\n"
f"当前版本:{_version},最新版本:{latest_version}\n" f"当前版本:{_version},最新版本:{latest_version}",
f"尝试自动更新...",
) )
# try: # try:
# code = await check_update(bot) # code = await check_update(bot)
+1 -1
View File
@@ -1,4 +1,4 @@
from nonebot.adapters.cqhttp import Bot, Message from nonebot.adapters.onebot.v11 import Bot, Message
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.message_builder import image from utils.message_builder import image
+4 -6
View File
@@ -1,6 +1,6 @@
from nonebot import on_command from nonebot import on_regex
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent from nonebot.adapters.onebot.v11 import Bot, MessageEvent
from utils.message_builder import image from utils.message_builder import image
from services.log import logger from services.log import logger
from utils.manager import withdraw_message_manager from utils.manager import withdraw_message_manager
@@ -31,12 +31,10 @@ __plugin_configs__ = {
}, },
} }
coser = on_command( coser = on_regex("^(cos|COS|coser|括丝)$", priority=5, block=True)
"cos", aliases={"coser", "括丝", "COS", "Cos", "cOS", "coS"}, priority=5, block=True
)
url = "http://iw233.cn/API/cos.php" url = "https://api.iyk0.com/cos"
@coser.handle() @coser.handle()
+25 -26
View File
@@ -1,12 +1,12 @@
from nonebot import on_command from nonebot import on_command
from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from utils.utils import get_message_text, is_number, get_message_imgs from utils.utils import is_number, get_message_img
from utils.message_builder import image from utils.message_builder import image
from utils.message_builder import text as _text from utils.message_builder import text as _text
from services.log import logger from services.log import logger
from utils.message_builder import at from utils.message_builder import at
from nonebot.params import CommandArg
__zx_plugin_name__ = "联系管理员" __zx_plugin_name__ = "联系管理员"
@@ -58,12 +58,10 @@ reply = on_command("/t", priority=1, permission=SUPERUSER, block=True)
@dialogue.handle() @dialogue.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
uid = event.user_id text = arg.extract_plain_text().strip()
coffee = int(list(bot.config.superusers)[0])
text = get_message_text(event.json())
img_msg = _text("") img_msg = _text("")
for img in get_message_imgs(event.json()): for img in get_message_img(event.json()):
img_msg += image(img) img_msg += image(img)
if not text and not img_msg: if not text and not img_msg:
await dialogue.send("请发送[滴滴滴]+您要说的内容~", at_sender=True) await dialogue.send("请发送[滴滴滴]+您要说的内容~", at_sender=True)
@@ -76,17 +74,18 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
group_name = (await bot.get_group_info(group_id=event.group_id))[ group_name = (await bot.get_group_info(group_id=event.group_id))[
"group_name" "group_name"
] ]
nickname = event.sender.card if event.sender.card else event.sender.nickname nickname = event.sender.card or event.sender.nickname
await bot.send_private_msg( for coffee in bot.config.superusers:
user_id=coffee, await bot.send_private_msg(
message=_text( user_id=int(coffee),
f"*****一份交流报告*****\n" message=_text(
f"昵称:{nickname}({uid})\n" f"*****一份交流报告*****\n"
f"群聊:{group_name}({group_id})\n" f"昵称:{nickname}({event.user_id})\n"
f"消息:{text}" f"群聊:{group_name}({group_id})\n"
f"消息:{text}"
)
+ img_msg,
) )
+ img_msg,
)
await dialogue.send( await dialogue.send(
_text(f"您的话已发送至管理员!\n======\n{text}") + img_msg, at_sender=True _text(f"您的话已发送至管理员!\n======\n{text}") + img_msg, at_sender=True
) )
@@ -99,12 +98,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
"msg": _text(text) + img_msg, "msg": _text(text) + img_msg,
} }
# print(dialogue_data) # print(dialogue_data)
logger.info(f"Q{uid}@群{group_id} 联系管理员:{coffee} text:{text}") logger.info(f"Q{event.user_id}@群{group_id} 联系管理员:text:{text}")
@reply.handle() @reply.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
msg = get_message_text(event.json()) msg = arg.extract_plain_text().strip()
if not msg: if not msg:
result = "*****待回复消息总览*****\n" result = "*****待回复消息总览*****\n"
for key in dialogue_data.keys(): for key in dialogue_data.keys():
@@ -127,26 +126,26 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
id_ = msg[0] id_ = msg[0]
user_id = dialogue_data[id_]["user_id"] user_id = dialogue_data[id_]["user_id"]
group_id = dialogue_data[id_]["group_id"] group_id = dialogue_data[id_]["group_id"]
text = msg[1] text = " ".join(msg[1:])
dialogue_data.pop(id_) dialogue_data.pop(id_)
else: else:
user_id = 0 user_id = 0
if is_number(msg[1]): if is_number(msg[1]):
group_id = int(msg[1]) group_id = int(msg[1])
text = msg[2] text = " ".join(msg[2:])
else: else:
await reply.finish("群号错误...", at_sender=True) await reply.finish("群号错误...", at_sender=True)
else: else:
user_id = int(msg[0]) user_id = int(msg[0])
if is_number(msg[1]) and len(msg[1]) > 5: if is_number(msg[1]) and len(msg[1]) > 5:
group_id = int(msg[1]) group_id = int(msg[1])
text = msg[2] text = " ".join(msg[2:])
else: else:
group_id = 0 group_id = 0
text = msg[1] text = " ".join(msg[1:])
else: else:
await reply.finish("第一参数,请输入数字.....", at_sender=True) await reply.finish("第一参数,请输入数字.....", at_sender=True)
for img in get_message_imgs(event.json()): for img in get_message_img(event.json()):
text += image(img) text += image(img)
if group_id: if group_id:
if user_id: if user_id:
+104 -167
View File
@@ -1,16 +1,13 @@
from nonebot import on_regex, on_keyword from nonebot import on_regex, on_keyword
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.typing import T_State from nonebot.typing import T_State
from .genshin_handle import ( from nonebot.params import RegexGroup
genshin_draw, from utils.utils import scheduler
update_genshin_info, from .genshin_handle import genshin_draw, update_genshin_info, reset_count, reload_genshin_pool
reset_count,
reload_genshin_pool,
)
from .prts_handle import update_prts_info, prts_draw, reload_prts_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 .pretty_handle import update_pretty_info, pretty_draw, reload_pretty_pool
from .guardian_handle import update_guardian_info, guardian_draw from .guardian_handle import update_guardian_info, guardian_draw, reload_guardian_pool
from .pcr_handle import update_pcr_info, pcr_draw from .pcr_handle import update_pcr_info, pcr_draw
from .azur_handle import update_azur_info, azur_draw from .azur_handle import update_azur_info, azur_draw
from .fgo_handle import update_fgo_info, fgo_draw from .fgo_handle import update_fgo_info, fgo_draw
@@ -18,21 +15,12 @@ from .onmyoji_handle import update_onmyoji_info, onmyoji_draw
from .update_game_info import update_info from .update_game_info import update_info
from .util import is_number, check_num from .util import is_number, check_num
from .rule import is_switch from .rule import is_switch
from .config import ( from .config import draw_config
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 .async_update_game_info import async_update_game
from typing import Tuple, Any
import re import re
import asyncio import asyncio
from utils.utils import scheduler
from services.log import logger
__zx_plugin_name__ = "游戏抽卡" __zx_plugin_name__ = "游戏抽卡"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -101,81 +89,43 @@ __plugin_settings__ = {
"cmd": ["游戏抽卡", "抽卡"], "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)
prts = on_regex( genshin = on_regex(r'.*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('genshin'), priority=5, block=True)
r".*?方舟[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("prts"), priority=5, block=True genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True)
) genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True)
prts_update = on_keyword( genshin_up_reload = on_keyword({'重载原神卡池'}, priority=1, block=True)
{"更新方舟信息", "更新明日方舟信息"}, permission=SUPERUSER, priority=1, block=True
)
prts_up_reload = on_keyword({"重载方舟卡池"}, priority=1, block=True)
genshin = on_regex( pretty = on_regex(r'.*?马娘卡?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('pretty'), priority=5, block=True)
".*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井]", pretty_update = on_keyword({'更新马娘信息', '更新赛马娘信息'}, permission=SUPERUSER, priority=1, block=True)
rule=is_switch("genshin"), pretty_up_reload = on_keyword({'重载赛马娘卡池'}, priority=1, block=True)
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)
pretty = on_regex( guardian = on_regex(r'.*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('guardian'), priority=5, block=True)
".*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("pretty"), priority=5, block=True guardian_update = on_keyword({'更新坎公骑冠剑信息'}, permission=SUPERUSER, priority=1, block=True)
) guardian_up_reload = on_keyword({'重载坎公骑冠剑卡池'}, priority=1, block=True)
pretty_update = on_keyword(
{"更新马娘信息", "更新赛马娘信息"}, permission=SUPERUSER, priority=1, block=True
)
pretty_up_reload = on_keyword({"重载赛马娘卡池"}, priority=1, block=True)
guardian = on_regex( pcr = on_regex(r'.*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('pcr'), priority=5, block=True)
".*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井]", pcr_update = on_keyword({'更新pcr信息', '更新公主连结信息'}, permission=SUPERUSER, priority=1, block=True)
rule=is_switch("guardian"),
priority=5,
block=True,
)
guardian_update = on_keyword(
{"更新坎公骑冠剑信息"}, permission=SUPERUSER, priority=1, block=True
)
pcr = on_regex( azur = on_regex(r'.*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('azur'), priority=5, block=True)
".*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井]", azur_update = on_keyword({'更新碧蓝信息', '更新碧蓝航线信息'}, permission=SUPERUSER, priority=1, block=True)
rule=is_switch("pcr"),
priority=5,
block=True,
)
pcr_update = on_keyword(
{"更新pcr信息", "更新公主连结信息"}, permission=SUPERUSER, priority=1, block=True
)
azur = on_regex( fgo = on_regex(r'.*?fgo[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('fgo'), priority=5, block=True)
".*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽]", fgo_update = on_keyword({'更新fgo信息'}, permission=SUPERUSER, priority=1, block=True)
rule=is_switch("azur"),
priority=5,
block=True,
)
azur_update = on_keyword(
{"更新碧蓝信息", "更新碧蓝航线信息"}, permission=SUPERUSER, priority=1, block=True
)
fgo = on_regex( onmyoji = on_regex(r'.*?阴阳师[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('onmyoji'), priority=5, block=True)
".*?fgo[1-9|一][0-9]{0,2}[抽]", rule=is_switch("fgo"), priority=5, block=True onmyoji_update = on_keyword({'更新阴阳师信息'}, permission=SUPERUSER, priority=1, 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() @prts.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State, reg: Tuple[Any, ...] = RegexGroup()):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
if msg in ["方舟一井", "方舟1井"]: if msg in ['方舟一井', '方舟1井']:
num = 300 num = 300
else: else:
rmsg = re.search(r".*?方舟(.*)抽", msg) rmsg = re.search(r'.*?方舟(.*)[抽|连]', msg)
if rmsg: if rmsg:
num, flag = check_num(rmsg.group(1), 300) num, flag = check_num(rmsg.group(1), 300)
if not flag: if not flag:
@@ -183,31 +133,28 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else: else:
return return
await prts.send(await prts_draw(int(num)), at_sender=True) 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() @prts_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_prts_pool() 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() @genshin.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
rmsg = re.search(r".*?原神(武器|角色)?池?(.*)[抽|井]", msg) rmsg = re.search(r'.*?原神(武器|角色)?池?(.*)[抽|井|连]', msg)
if rmsg: if rmsg:
pool_name = rmsg.group(1) pool_name = rmsg.group(1)
if pool_name == "武器": if pool_name == '武器':
pool_name = "arms" pool_name = 'arms'
elif pool_name == "角色": elif pool_name == '角色':
pool_name = "char" pool_name = 'char'
else: else:
pool_name = "" pool_name = ''
num = rmsg.group(2) num = rmsg.group(2)
if msg.find("一井") != -1 or msg.find("1井") != -1: if msg.find('一井') != -1 or msg.find('1井') != -1:
num = 180 num = 180
else: else:
num, flag = check_num(num, 180) num, flag = check_num(num, 180)
@@ -215,94 +162,89 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await genshin.finish(num, at_sender=True) await genshin.finish(num, at_sender=True)
else: else:
return return
await genshin.send( await genshin.send(await genshin_draw(event.user_id, int(num), pool_name), at_sender=True)
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() @genshin_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_genshin_pool() text = await reload_genshin_pool()
await genshin_reset.finish(Message(f"重载成功!\n{text}")) await genshin_reset.finish(Message(f'重载成功!\n{text}'))
@genshin_reset.handle() @genshin_reset.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
reset_count(event.user_id) reset_count(event.user_id)
await genshin_reset.send("重置了原神抽卡次数", at_sender=True) await genshin_reset.send('重置了原神抽卡次数', at_sender=True)
@pretty.handle() @pretty.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() 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 num = 200
if msg.find("卡") == -1: if msg.find("卡") == -1:
pool_name = "char" pool_name = 'char'
else: else:
pool_name = "card" pool_name = 'card'
else: else:
rmsg = re.search(r".*?马娘(.*)抽", msg) rmsg = re.search(r'.*?马娘(.*)[抽|连]', msg)
if rmsg: if rmsg:
num = rmsg.group(1) num = rmsg.group(1)
if num[0] == "卡": if num[0] == '卡':
num = num[1:] num = num[1:]
pool_name = "card" pool_name = 'card'
else: else:
pool_name = "char" pool_name = 'char'
num, flag = check_num(num, 200) num, flag = check_num(num, 200)
if not flag: if not flag:
await pretty.finish(num, at_sender=True) await pretty.finish(num, at_sender=True)
else: else:
return return
await pretty.send(await pretty_draw(int(num), pool_name), at_sender=True) 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() @pretty_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_pretty_pool() text = await reload_pretty_pool()
await genshin_reset.finish(Message(f"重载成功!\n{text}")) await genshin_reset.finish(Message(f'重载成功!\n{text}'))
@guardian.handle() @guardian.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
pool_name = "char" pool_name = 'char'
if msg.find("1井") != -1 or msg.find("一井") != -1: if msg.find('1井') != -1 or msg.find('一井') != -1:
num = 300 num = 300
if msg.find("武器") != -1: if msg.find('武器') != -1:
pool_name = "arms" pool_name = 'arms'
else: else:
rmsg = re.search(r".*?坎公骑冠剑(.*)抽", msg) rmsg = re.search(r'.*?坎公骑冠剑(.*)[抽|连]', msg)
if rmsg: if rmsg:
num = rmsg.group(1) num = rmsg.group(1)
if num.find("武器") != -1: if num.find('武器') != -1:
pool_name = "arms" pool_name = 'arms'
num = num.replace("武器", "") num = num.replace('武器', '')
num, flag = check_num(num, 300) num, flag = check_num(num, 300)
if not flag: if not flag:
await guardian.finish(num, at_sender=True) await guardian.finish(num, at_sender=True)
else: else:
return return
await guardian.send(await guardian_draw(int(num), pool_name), at_sender=True) await guardian.send(await guardian_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}抽"
) @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}'))
@pcr.handle() @pcr.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() 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 num = 300
else: else:
rmsg = re.search(r".*?(pcr|公主连结)(.*)[抽|井]", msg) rmsg = re.search(r'.*?(pcr|公主连结)(.*)[抽|井|连]', msg)
if rmsg: if rmsg:
num, flag = check_num(rmsg.group(2), 300) num, flag = check_num(rmsg.group(2), 300)
if not flag: if not flag:
@@ -310,15 +252,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else: else:
return return
await pcr.send(await pcr_draw(int(num)), at_sender=True) 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() @azur.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
rmsg = re.search(".*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽]", msg) rmsg = re.search(r'.*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽|连]', msg)
if rmsg: if rmsg:
pool_name = rmsg.group(1) pool_name = rmsg.group(1)
num, flag = check_num(rmsg.group(2), 300) num, flag = check_num(rmsg.group(2), 300)
@@ -327,15 +266,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else: else:
return return
await azur.send(await azur_draw(int(num), pool_name), at_sender=True) 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() @fgo.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
rmsg = re.search(".*?fgo(.*)抽", msg) rmsg = re.search(r'.*?fgo(.*)[抽|连]', msg)
if rmsg: if rmsg:
num, flag = check_num(rmsg.group(1), 300) num, flag = check_num(rmsg.group(1), 300)
if not flag: if not flag:
@@ -343,15 +279,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else: else:
return return
await fgo.send(await fgo_draw(int(num)), at_sender=True) 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() @onmyoji.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
rmsg = re.search(".*?阴阳师(.*)抽", msg) rmsg = re.search(r'.*?阴阳师(.*)[抽|连]', msg)
if rmsg: if rmsg:
num, flag = check_num(rmsg.group(1), 300) num, flag = check_num(rmsg.group(1), 300)
if not flag: if not flag:
@@ -359,118 +292,122 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else: else:
return return
await onmyoji.send(await onmyoji_draw(int(num)), at_sender=True) 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() @prts_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_prts_info() await update_prts_info()
await prts_update.finish("更新完成!") await prts_update.finish('更新完成!')
@genshin_update.handle() @genshin_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_genshin_info() await update_genshin_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
@pretty_update.handle() @pretty_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pretty_info() await update_pretty_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
@guardian_update.handle() @guardian_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_guardian_info() await update_guardian_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
@pcr_update.handle() @pcr_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pcr_info() await update_pcr_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
@azur_update.handle() @azur_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_azur_info() await update_azur_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
@fgo_update.handle() @fgo_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_fgo_info() await update_fgo_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
@onmyoji_update.handle() @onmyoji_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_onmyoji_info() await update_onmyoji_info()
await genshin_update.finish("更新完成!") await genshin_update.finish('更新完成!')
# 更新资源 # 更新资源
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", 'cron',
hour=4, hour=4,
minute=1, minute=1,
) )
async def _(): async def _():
tasks = [] tasks = []
if PRTS_FLAG: if draw_config.PRTS_FLAG:
tasks.append(asyncio.ensure_future(update_prts_info())) tasks.append(asyncio.ensure_future(update_prts_info()))
if GENSHIN_FLAG: if draw_config.GENSHIN_FLAG:
tasks.append(asyncio.ensure_future(update_genshin_info())) tasks.append(asyncio.ensure_future(update_genshin_info()))
if PRETTY_FLAG: if draw_config.PRETTY_FLAG:
tasks.append(asyncio.ensure_future(update_pretty_info())) tasks.append(asyncio.ensure_future(update_pretty_info()))
if GUARDIAN_FLAG: if draw_config.GUARDIAN_FLAG:
tasks.append(asyncio.ensure_future(update_guardian_info())) tasks.append(asyncio.ensure_future(update_guardian_info()))
if PCR_FLAG: if draw_config.PCR_FLAG:
tasks.append(asyncio.ensure_future(update_pcr_info())) tasks.append(asyncio.ensure_future(update_pcr_info()))
if AZUR_FLAG: if draw_config.AZUR_FLAG:
tasks.append(asyncio.ensure_future(update_azur_info())) tasks.append(asyncio.ensure_future(update_azur_info()))
if FGO_FLAG: if draw_config.FGO_FLAG:
tasks.append(asyncio.ensure_future(update_fgo_info())) tasks.append(asyncio.ensure_future(update_fgo_info()))
if ONMYOJI_FLAG: if draw_config.ONMYOJI_FLAG:
tasks.append(asyncio.ensure_future(update_onmyoji_info())) tasks.append(asyncio.ensure_future(update_onmyoji_info()))
await asyncio.gather(*tasks) await asyncio.gather(*tasks)
logger.info("draw_card 抽卡自动更新完成...")
# 每天四点重载方舟up卡池 # 每天四点重载方舟up卡池
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", 'cron',
hour=4, hour=4,
minute=1, minute=1,
) )
async def _(): async def _():
if PRTS_FLAG: if draw_config.PRTS_FLAG:
await reload_prts_pool() await reload_prts_pool()
logger.info("自动重载方舟卡池UP成功")
# 每天四点重载赛马娘up卡池 # 每天四点重载赛马娘up卡池
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", 'cron',
hour=4, hour=4,
minute=1, minute=1,
) )
async def _(): async def _():
if PRETTY_FLAG: if draw_config.PRETTY_FLAG:
await reload_pretty_pool() await reload_pretty_pool()
logger.info("自动重载赛马娘UP成功")
# 每天下午六点点重载原神up卡池 # 每天下午六点点重载原神up卡池
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", 'cron',
hour=18, hour=18,
minute=1, minute=1,
) )
async def _(): async def _():
if PRTS_FLAG: if draw_config.PRTS_FLAG:
await reload_genshin_pool() await reload_genshin_pool()
logger.info("自动重载原神卡池UP成功")
# 重载坎公骑冠剑卡池
@scheduler.scheduled_job(
'cron',
hour=4,
minute=1,
)
async def _():
if draw_config.GUARDIAN_FLAG:
await reload_guardian_pool()
+74 -69
View File
@@ -1,11 +1,11 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from datetime import datetime, timedelta
from .config import DRAW_PATH
from pathlib import Path
from asyncio.exceptions import TimeoutError
from services.log import logger
from utils.http_utils import AsyncHttpx
import re import re
from datetime import datetime, timedelta
from .config import DRAW_DATA_PATH
from asyncio.exceptions import TimeoutError
from nonebot.log import logger
from utils.http_utils import AsyncHttpx
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: 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)"'} headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
prts_up_char = Path(DRAW_PATH + "/draw_card_up/prts_up_char.json") prts_up_char = DRAW_DATA_PATH / "draw_card_up" / "prts_up_char.json"
genshin_up_char = Path(DRAW_PATH + "/draw_card_up/genshin_up_char.json") genshin_up_char = DRAW_DATA_PATH / "draw_card_up" / "genshin_up_char.json"
pretty_up_char = Path(DRAW_PATH + "/draw_card_up/pretty_up_char.json") pretty_up_char = DRAW_DATA_PATH / "draw_card_up" / "pretty_up_char.json"
guardian_up_char = Path(DRAW_PATH + "/draw_card_up/guardian_up_char.json") guardian_up_char = DRAW_DATA_PATH / "draw_card_up" / "guardian_up_char.json"
prts_url = "https://ak.hypergryph.com/news.html" prts_url = "https://ak.hypergryph.com/news.html"
genshin_url = "https://wiki.biligame.com/ys/%E7%A5%88%E6%84%BF" 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): def is_expired(data: dict):
try: times = data['time'].split('-')
times = data['time'].split('-') for i in range(len(times)):
for i in range(len(times)): times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-')
times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-') start_date = datetime.strptime(times[0], '%Y-%m-%d').date()
start_date = datetime.strptime(times[0], '%Y-%m-%d').date() end_date = datetime.strptime(times[1], '%Y-%m-%d').date()
end_date = datetime.strptime(times[1], '%Y-%m-%d').date() now = datetime.now().date()
now = datetime.now().date() return not start_date <= now <= end_date
except ValueError:
return False
return start_date <= now <= end_date
# 检查写入 # 检查写入
def check_write(data: dict, up_char_file): def check_write(data: dict, up_char_file):
if is_expired(data['char']): try:
for x in list(data.keys()): if is_expired(data['char']):
data[x]['title'] = '' for x in list(data.keys()):
else: data[x]['title'] = ''
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: else:
with open(up_char_file, 'w', encoding='utf8') as f: with open(up_char_file, 'w', encoding='utf8') as f:
json.dump(data, f, indent=4, ensure_ascii=False) 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 return data
@@ -66,17 +66,22 @@ class PrtsAnnouncement:
self.game_name = '明日方舟' self.game_name = '明日方舟'
async def _get_announcement_text(self): async def _get_announcement_text(self):
text = (await AsyncHttpx.get(prts_url)).text res = await AsyncHttpx.get(prts_url, timeout=7)
soup = BeautifulSoup(text, 'lxml') soup = BeautifulSoup(res.text, 'lxml')
ol = soup.find('ol', {'class': 'articleList active', 'data-category-key': 'LATEST'}) ol = soup.find('ol', {'class': 'articleList active', 'data-category-key': 'LATEST'})
for li in ol: for li in ol:
itype = li.find('span', {'class': 'articleItemCate'}).text type_ = li.find('span', {'class': 'articleItemCate'}).text
if itype == '活动': if type_ == '活动':
a = li.find('a')['href'] a = li.find('a')['href']
return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}')).text return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}', timeout=7)).text
async def update_up_char(self): async def update_up_char(self):
prts_up_char.parent.mkdir(parents=True, exist_ok=True) 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: try:
data = {'char': {'up_char': {'6': {}, '5': {}, '4': {}}, 'title': '', 'time': '', 'pool_img': ''}} data = {'char': {'up_char': {'6': {}, '5': {}, '4': {}}, 'title': '', 'time': '', 'pool_img': ''}}
text = await self._get_announcement_text() text = await self._get_announcement_text()
@@ -145,7 +150,7 @@ class GenshinAnnouncement:
self.game_name = '原神' self.game_name = '原神'
async def _get_announcement_text(self): async def _get_announcement_text(self):
return (await AsyncHttpx.get(genshin_url)).text return (await AsyncHttpx.get(genshin_url, timeout=7)).text
async def update_up_char(self): async def update_up_char(self):
genshin_up_char.parent.mkdir(exist_ok=True, parents=True) genshin_up_char.parent.mkdir(exist_ok=True, parents=True)
@@ -162,34 +167,34 @@ class GenshinAnnouncement:
trs = table.find('tbody').find_all('tr') trs = table.find('tbody').find_all('tr')
pool_img = trs[0].find('th').find('img') pool_img = trs[0].find('th').find('img')
if pool_img['title'].find('角色活动') == -1: if pool_img['title'].find('角色活动') == -1:
itype = 'arms' type_ = 'arms'
else: else:
itype = 'char' type_ = 'char'
try: try:
data[itype]['pool_img'] = str(pool_img['srcset']).split(' ')[0] data[type_]['pool_img'] = str(pool_img['srcset']).split(' ')[0]
except KeyError: except KeyError:
data[itype]['pool_img'] = pool_img['src'] data[type_]['pool_img'] = pool_img['src']
data[itype]['title'] = str(pool_img['title']).split(f'期{"角色" if itype == "char" else "武器"}')[0][:-3] data[type_]['title'] = str(pool_img['title']).split(f'期{"角色" if type_ == "char" else "武器"}')[0][:-3]
data[itype]['time'] = trs[1].find('td').text data[type_]['time'] = trs[1].find('td').text
if data[itype]['time'][-1] == '\n': if data[type_]['time'][-1] == '\n':
data[itype]['time'] = data[itype]['time'][:-1] data[type_]['time'] = data[type_]['time'][:-1]
if '版本更新后' in data[itype]['time']: if '版本更新后' in data[type_]['time']:
sp = data[itype]['time'].split('~') sp = data[type_]['time'].split('~')
end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M:%S") end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M")
start_time = end_time - timedelta(days=20) start_time = end_time - timedelta(days=20)
data[itype]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d') data[type_]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d')
tmp = '' tmp = ''
for tm in data[itype]['time'].split('~'): for tm in data[type_]['time'].split('~'):
date_time_sp = tm.split('/') date_time_sp = tm.split('/')
date_time_sp[2] = date_time_sp[2].strip().replace(' ', '日 ') date_time_sp[2] = date_time_sp[2].strip().replace(' ', '日 ')
tmp += date_time_sp[1] + '月' + date_time_sp[2] + ' - ' tmp += date_time_sp[1] + '月' + date_time_sp[2] + ' - '
data[itype]['time'] = tmp[:-2].strip() data[type_]['time'] = tmp[:-2].strip()
for a in trs[2].find('td').find_all('a'): for a in trs[2].find('td').find_all('a'):
char_name = a['title'] char_name = a['title']
data[itype]['up_char']['5'][char_name] = "50" data[type_]['up_char']['5'][char_name] = "50"
for a in trs[3].find('td').find_all('a'): for a in trs[3].find('td').find_all('a'):
char_name = a['title'] char_name = a['title']
data[itype]['up_char']['4'][char_name] = "50" data[type_]['up_char']['4'][char_name] = "50"
except TimeoutError: except TimeoutError:
logger.warning(f'更新原神UP池信息超时...') logger.warning(f'更新原神UP池信息超时...')
if genshin_up_char.exists(): if genshin_up_char.exists():
@@ -214,10 +219,9 @@ class PrettyAnnouncement:
self.game_name = '赛马娘' self.game_name = '赛马娘'
async def _get_announcement_text(self): async def _get_announcement_text(self):
text = (await AsyncHttpx.get(pretty_url)).text res = await AsyncHttpx.get(pretty_url, timeout=7)
soup = BeautifulSoup(text, 'lxml') soup = BeautifulSoup(res.text, 'lxml')
divs = soup.find('div', {'id': 'mw-content-text'}).find('div').find_all('div') divs = soup.find('div', {'id': 'mw-content-text'}).find('div').find_all('div')
title = " "
for div in divs: for div in divs:
a = div.find('a') a = div.find('a')
try: try:
@@ -227,10 +231,9 @@ class PrettyAnnouncement:
if title.find('新角色追加') != -1: if title.find('新角色追加') != -1:
url = a['href'] url = a['href']
break break
return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}')).text, title[:-2] return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}', timeout=7)).text, title[:-2]
async def update_up_char(self): async def update_up_char(self):
pretty_up_char.parent.mkdir(exist_ok=True, parents=True)
data = { data = {
'char': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''}, 'char': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''},
'card': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''} 'card': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''}
@@ -243,12 +246,14 @@ class PrettyAnnouncement:
context = soup.find('div', {'class': 'mw-parser-output'}) context = soup.find('div', {'class': 'mw-parser-output'})
data['char']['title'] = title data['char']['title'] = title
data['card']['title'] = title data['card']['title'] = title
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)) for big in context.find_all('big'):
if r: r = re.search(r'\d{1,2}/\d{1,2} \d{1,2}:\d{1,2}', str(big.text))
time = str(r.group(1)) if r:
time = str(big.text)
break
else: else:
logger.error('赛马娘UP无法找到活动日期....取消更新UP池子...') logger.warning('赛马娘UP无法找到活动日期....取消更新UP池子...')
return check_write(data, pretty_up_char) return
time = time.replace('~', '-').replace('/', '月').split(' ') time = time.replace('~', '-').replace('/', '月').split(' ')
time = time[0] + '日 ' + time[1] + ' - ' + time[3] + '日 ' + time[4] time = time[0] + '日 ' + time[1] + ' - ' + time[3] + '日 ' + time[4]
data['char']['time'] = time data['char']['time'] = time
@@ -309,7 +314,7 @@ class PrettyAnnouncement:
if star == 'R': if star == 'R':
data['card']['up_char']['1'][char_name] = '70' data['card']['up_char']['1'][char_name] = '70'
# 日文->中文 # 日文->中文
with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f: with open(DRAW_DATA_PATH / 'pretty_card.json', 'r', encoding='utf8') as f:
all_data = json.load(f) all_data = json.load(f)
for star in data['card']['up_char'].keys(): for star in data['card']['up_char'].keys():
for name in list(data['card']['up_char'][star].keys()): for name in list(data['card']['up_char'][star].keys()):
@@ -338,7 +343,7 @@ class GuardianAnnouncement:
self.game_name = '坎公骑冠剑' self.game_name = '坎公骑冠剑'
async def _get_announcement_text(self): async def _get_announcement_text(self):
return (await AsyncHttpx.get(guardian_url)).text return (await AsyncHttpx.get(guardian_url, timeout=7)).text
async def update_up_char(self): async def update_up_char(self):
data = { data = {
+16 -23
View File
@@ -1,7 +1,6 @@
import asyncio import asyncio
import nonebot import nonebot
import os from nonebot.log import logger
from services.log import logger
from .pcr_handle import update_pcr_info, init_pcr_data from .pcr_handle import update_pcr_info, init_pcr_data
from .azur_handle import update_azur_info, init_azur_data from .azur_handle import update_azur_info, init_azur_data
from .prts_handle import update_prts_info, init_prts_data from .prts_handle import update_prts_info, init_prts_data
@@ -10,11 +9,10 @@ from .guardian_handle import update_guardian_info, init_guardian_data
from .genshin_handle import update_genshin_info, init_genshin_data from .genshin_handle import update_genshin_info, init_genshin_data
from .fgo_handle import update_fgo_info, init_fgo_data from .fgo_handle import update_fgo_info, init_fgo_data
from .onmyoji_handle import update_onmyoji_info, init_onmyoji_data from .onmyoji_handle import update_onmyoji_info, init_onmyoji_data
from .config import DRAW_PATH, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, PCR_FLAG, AZUR_FLAG, GENSHIN_FLAG, FGO_FLAG, \ from .config import draw_config, DRAW_DATA_PATH
ONMYOJI_FLAG
driver: nonebot.Driver = nonebot.get_driver() driver = nonebot.get_driver()
@driver.on_startup @driver.on_startup
@@ -22,49 +20,44 @@ async def async_update_game():
tasks = [] tasks = []
init_lst = [init_pcr_data, init_pretty_data, init_azur_data, init_prts_data, init_genshin_data, init_guardian_data, 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] init_fgo_data, init_onmyoji_data]
if PRTS_FLAG and not os.path.exists(DRAW_PATH + 'prts.json'): if draw_config.PRTS_FLAG and not (DRAW_DATA_PATH / 'prts.json').exists():
tasks.append(asyncio.ensure_future(update_prts_info())) tasks.append(asyncio.ensure_future(update_prts_info()))
init_lst.remove(init_prts_data) init_lst.remove(init_prts_data)
if PRETTY_FLAG and (not os.path.exists(DRAW_PATH + 'pretty.json') or if draw_config.PRETTY_FLAG and (not (DRAW_DATA_PATH / 'pretty.json').exists() or
not os.path.exists(DRAW_PATH + 'pretty_card.json')): not (DRAW_DATA_PATH / 'pretty_card.json').exists()):
tasks.append(asyncio.ensure_future(update_pretty_info())) tasks.append(asyncio.ensure_future(update_pretty_info()))
init_lst.remove(init_pretty_data) init_lst.remove(init_pretty_data)
if GUARDIAN_FLAG and not os.path.exists(DRAW_PATH + 'guardian.json'): if draw_config.GUARDIAN_FLAG and not (DRAW_DATA_PATH / 'guardian.json').exists():
tasks.append(asyncio.ensure_future(update_guardian_info())) tasks.append(asyncio.ensure_future(update_guardian_info()))
init_lst.remove(init_guardian_data)
if PCR_FLAG and not os.path.exists(DRAW_PATH + 'pcr.json'): if draw_config.PCR_FLAG and not (DRAW_DATA_PATH / 'pcr.json').exists():
tasks.append(asyncio.ensure_future(update_pcr_info())) tasks.append(asyncio.ensure_future(update_pcr_info()))
init_lst.remove(init_pcr_data) init_lst.remove(init_pcr_data)
if GENSHIN_FLAG and (not os.path.exists(DRAW_PATH + 'genshin.json') or if draw_config.GENSHIN_FLAG and (not (DRAW_DATA_PATH / 'genshin.json').exists() or
not os.path.exists(DRAW_PATH + 'genshin_arms.json')): not (DRAW_DATA_PATH / 'genshin_arms.json').exists()):
tasks.append(asyncio.ensure_future(update_genshin_info())) tasks.append(asyncio.ensure_future(update_genshin_info()))
init_lst.remove(init_genshin_data) init_lst.remove(init_genshin_data)
if AZUR_FLAG and not os.path.exists(DRAW_PATH + 'azur.json'): if draw_config.AZUR_FLAG and not (DRAW_DATA_PATH / 'azur.json').exists():
tasks.append(asyncio.ensure_future(update_azur_info())) tasks.append(asyncio.ensure_future(update_azur_info()))
init_lst.remove(init_azur_data) init_lst.remove(init_azur_data)
if FGO_FLAG and (not os.path.exists(DRAW_PATH + 'fgo.json') or if draw_config.FGO_FLAG and (not (DRAW_DATA_PATH / 'fgo.json').exists() or
not os.path.exists(DRAW_PATH + 'fgo_card.json')): not (DRAW_DATA_PATH / 'fgo_card.json').exists()):
tasks.append(asyncio.ensure_future(update_fgo_info())) tasks.append(asyncio.ensure_future(update_fgo_info()))
init_lst.remove(init_fgo_data) init_lst.remove(init_fgo_data)
if ONMYOJI_FLAG and not os.path.exists(DRAW_PATH + 'onmyoji.json'): if draw_config.ONMYOJI_FLAG and not (DRAW_DATA_PATH / 'onmyoji.json').exists():
tasks.append(asyncio.ensure_future(update_onmyoji_info())) tasks.append(asyncio.ensure_future(update_onmyoji_info()))
init_lst.remove(init_onmyoji_data) init_lst.remove(init_onmyoji_data)
try: try:
await asyncio.gather(*tasks) await asyncio.gather(*tasks)
for func in init_lst: for func in init_lst:
await func() await func()
except asyncio.exceptions.CancelledError: except asyncio.exceptions.CancelledError:
logger.info('更新异常:CancelledError,再次更新...') logger.warning('更新异常:CancelledError,再次更新...')
await async_update_game() await async_update_game()
+12 -13
View File
@@ -1,9 +1,8 @@
from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.adapters.cqhttp import MessageSegment
import random import random
from .update_game_simple_info import update_simple_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, format_card_information from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card, format_card_information
from .config import AZUR_ONE_P, AZUR_TWO_P, AZUR_THREE_P, AZUR_FOUR_P, AZUR_FLAG, DRAW_PATH from .config import draw_config, DRAW_DATA_PATH
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
try: try:
@@ -16,7 +15,7 @@ ALL_CHAR = []
@dataclass @dataclass
class AzurChar(BaseData): class AzurChar(BaseData):
itype: str # 舰娘类型 type_: str # 舰娘类型
async def azur_draw(count: int, pool_name: str): async def azur_draw(count: int, pool_name: str):
@@ -42,22 +41,22 @@ async def update_azur_info():
async def init_azur_data(): async def init_azur_data():
global ALL_CHAR global ALL_CHAR
if AZUR_FLAG: if draw_config.AZUR_FLAG:
with open(DRAW_PATH + 'azur.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'azur.json').open('r', encoding='utf8') as f:
azur_dict = json.load(f) azur_dict = json.load(f)
ALL_CHAR = init_game_pool('azur', azur_dict, AzurChar) ALL_CHAR = init_game_pool('azur', azur_dict, AzurChar)
# 抽取卡池 # 抽取卡池
def _get_azur_card(pool_name: str): def _get_azur_card(pool_name: str, mode: int = 1):
global ALL_CHAR global ALL_CHAR
azur_config = draw_config.azur
if pool_name == '轻型': if pool_name == '轻型':
itype = ['驱逐', '轻巡', '维修'] type_ = ['驱逐', '轻巡', '维修']
elif pool_name == '重型': elif pool_name == '重型':
itype = ['重巡', '战列', '战巡', '重炮'] type_ = ['重巡', '战列', '战巡', '重炮']
else: else:
itype = ['维修', '潜艇', '重巡', '轻航', '航母'] type_ = ['维修', '潜艇', '重巡', '轻航', '航母']
star = get_star([4, 3, 2, 1], [AZUR_FOUR_P, AZUR_THREE_P, AZUR_TWO_P, AZUR_ONE_P]) 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.itype in itype and not x.limited] chars = [x for x in ALL_CHAR if x.star == star and x.type_ in type_ and not x.limited]
return random.choice(chars), 4 - star return random.choice(chars), 4 - star
+123 -371
View File
@@ -1,6 +1,7 @@
import nonebot import nonebot
from pathlib import Path from nonebot.log import logger
from configs.path_config import DATA_PATH from pydantic import BaseModel, Extra, ValidationError
from configs.path_config import IMAGE_PATH, DATA_PATH
from configs.config import Config from configs.config import Config
try: try:
@@ -9,133 +10,111 @@ except ModuleNotFoundError:
import json import json
DRAW_PATH = DATA_PATH + "/draw_card/" # 原神
class GenshinConfig(BaseModel, extra=Extra.ignore):
_draw_config = Path(rf"{DRAW_PATH}/draw_card_config/draw_card_config.json") 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
for game_flag, game_name in zip( # 明日方舟
[ class PrtsConfig(BaseModel, extra=Extra.ignore):
"PRTS_FLAG", PRTS_SIX_P: float = 0.02
"GENSHIN_FLAG", PRTS_FIVE_P: float = 0.08
"PRETTY_FLAG", PRTS_FOUR_P: float = 0.48
"GUARDIAN_FLAG", PRTS_THREE_P: float = 0.42
"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")
# 方舟概率 # 赛马娘
PRTS_SIX_P = 0.02 class PrettyConfig(BaseModel, extra=Extra.ignore):
PRTS_FIVE_P = 0.08 PRETTY_THREE_P: float = 0.03
PRTS_FOUR_P = 0.48 PRETTY_TWO_P: float = 0.18
PRTS_THREE_P = 0.42 PRETTY_ONE_P: float = 0.79
# 原神概率
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 = 0.0275 GUARDIAN_THREE_CHAR_P: float = 0.0275
GUARDIAN_TWO_CHAR_P = 0.19 GUARDIAN_TWO_CHAR_P: float = 0.19
GUARDIAN_ONE_CHAR_P = 0.7825 GUARDIAN_ONE_CHAR_P: float = 0.7825
# UP角色 GUARDIAN_THREE_CHAR_UP_P: float = 0.01375
GUARDIAN_THREE_CHAR_UP_P = 0.01375 GUARDIAN_THREE_CHAR_OTHER_P: float = 0.01375
GUARDIAN_THREE_CHAR_OTHER_P = 0.01375 GUARDIAN_EXCLUSIVE_ARMS_P: float = 0.03
# 武器概率 GUARDIAN_FIVE_ARMS_P: float = 0.03
GUARDIAN_EXCLUSIVE_ARMS_P = 0.03 GUARDIAN_FOUR_ARMS_P: float = 0.09
GUARDIAN_FIVE_ARMS_P = 0.03 GUARDIAN_THREE_ARMS_P: float = 0.27
GUARDIAN_FOUR_ARMS_P = 0.09 GUARDIAN_TWO_ARMS_P: float = 0.58
GUARDIAN_THREE_ARMS_P = 0.27 GUARDIAN_EXCLUSIVE_ARMS_UP_P: float = 0.01
GUARDIAN_TWO_ARMS_P = 0.58 GUARDIAN_EXCLUSIVE_ARMS_OTHER_P: float = 0.02
# UP武器
GUARDIAN_EXCLUSIVE_ARMS_UP_P = 0.01
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P = 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
# 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
# 碧蓝航线 # 碧蓝航线
AZUR_FIVE_P = 0.012 class AzurConfig(BaseModel, extra=Extra.ignore):
AZUR_FOUR_P = 0.07 AZUR_FIVE_P: float = 0.012
AZUR_THREE_P = 0.12 AZUR_FOUR_P: float = 0.07
AZUR_TWO_P = 0.51 AZUR_THREE_P: float = 0.12
AZUR_ONE_P = 0.3 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
# 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_SP = 0.0025 class OnmyojiConfig(BaseModel, extra=Extra.ignore):
ONMYOJI_SSR = 0.01 ONMYOJI_SP: float = 0.0025
ONMYOJI_SR = 0.2 ONMYOJI_SSR: float = 0.01
ONMYOJI_R = 0.7875 ONMYOJI_SR: float = 0.2
ONMYOJI_R: float = 0.7875
path_dict = { class PathDict(BaseModel, extra=Extra.ignore):
"genshin": "原神", genshin: str = "原神"
"prts": "明日方舟", prts: str = "明日方舟"
"pretty": "赛马娘", pretty: str = "赛马娘"
"guardian": "坎公骑冠剑", guardian: str = "坎公骑冠剑"
"pcr": "公主连结", pcr: str = "公主连结"
"azur": "碧蓝航线", azur: str = "碧蓝航线"
"fgo": "命运-冠位指定", fgo: str = "命运-冠位指定"
"onmyoji": "阴阳师", onmyoji: str = "阴阳师"
}
driver: nonebot.Driver = nonebot.get_driver()
config_default_data = { class DrawConfig(BaseModel, extra=Extra.ignore):
"path_dict": { # 开关
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 = {
"genshin": "原神", "genshin": "原神",
"prts": "明日方舟", "prts": "明日方舟",
"pretty": "赛马娘", "pretty": "赛马娘",
@@ -144,268 +123,41 @@ config_default_data = {
"azur": "碧蓝航线", "azur": "碧蓝航线",
"fgo": "命运-冠位指定", "fgo": "命运-冠位指定",
"onmyoji": "阴阳师", "onmyoji": "阴阳师",
}, }
"prts": {
"PRTS_SIX_P": 0.02, # 抽卡概率
"PRTS_FIVE_P": 0.08, prts: PrtsConfig = PrtsConfig()
"PRTS_FOUR_P": 0.48, genshin: GenshinConfig = GenshinConfig()
"PRTS_THREE_P": 0.42, pretty: PrettyConfig = PrettyConfig()
}, guardian: GuardianConfig = GuardianConfig()
"genshin": { pcr: PcrConfig = PcrConfig()
"GENSHIN_FIVE_P": 0.006, azur: AzurConfig = AzurConfig()
"GENSHIN_FOUR_P": 0.051, fgo: FgoConfig = FgoConfig()
"GENSHIN_THREE_P": 0.43, onmyoji: OnmyojiConfig = OnmyojiConfig()
"GENSHIN_G_FIVE_P": 0.13,
"GENSHIN_G_FOUR_P": 0.016,
"I72_ADD": 0.0585, driver = nonebot.get_driver()
}, global_config = driver.config
"pretty": { DRAW_DATA_PATH = DATA_PATH / "draw_card"
"PRETTY_THREE_P": 0.03, DRAW_IMAGE_PATH = IMAGE_PATH / "draw_card"
"PRETTY_TWO_P": 0.18, # DRAW_PATH = Path(draw_path) if draw_path else Path("data/draw_card").absolute()
"PRETTY_ONE_P": 0.79, config_path = DRAW_DATA_PATH / "draw_card_config" / "draw_card_config.json"
},
"guardian": { draw_config: Config = DrawConfig()
"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 @driver.on_startup
def check_config(): def check_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 global draw_config
_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:
try: if not config_path.exists():
PRTS_SIX_P = float(data["prts"]["PRTS_SIX_P"]) config_path.parent.mkdir(parents=True, exist_ok=True)
PRTS_FIVE_P = float(data["prts"]["PRTS_FIVE_P"]) draw_config = DrawConfig()
PRTS_FOUR_P = float(data["prts"]["PRTS_FOUR_P"]) logger.warning("draw_card:配置文件不存在,已重新生成配置文件.....")
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"]
try: json.dump(
GENSHIN_FIVE_P = float(data["genshin"]["GENSHIN_FIVE_P"]) draw_config.dict(),
GENSHIN_FOUR_P = float(data["genshin"]["GENSHIN_FOUR_P"]) config_path.open("w", encoding="utf8"),
GENSHIN_THREE_P = float(data["genshin"]["GENSHIN_THREE_P"]) indent=4,
GENSHIN_G_FIVE_P = float(data["genshin"]["GENSHIN_G_FIVE_P"]) ensure_ascii=False,
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
)
+113
View File
@@ -0,0 +1,113 @@
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
+18 -19
View File
@@ -1,10 +1,8 @@
from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.adapters.cqhttp import MessageSegment
import random import random
from .update_game_requests_info import update_requests_info 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 .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
from .config import FGO_CARD_FOUR_P, FGO_CARD_FIVE_P, FGO_CARD_THREE_P, FGO_SERVANT_THREE_P, \ from .config import DRAW_DATA_PATH, draw_config
FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_FLAG, DRAW_PATH
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
@@ -45,11 +43,11 @@ async def update_fgo_info():
async def init_fgo_data(): async def init_fgo_data():
global ALL_CHAR, ALL_CARD global ALL_CHAR, ALL_CARD
if FGO_FLAG: if draw_config.FGO_FLAG:
with open(DRAW_PATH + 'fgo.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'fgo.json').open('r', encoding='utf8') as f:
fgo_dict = json.load(f) fgo_dict = json.load(f)
ALL_CHAR = init_game_pool('fgo', fgo_dict, FgoChar) ALL_CHAR = init_game_pool('fgo', fgo_dict, FgoChar)
with open(DRAW_PATH + 'fgo_card.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'fgo_card.json').open('r', encoding='utf8') as f:
fgo_dict = json.load(f) fgo_dict = json.load(f)
ALL_CARD = init_game_pool('fgo', fgo_dict, FgoChar) ALL_CARD = init_game_pool('fgo', fgo_dict, FgoChar)
@@ -57,21 +55,22 @@ async def init_fgo_data():
# 抽取卡池 # 抽取卡池
def _get_fgo_card(mode: int = 1): def _get_fgo_card(mode: int = 1):
global ALL_CHAR, ALL_CARD global ALL_CHAR, ALL_CARD
fgo_config = draw_config.fgo
if mode == 1: if mode == 1:
star = get_star([8, 7, 6, 5, 4, 3], [FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_THREE_P, 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_CARD_FIVE_P, FGO_CARD_FOUR_P, FGO_CARD_THREE_P]) fgo_config.FGO_CARD_FIVE_P, fgo_config.FGO_CARD_FOUR_P, fgo_config.FGO_CARD_THREE_P])
elif mode == 2: elif mode == 2:
star = get_star([5, 4], [FGO_CARD_FIVE_P, FGO_CARD_FOUR_P]) star = get_star([5, 4], [fgo_config.FGO_CARD_FIVE_P, fgo_config.FGO_CARD_FOUR_P])
else: else:
star = get_star([8, 7, 6], [FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_THREE_P]) star = get_star([8, 7, 6], [fgo_config.FGO_SERVANT_FIVE_P, fgo_config.FGO_SERVANT_FOUR_P, fgo_config.FGO_SERVANT_THREE_P])
if star > 5: if star > 5:
itype = 'servant' type_ = 'servant'
star -= 3 star -= 3
chars = [x for x in ALL_CHAR if x.star == star if not x.limited] chars = [x for x in ALL_CHAR if x.star == star if not x.limited]
else: else:
itype = 'card' type_ = 'card'
chars = [x for x in ALL_CARD if x.star == star if not x.limited] chars = [x for x in ALL_CARD if x.star == star if not x.limited]
return random.choice(chars), 5 - star, itype return random.choice(chars), 5 - star, type_
# 整理数据 # 整理数据
@@ -88,18 +87,18 @@ def _format_card_information(count: int):
card_count += 1 card_count += 1
# 四星卡片保底 # 四星卡片保底
if card_count == 9: if card_count == 9:
obj, code, itype = _get_fgo_card(2) obj, code, type_ = _get_fgo_card(2)
# 三星从者保底 # 三星从者保底
elif servant_count == 10: elif servant_count == 10:
obj, code, itype = _get_fgo_card(3) obj, code, type_ = _get_fgo_card(3)
_count = 0 _count = 0
# 普通抽 # 普通抽
else: else:
obj, code, itype = _get_fgo_card() obj, code, type_ = _get_fgo_card()
star_list[code] += 1 star_list[code] += 1
if itype == 'card' and code < 2: if type_ == 'card' and code < 2:
card_count = 0 card_count = 0
if itype == 'servant': if type_ == 'servant':
servant_count = 0 servant_count = 0
if code == 0: if code == 0:
max_star_lst.append(obj.name) max_star_lst.append(obj.name)
+188 -110
View File
@@ -1,10 +1,16 @@
import os from nonebot.adapters.onebot.v11 import MessageSegment, Message
from nonebot.adapters.cqhttp import MessageSegment, Message
import random import random
from .update_game_info import update_info from .update_game_info import update_info
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, init_up_char from .util import (
from .config import GENSHIN_FIVE_P, GENSHIN_FOUR_P, GENSHIN_G_FIVE_P, GENSHIN_G_FOUR_P, GENSHIN_THREE_P, I72_ADD, \ generate_img,
DRAW_PATH, GENSHIN_FLAG init_rst,
BaseData,
set_list,
get_star,
init_up_char,
)
from .config import DRAW_DATA_PATH, draw_config
from .count_manager import GenshinCountManager
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
from .announcement import GenshinAnnouncement from .announcement import GenshinAnnouncement
@@ -17,9 +23,11 @@ except ModuleNotFoundError:
announcement = GenshinAnnouncement() announcement = GenshinAnnouncement()
genshin_five = {} draw_count_manager = GenshinCountManager((10, 90), ("4", "5"))
genshin_count = {}
genshin_pl_count = {} # genshin_five = {}
# genshin_count = {}
# genshin_pl_count = {}
ALL_CHAR = [] ALL_CHAR = []
ALL_ARMS = [] ALL_ARMS = []
@@ -27,9 +35,10 @@ ALL_ARMS = []
UP_CHAR = [] UP_CHAR = []
UP_ARMS = [] UP_ARMS = []
_CURRENT_CHAR_POOL_TITLE = ''
_CURRENT_ARMS_POOL_TITLE = '' _CURRENT_CHAR_POOL_TITLE = ""
POOL_IMG = '' _CURRENT_ARMS_POOL_TITLE = ""
POOL_IMG = ""
@dataclass @dataclass
@@ -39,19 +48,22 @@ class GenshinChar(BaseData):
async def genshin_draw(user_id: int, count: int, pool_name: str): async def genshin_draw(user_id: int, count: int, pool_name: str):
# 0 1 2 # 0 1 2
cnlist = ['★★★★★', '★★★★', '★★★'] star = ["★★★★★", "★★★★", "★★★"]
char_list, five_list, five_index_list, char_dict, star_list = _format_card_information(count, user_id, pool_name) (
temp = '' char_list,
title = '' five_dict,
star_num_list,
) = _format_card_information(count, user_id, pool_name)
title = ""
up_type = [] up_type = []
up_list = [] up_list = []
if pool_name == 'char' and _CURRENT_CHAR_POOL_TITLE: if pool_name == "char" and _CURRENT_CHAR_POOL_TITLE:
up_type = UP_CHAR up_type = UP_CHAR
title = _CURRENT_CHAR_POOL_TITLE 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 up_type = UP_ARMS
title = _CURRENT_ARMS_POOL_TITLE title = _CURRENT_ARMS_POOL_TITLE
tmp = '' tmp = ""
if up_type: if up_type:
for x in up_type: for x in up_type:
for operator in x.operators: for operator in x.operators:
@@ -60,151 +72,217 @@ async def genshin_draw(user_id: int, count: int, pool_name: str):
tmp += f'五星UP:{" ".join(x.operators)} \n' tmp += f'五星UP:{" ".join(x.operators)} \n'
elif x.star == 4: elif x.star == 4:
tmp += f'四星UP:{" ".join(x.operators)}' tmp += f'四星UP:{" ".join(x.operators)}'
rst = init_star_rst(star_list, cnlist, five_list, five_index_list, up_list) rst = init_rst(five_dict, star_num_list, star, up_list)
pool_info = f'当前up池:{title}\n{tmp}' if title else '' pool_info = f"当前up池:{title}\n{tmp}" if title else ""
if count > 90: if count > 90:
char_list = set_list(char_list) char_list = set_list(char_list)
return pool_info + '\n' + MessageSegment.image( return (
"base64://" + await generate_img(char_list, 'genshin', star_list)) + '\n' + rst[:-1] + \ pool_info
temp[:-1] + f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"} 抽' \ + "\n"
+ "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】" + 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%】"
)
async def update_genshin_info(): async def update_genshin_info():
global ALL_CHAR, ALL_ARMS global ALL_CHAR, ALL_ARMS
url = 'https://wiki.biligame.com/ys/角色筛选' url = "https://wiki.biligame.com/ys/角色筛选"
data, code = await update_info(url, 'genshin') data, code = await update_info(url, "genshin")
if code == 200: if code == 200:
ALL_CHAR = init_game_pool('genshin', data, GenshinChar) ALL_CHAR = init_game_pool("genshin", data, GenshinChar)
url = 'https://wiki.biligame.com/ys/武器图鉴' url = "https://wiki.biligame.com/ys/武器图鉴"
data, code = await update_info(url, 'genshin_arms', ['头像', '名称', '类型', '稀有度.alt', data, code = await update_info(
'获取途径', '初始基础属性1', '初始基础属性2', url,
'攻击力(MAX)', '副属性(MAX)', '技能']) "genshin_arms",
)
if code == 200: 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() await _genshin_init_up_char()
async def init_genshin_data(): async def init_genshin_data():
global ALL_CHAR, ALL_ARMS global ALL_CHAR, ALL_ARMS
if GENSHIN_FLAG: if draw_config.GENSHIN_FLAG:
if not os.path.exists(DRAW_PATH + 'genshin.json') or not os.path.exists(DRAW_PATH + 'genshin_arms.json'): if not (DRAW_DATA_PATH / "genshin.json").exists() or not (DRAW_DATA_PATH / "genshin_arms.json").exists():
await update_genshin_info() await update_genshin_info()
else: else:
with open(DRAW_PATH + 'genshin.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / "genshin.json").open("r", encoding="utf8") as f:
genshin_dict = json.load(f) genshin_dict = json.load(f)
with open(DRAW_PATH + 'genshin_arms.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / "genshin_arms.json").open("r", encoding="utf8") as f:
genshin_ARMS_dict = json.load(f) genshin_ARMS_dict = json.load(f)
ALL_CHAR = init_game_pool('genshin', genshin_dict, GenshinChar) ALL_CHAR = init_game_pool("genshin", genshin_dict, GenshinChar)
ALL_ARMS = init_game_pool('genshin_arms', genshin_ARMS_dict, GenshinChar) ALL_ARMS = init_game_pool("genshin_arms", genshin_ARMS_dict, GenshinChar)
await _genshin_init_up_char() await _genshin_init_up_char()
# 抽取卡池 # 抽取卡池
def _get_genshin_card(mode: int = 1, pool_name: str = '', add: float = 0.0): def _get_genshin_card(mode: int = 1, pool_name: str = "", add: float = 0.0, is_up: bool = False):
"""
mode 1:普通抽 2:四星保底 3:五星保底
"""
global ALL_ARMS, ALL_CHAR, UP_ARMS, UP_CHAR, _CURRENT_ARMS_POOL_TITLE, _CURRENT_CHAR_POOL_TITLE 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: if mode == 1:
star = get_star([5, 4, 3], [GENSHIN_FIVE_P + add, GENSHIN_FOUR_P, GENSHIN_THREE_P]) star = get_star(
[5, 4, 3], [genshin_config.GENSHIN_FIVE_P + add, genshin_config.GENSHIN_FOUR_P, genshin_config.GENSHIN_THREE_P]
)
elif mode == 2: elif mode == 2:
star = get_star([5, 4], [GENSHIN_G_FIVE_P + add, GENSHIN_G_FOUR_P]) star = get_star([5, 4], [genshin_config.GENSHIN_G_FIVE_P + add, genshin_config.GENSHIN_G_FOUR_P])
else: else:
star = 5 star = 5
if pool_name == 'char': if pool_name == "char":
data_lst = UP_CHAR data_lst = UP_CHAR
flag = _CURRENT_CHAR_POOL_TITLE flag = _CURRENT_CHAR_POOL_TITLE
itype_all_lst = ALL_CHAR + [x for x in ALL_ARMS if x.star == star and x.star < 5] type_all_lst = ALL_CHAR + [
elif pool_name == 'arms': x for x in ALL_ARMS if x.star == star and x.star < 5
]
elif pool_name == "arms":
data_lst = UP_ARMS data_lst = UP_ARMS
flag = _CURRENT_ARMS_POOL_TITLE flag = _CURRENT_ARMS_POOL_TITLE
itype_all_lst = ALL_ARMS + [x for x in ALL_CHAR if x.star == star and x.star < 5] type_all_lst = ALL_ARMS + [
x for x in ALL_CHAR if x.star == star and x.star < 5
]
else: else:
data_lst = '' data_lst = ""
flag = '' flag = ""
itype_all_lst = '' type_all_lst = ""
all_lst = ALL_ARMS + ALL_CHAR all_lst = ALL_ARMS + ALL_CHAR
# 是否UP # 是否UP
if flag and star > 3 and pool_name: try:
# 获取up角色列表 if flag and star > 3:
up_char_lst = [x.operators for x in data_lst if x.star == star][0] # 获取up角色列表
# 成功获取up角色 up_char_lst = [x.operators for x in data_lst if x.star == star][0]
if random.random() < 0.5: # print(up_char_lst)
up_char_name = random.choice(up_char_lst) # 成功获取up角色
acquire_char = [x for x in all_lst if x.name == up_char_name][0] 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)
else: else:
# 无up chars = [x for x in all_lst if x.star == star and not x.limited]
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(chars)
acquire_char = random.choice(all_char_lst) except IndexError:
else:
chars = [x for x in all_lst if x.star == star and not x.limited] chars = [x for x in all_lst if x.star == star and not x.limited]
acquire_char = random.choice(chars) acquire_char = random.choice(chars)
return acquire_char, 5 - star return acquire_char, 5 - star
def _format_card_information(_count: int, user_id, pool_name): def _format_card_information(_count: int, user_id, pool_name):
char_list = [] char_list = [] # 获取角色列表
star_list = [0, 0, 0] star_num_list = [0, 0, 0] # 各个星级数量
five_index_list = [] five_dict = {} # 五星数量
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 add = 0.0
if genshin_count.get(user_id) and _count <= _x: pool = UP_CHAR if pool_name == 'char' else UP_ARMS
f_count = genshin_count[user_id] for _ in range(_count):
else: draw_count_manager.increase(user_id)
f_count = 0 star = draw_count_manager.check(user_id)
if genshin_pl_count.get(user_id) and _count <= _x: if (draw_count_manager.get_user_count(user_id) - draw_count_manager.get_user_count(user_id, 1)) % 90 >= 72:
count = genshin_pl_count[user_id] add += draw_config.genshin.I72_ADD
else: if star:
count = 0 star = int(star)
for i in range(_count): if star == 4:
count += 1 char, code = _get_genshin_card(2, pool_name, add=add)
f_count += 1 draw_count_manager.record_count(user_id, 0)
# 十连保底 else:
if count == 10 and f_count != _x: char, code = _get_genshin_card(3, pool_name, add, draw_count_manager.is_up(user_id))
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: else:
if f_count >= _start_add_count: char, code = _get_genshin_card(1, pool_name, add, draw_count_manager.is_up(user_id))
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 code == 0:
if _count <= _x: add = 0
genshin_five[user_id] = f_count if not five_dict.get(char.name):
add = 0.0 five_dict[char.name] = [draw_count_manager.get_user_count(user_id)]
f_count = 0 else:
five_list.append(char.name) five_dict[char.name].append(draw_count_manager.get_user_count(user_id) % 90)
five_index_list.append(i) draw_count_manager.set_count(user_id, 2, draw_count_manager.get_user_count(user_id, 1))
try: draw_count_manager.record_count(user_id, 0)
five_dict[char.name] += 1 draw_count_manager.record_count(user_id, 1)
except KeyError: if char.name not in [x.operators for x in pool if x.star == 5][0]:
five_dict[char.name] = 1 draw_count_manager.set_is_up(user_id, True)
else:
draw_count_manager.set_is_up(user_id, False)
star_num_list[code] += 1
char_list.append(char) char_list.append(char)
if _count <= _x: return char_list, five_dict, star_num_list
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 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
def reset_count(user_id: int): def reset_count(user_id: int):
genshin_count[user_id] = 0 draw_count_manager.reset(user_id)
genshin_pl_count[user_id] = 0
# 获取up和概率 # 获取up和概率
async def _genshin_init_up_char(): async def _genshin_init_up_char():
global _CURRENT_CHAR_POOL_TITLE, _CURRENT_ARMS_POOL_TITLE, UP_CHAR, UP_ARMS, POOL_IMG 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(): async def reload_genshin_pool():
await _genshin_init_up_char() 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}"
)
+16 -17
View File
@@ -1,17 +1,12 @@
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 .update_game_info import update_info
from .announcement import GuardianAnnouncement
from .util import init_star_rst, generate_img, max_card, BaseData,\ from .util import init_star_rst, generate_img, max_card, BaseData,\
set_list, get_star, format_card_information, init_up_char set_list, get_star, format_card_information, init_up_char
import random import random
from .config import DRAW_PATH, GUARDIAN_ONE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_THREE_CHAR_P, \ from .config import DRAW_DATA_PATH, draw_config
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 dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
from .announcement import GuardianAnnouncement
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -96,13 +91,13 @@ async def update_guardian_info():
async def init_guardian_data(): async def init_guardian_data():
global ALL_CHAR, ALL_ARMS global ALL_CHAR, ALL_ARMS
if GUARDIAN_FLAG: if draw_config.GUARDIAN_FLAG:
if not os.path.exists(DRAW_PATH + 'guardian.json') or not os.path.exists(DRAW_PATH + 'guardian_arms.json'): if not (DRAW_DATA_PATH / 'guardian.json').exists() or not (DRAW_DATA_PATH / 'guardian_arms.json').exists():
await update_guardian_info() await update_guardian_info()
else: else:
with open(DRAW_PATH + 'guardian.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'guardian.json').open('r', encoding='utf8') as f:
guardian_char_dict = json.load(f) guardian_char_dict = json.load(f)
with open(DRAW_PATH + 'guardian_arms.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'guardian_arms.json').open('r', encoding='utf8') as f:
guardian_arms_dict = json.load(f) guardian_arms_dict = json.load(f)
ALL_CHAR = init_game_pool('guardian', guardian_char_dict, GuardianChar) ALL_CHAR = init_game_pool('guardian', guardian_char_dict, GuardianChar)
ALL_ARMS = init_game_pool('guardian_arms', guardian_arms_dict, GuardianArms) ALL_ARMS = init_game_pool('guardian_arms', guardian_arms_dict, GuardianArms)
@@ -112,21 +107,22 @@ async def init_guardian_data():
# 抽取卡池 # 抽取卡池
def _get_guardian_card(pool_name: str = '', mode: int = 1): 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 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 pool_name == 'char':
if mode == 1: if mode == 1:
star = get_star([3, 2, 1], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_ONE_CHAR_P]) star = get_star([3, 2, 1], [guardian_config.GUARDIAN_THREE_CHAR_P, guardian_config.GUARDIAN_TWO_CHAR_P, guardian_config.GUARDIAN_ONE_CHAR_P])
else: else:
star = get_star([3, 2], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P]) star = get_star([3, 2], [guardian_config.GUARDIAN_THREE_CHAR_P, guardian_config.GUARDIAN_TWO_CHAR_P])
up_lst = UP_CHAR up_lst = UP_CHAR
flag = _CURRENT_CHAR_POOL_TITLE flag = _CURRENT_CHAR_POOL_TITLE
_max_star = 3 _max_star = 3
all_data = ALL_CHAR all_data = ALL_CHAR
else: else:
if mode == 1: if mode == 1:
star = get_star([5, 4, 3, 2], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P, star = get_star([5, 4, 3, 2], [guardian_config.GUARDIAN_FIVE_ARMS_P, guardian_config.GUARDIAN_FOUR_ARMS_P,
GUARDIAN_THREE_ARMS_P, GUARDIAN_TWO_ARMS_P]) guardian_config.GUARDIAN_THREE_ARMS_P, guardian_config.GUARDIAN_TWO_ARMS_P])
else: else:
star = get_star([5, 4], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P]) star = get_star([5, 4], [guardian_config.GUARDIAN_FIVE_ARMS_P, guardian_config.GUARDIAN_FOUR_ARMS_P])
up_lst = UP_ARMS up_lst = UP_ARMS
flag = _CURRENT_ARMS_POOL_TITLE flag = _CURRENT_ARMS_POOL_TITLE
_max_star = 5 _max_star = 5
@@ -158,3 +154,6 @@ async def _guardian_init_up_char():
async def reload_guardian_pool(): async def reload_guardian_pool():
await _guardian_init_up_char() await _guardian_init_up_char()
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE}') return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE}')
+123 -56
View File
@@ -1,137 +1,204 @@
from typing import Any from typing import Any
from .config import DATA_PATH from .config import DRAW_DATA_PATH
from utils.utils import is_number from .util import is_number
from pathlib import Path from nonebot.log import logger
from services.log import logger
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
def init_game_pool(game: str, data: dict, Operator: Any): def init_game_pool(game: str, data: dict, operator: Any):
tmp_lst = [] tmp_lst = []
if game == 'prts': if game == "prts":
for key in data.keys(): for key in data.keys():
limited = False limited = False
recruit_only = False recruit_only = False
event_only = False event_only = False
if '限定寻访' in data[key]['获取途径']: if "限定寻访" in data[key]["获取途径"]:
limited = True limited = True
if '干员寻访' not in data[key]['获取途径'] and '公开招募' in data[key]['获取途径']: if "干员寻访" not in data[key]["获取途径"] and "公开招募" in data[key]["获取途径"]:
recruit_only = True recruit_only = True
if '活动获取' in data[key]['获取途径']: if "活动获取" in data[key]["获取途径"]:
event_only = True event_only = True
if '干员寻访' not in data[key]['获取途径'] and '凭证交易所' == data[key]['获取途径'][0]: if "干员寻访" not in data[key]["获取途径"] and "凭证交易所" == data[key]["获取途径"][0]:
limited = True limited = True
if '干员寻访' not in data[key]['获取途径'] and '信用累计奖励' == data[key]['获取途径'][0]: if "干员寻访" not in data[key]["获取途径"] and "信用累计奖励" == data[key]["获取途径"][0]:
limited = True limited = True
if key.find('阿米娅') != -1: if key.find("阿米娅") != -1:
continue continue
try: try:
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']), tmp_lst.append(
limited=limited, recruit_only=recruit_only, event_only=event_only)) operator(
name=key,
star=int(data[key]["星级"]),
limited=limited,
recruit_only=recruit_only,
event_only=event_only,
)
)
except Exception as e: except Exception as e:
logger.warning(f"明日方舟导入角色 {key} 数据错误:{type(e)}:{e}") logger.warning(f"明日方舟导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin': if game == "genshin":
for key in data.keys(): for key in data.keys():
if key.find('旅行者') != -1: if key.find("旅行者") != -1:
continue continue
limited = False limited = False
if data[key]['常驻/限定'] == '限定UP': if data[key]["常驻/限定"] == "限定UP":
limited = True limited = True
try: 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: except Exception as e:
logger.warning(f"原神导入角色 {key} 数据错误:{type(e)}:{e}") logger.warning(f"原神导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin_arms': if game == "genshin_arms":
for key in data.keys(): for key in data.keys():
if data[key]['获取途径'].find('祈愿') != -1: if data[key]["获取途径"].find("祈愿") != -1:
limited = False limited = False
if data[key]['获取途径'].find('限定祈愿') != -1: if data[key]["获取途径"].find("限定祈愿") != -1:
limited = True limited = True
try: 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: except Exception as e:
logger.warning(f"原神导入武器 {key} 数据错误:{type(e)}:{e}") logger.warning(f"原神导入武器 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty': if game == "pretty":
for key in data.keys(): for key in data.keys():
try: 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: except Exception as e:
logger.warning(f"赛马娘导入角色 {key} 数据错误:{type(e)}:{e}") logger.warning(f"赛马娘导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty_card': if game == "pretty_card":
for key in data.keys(): for key in data.keys():
limited = False limited = False
if '卡池' not in data[key]['获取方式']: if "卡池" not in data[key]["获取方式"]:
limited = True limited = True
if not data[key]['获取方式']: if not data[key]["获取方式"]:
limited = False limited = False
try: 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: except Exception as e:
logger.warning(f"赛马娘导入卡片 {key} 数据错误:{type(e)}:{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(): for key in data.keys():
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False)) tmp_lst.append(
if game == 'pcr': operator(name=data[key]["名称"], star=int(data[key]["星级"]), limited=False)
)
if game == "pcr":
for key in data.keys(): for key in data.keys():
limited = False limited = False
if key.find('(') != -1: if key.find("(") != -1:
limited = True limited = True
try: 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: except Exception as e:
logger.warning(f"公主连接导入角色 {key} 数据错误:{type(e)}:{e}") logger.warning(f"公主连接导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'azur': if game == "azur":
for key in data.keys(): for key in data.keys():
if is_number(data[key]['星级']): if is_number(data[key]["星级"]):
limited = False limited = False
if '可以建造' not in data[key]['获取途径']: if "可以建造" not in data[key]["获取途径"]:
limited = True limited = True
try: try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), tmp_lst.append(
limited=limited, itype=data[key]['类型'])) operator(
name=data[key]["名称"],
star=int(data[key]["星级"]),
limited=limited,
type_=data[key]["类型"],
)
)
except Exception as e: except Exception as e:
logger.warning(f"碧蓝航线导入角色 {key} 数据错误:{type(e)}:{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(): for key in data.keys():
limited = False limited = False
try: 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 limited = True
except KeyError: except KeyError:
pass pass
try: 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: except Exception as e:
logger.warning(f"FGO导入角色 {key} 数据错误:{type(e)}:{e}") logger.warning(f"FGO导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'onmyoji': if game == "onmyoji":
for key in data.keys(): for key in data.keys():
limited = False limited = False
if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护', if key in [
'灶门祢豆子', '灶门炭治郎']: "奴良陆生",
"卖药郎",
"鬼灯",
"阿香",
"蜜桃&芥子",
"犬夜叉",
"杀生丸",
"桔梗",
"朽木露琪亚",
"黑崎一护",
"灶门祢豆子",
"灶门炭治郎",
]:
limited = True limited = True
try: 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: except Exception as e:
logger.warning(f"阴阳师导入角色 {key} 数据错误:{type(e)}:{e}") logger.warning(f"阴阳师导入角色 {key} 数据错误:{type(e)}:{e}")
# print(tmp_lst) # print(tmp_lst)
char_name_lst = [x.name for x in tmp_lst] char_name_lst = [x.name for x in tmp_lst]
up_char_file = Path(f'{DATA_PATH}/draw_card/draw_card_up/{game.split("_")[0]}_up_char.json') up_char_file = (
DRAW_DATA_PATH
/ f"draw_card"
/ "draw_card_up"
/ f"{game.split('_')[0]}_up_char.json"
)
if up_char_file.exists(): if up_char_file.exists():
data = json.load(open(up_char_file, 'r', encoding='utf8')) data = json.load(open(up_char_file, "r", encoding="utf8"))
if len(game.split('_')) == 1: if len(game.split("_")) == 1:
key = 'char' key = "char"
else: else:
key = list(data.keys())[1] key = list(data.keys())[1]
for x in data[key]['up_char']: for x in data[key]["up_char"]:
for char in data[key]['up_char'][x]: for char in data[key]["up_char"][x]:
if char not in char_name_lst: if char not in char_name_lst:
if game.find('prts') != -1: if game.find("prts") != -1:
tmp_lst.append(Operator(name=char, star=int(x), tmp_lst.append(
recruit_only=False, event_only=False, limited=False)) operator(
name=char,
star=int(x),
recruit_only=False,
event_only=False,
limited=False,
)
)
else: 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 return tmp_lst
+6 -7
View File
@@ -1,9 +1,8 @@
from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.adapters.cqhttp import MessageSegment
import random import random
from .update_game_requests_info import update_requests_info 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 .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_FLAG from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
try: try:
@@ -39,8 +38,8 @@ async def update_onmyoji_info():
async def init_onmyoji_data(): async def init_onmyoji_data():
global ALL_CHAR global ALL_CHAR
if ONMYOJI_FLAG: if draw_config.ONMYOJI_FLAG:
with open(DRAW_PATH + 'onmyoji.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'onmyoji.json').open('r', encoding='utf8') as f:
azur_dict = json.load(f) azur_dict = json.load(f)
ALL_CHAR = init_game_pool('onmyoji', azur_dict, OnmyojiChar) ALL_CHAR = init_game_pool('onmyoji', azur_dict, OnmyojiChar)
@@ -56,7 +55,8 @@ onmyoji_star = {
# 抽取卡池 # 抽取卡池
def _get_onmyoji_card(): def _get_onmyoji_card():
global ALL_CHAR global ALL_CHAR
star = get_star([5, 4, 3, 2], [ONMYOJI_SP, ONMYOJI_SSR, ONMYOJI_SR, ONMYOJI_R]) 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])
chars = [x for x in ALL_CHAR if x.star == onmyoji_star[star] and not x.limited] chars = [x for x in ALL_CHAR if x.star == onmyoji_star[star] and not x.limited]
return random.choice(chars), 5 - star return random.choice(chars), 5 - star
@@ -79,4 +79,3 @@ def format_card_information(count: int):
obj_dict[obj.name] = 1 obj_dict[obj.name] = 1
obj_list.append(obj) obj_list.append(obj)
return obj_list, obj_dict, star_list, rst return obj_list, obj_dict, star_list, rst
+12 -8
View File
@@ -1,13 +1,16 @@
import ujson as json from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.adapters.cqhttp import MessageSegment
import random import random
from .update_game_info import update_info from .update_game_info import update_info
from .update_game_simple_info import update_simple_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 .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
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 .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
try:
import ujson as json
except ModuleNotFoundError:
import json
ALL_CHAR = [] ALL_CHAR = []
@@ -30,7 +33,7 @@ async def pcr_draw(count: int):
async def update_pcr_info(): async def update_pcr_info():
global ALL_CHAR global ALL_CHAR
if PCR_TAI: if draw_config.PCR_TAI:
url = 'https://wiki.biligame.com/pcr/角色图鉴' url = 'https://wiki.biligame.com/pcr/角色图鉴'
data, code = await update_simple_info(url, 'pcr') data, code = await update_simple_info(url, 'pcr')
else: else:
@@ -42,8 +45,8 @@ async def update_pcr_info():
async def init_pcr_data(): async def init_pcr_data():
global ALL_CHAR global ALL_CHAR
if PCR_FLAG: if draw_config.PCR_FLAG:
with open(DRAW_PATH + 'pcr.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'pcr.json').open('r', encoding='utf8') as f:
pcr_dict = json.load(f) pcr_dict = json.load(f)
ALL_CHAR = init_game_pool('pcr', pcr_dict, PcrChar) ALL_CHAR = init_game_pool('pcr', pcr_dict, PcrChar)
@@ -51,10 +54,11 @@ async def init_pcr_data():
# 抽取卡池 # 抽取卡池
def _get_pcr_card(mode: int = 1): def _get_pcr_card(mode: int = 1):
global ALL_CHAR global ALL_CHAR
pcr_config = draw_config.pcr
if mode == 2: if mode == 2:
star = get_star([3, 2], [PCR_G_THREE_P, PCR_G_TWO_P]) star = get_star([3, 2], [pcr_config.PCR_G_THREE_P, pcr_config.PCR_G_TWO_P])
else: else:
star = get_star([3, 2, 1], [PCR_THREE_P, PCR_TWO_P, PCR_ONE_P]) star = get_star([3, 2, 1], [pcr_config.PCR_THREE_P, pcr_config.PCR_TWO_P, pcr_config.PCR_ONE_P])
chars = [x for x in ALL_CHAR if x.star == star and not x.limited] chars = [x for x in ALL_CHAR if x.star == star and not x.limited]
return random.choice(chars), 3 - star return random.choice(chars), 3 - star
+12 -13
View File
@@ -1,13 +1,12 @@
from nonebot.adapters.onebot.v11 import MessageSegment
from .update_game_info import update_info
from .announcement import PrettyAnnouncement from .announcement import PrettyAnnouncement
from .update_game_info import update_info
from .util import init_star_rst, generate_img, max_card, BaseData, \ from .util import init_star_rst, generate_img, max_card, BaseData, \
set_list, get_star, format_card_information, init_up_char set_list, get_star, format_card_information, init_up_char
import random import random
from .config import PRETTY_THREE_P, PRETTY_TWO_P, DRAW_PATH, PRETTY_ONE_P, PRETTY_FLAG from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
from nonebot.adapters.cqhttp import MessageSegment, Message
try: try:
import ujson as json import ujson as json
@@ -74,7 +73,8 @@ async def pretty_draw(count: int, pool_name):
rst = init_star_rst(star_list, cnlist, three_list, three_olist, up_list) rst = init_star_rst(star_list, cnlist, three_list, three_olist, up_list)
if count > 90: if count > 90:
obj_list = set_list(obj_list) 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) + '\n' + rst[:-1] + '\n' + max_card(obj_dict)
@@ -93,10 +93,10 @@ async def update_pretty_info():
async def init_pretty_data(): async def init_pretty_data():
global ALL_CHAR, ALL_CARD global ALL_CHAR, ALL_CARD
if PRETTY_FLAG: if draw_config.PRETTY_FLAG:
with open(DRAW_PATH + 'pretty.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'pretty.json').open('r', encoding='utf8') as f:
pretty_char_dict = json.load(f) pretty_char_dict = json.load(f)
with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'pretty_card.json').open('r', encoding='utf8') as f:
pretty_card_dict = json.load(f) pretty_card_dict = json.load(f)
ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar) ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar)
ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar) ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar)
@@ -106,10 +106,11 @@ async def init_pretty_data():
# 抽取卡池 # 抽取卡池
def _get_pretty_card(pool_name: str, mode: int = 1): def _get_pretty_card(pool_name: str, mode: int = 1):
global ALL_CHAR, ALL_CARD, _CURRENT_CHAR_POOL_TITLE, _CURRENT_CARD_POOL_TITLE global ALL_CHAR, ALL_CARD, _CURRENT_CHAR_POOL_TITLE, _CURRENT_CARD_POOL_TITLE
pretty_config = draw_config.pretty
if mode == 1: if mode == 1:
star = get_star([3, 2, 1], [PRETTY_THREE_P, PRETTY_TWO_P, PRETTY_ONE_P]) star = get_star([3, 2, 1], [pretty_config.PRETTY_THREE_P, pretty_config.PRETTY_TWO_P, pretty_config.PRETTY_ONE_P])
else: else:
star = get_star([3, 2], [PRETTY_THREE_P, PRETTY_TWO_P]) star = get_star([3, 2], [pretty_config.PRETTY_THREE_P, pretty_config.PRETTY_TWO_P])
if pool_name == 'card': if pool_name == 'card':
title = _CURRENT_CARD_POOL_TITLE title = _CURRENT_CARD_POOL_TITLE
up_data = UP_CARD up_data = UP_CARD
@@ -127,7 +128,6 @@ def _get_pretty_card(pool_name: str, mode: int = 1):
acquire_operator = random.choice(all_up_star) acquire_operator = random.choice(all_up_star)
if pool_name == 'char': if pool_name == 'char':
acquire_operator = acquire_operator.split(']')[1] acquire_operator = acquire_operator.split(']')[1]
print(acquire_operator)
acquire_operator = [x for x in data if x.name == acquire_operator][0] acquire_operator = [x for x in data if x.name == acquire_operator][0]
else: else:
acquire_operator = random.choice([x for x in data if x.star == star and not x.limited]) acquire_operator = random.choice([x for x in data if x.star == star and not x.limited])
@@ -144,6 +144,5 @@ async def _pretty_init_up_char():
async def reload_pretty_pool(): async def reload_pretty_pool():
await _pretty_init_up_char() await _pretty_init_up_char()
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_CARD_POOL_TITLE} {POOL_IMG}') return f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_CARD_POOL_TITLE} {POOL_IMG}'
+9 -13
View File
@@ -1,14 +1,12 @@
from nonebot.adapters.onebot.v11 import MessageSegment, Message
from nonebot.adapters.cqhttp import MessageSegment, Message
import random import random
from .config import PRTS_FIVE_P, PRTS_FOUR_P, PRTS_SIX_P, PRTS_THREE_P, DRAW_PATH, PRTS_FLAG from .config import DRAW_DATA_PATH, draw_config
from .update_game_info import update_info from .update_game_info import update_info
from .util import generate_img, init_star_rst, max_card, BaseData, UpEvent, set_list, get_star 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 .init_card_pool import init_game_pool
from pathlib import Path
from .announcement import PrtsAnnouncement from .announcement import PrtsAnnouncement
from services.log import logger
from dataclasses import dataclass from dataclasses import dataclass
from nonebot.log import logger
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -17,8 +15,6 @@ except ModuleNotFoundError:
announcement = PrtsAnnouncement() announcement = PrtsAnnouncement()
up_char_file = Path() / "data" / "draw_card" / "draw_card_up" / "prts_up_char.json"
prts_dict = {} prts_dict = {}
UP_OPERATOR = [] UP_OPERATOR = []
ALL_OPERATOR = [] ALL_OPERATOR = []
@@ -71,8 +67,8 @@ async def update_prts_info():
async def init_prts_data(): async def init_prts_data():
global prts_dict, ALL_OPERATOR global prts_dict, ALL_OPERATOR
if PRTS_FLAG: if draw_config.PRTS_FLAG:
with open(DRAW_PATH + 'prts.json', 'r', encoding='utf8') as f: with (DRAW_DATA_PATH / 'prts.json').open('r', encoding='utf8') as f:
prts_dict = json.load(f) prts_dict = json.load(f)
ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator) ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator)
await _init_up_char() await _init_up_char()
@@ -80,7 +76,8 @@ async def init_prts_data():
# 抽取干员 # 抽取干员
def _get_operator_card(add: float): def _get_operator_card(add: float):
star = get_star([6, 5, 4, 3], [PRTS_SIX_P + add, PRTS_FIVE_P, PRTS_FOUR_P, PRTS_THREE_P]) 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])
if _CURRENT_POOL_TITLE: if _CURRENT_POOL_TITLE:
zooms = [x.zoom for x in UP_OPERATOR if x.star == star] zooms = [x.zoom for x in UP_OPERATOR if x.star == star]
zoom = 0 zoom = 0
@@ -92,12 +89,11 @@ def _get_operator_card(add: float):
else: else:
weight = z weight = z
up_operator_name = "" up_operator_name = ""
# UP # UPs
try: try:
if random.random() < zoom: if 0 < zoom:
up_operators = [x.operators for x in UP_OPERATOR if x.star == star and x.zoom < 1][0] 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) 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] acquire_operator = [x for x in ALL_OPERATOR if x.name == up_operator_name][0]
else: else:
all_star_operators = [x for x in ALL_OPERATOR if x.star == star all_star_operators = [x for x in ALL_OPERATOR if x.star == star
+19 -27
View File
@@ -1,36 +1,28 @@
from nonebot.rule import Rule from nonebot.rule import Rule
from nonebot.adapters.cqhttp import Bot, MessageEvent from nonebot.adapters.onebot.v11 import Bot, MessageEvent
from nonebot.typing import T_State from nonebot.typing import T_State
from .config import ( from .config import draw_config
GENSHIN_FLAG,
PRTS_FLAG,
PRETTY_FLAG,
GUARDIAN_FLAG,
PCR_FLAG,
AZUR_FLAG,
FGO_FLAG,
ONMYOJI_FLAG,
)
def is_switch(game_name: str) -> Rule: def is_switch(game_name: str) -> Rule:
async def _is_switch(bot: Bot, event: MessageEvent, state: T_State) -> bool: async def _is_switch(bot: Bot, event: MessageEvent, state: T_State) -> bool:
if game_name == "prts": if game_name == 'prts':
return PRTS_FLAG return draw_config.PRTS_FLAG
if game_name == "genshin": if game_name == 'genshin':
return GENSHIN_FLAG return draw_config.GENSHIN_FLAG
if game_name == "pretty": if game_name == 'pretty':
return PRETTY_FLAG return draw_config.PRETTY_FLAG
if game_name == "guardian": if game_name == 'guardian':
return GUARDIAN_FLAG return draw_config.GUARDIAN_FLAG
if game_name == "pcr": if game_name == 'pcr':
return PCR_FLAG return draw_config.PCR_FLAG
if game_name == "azur": if game_name == 'azur':
return AZUR_FLAG return draw_config.AZUR_FLAG
if game_name == "fgo": if game_name == 'fgo':
return FGO_FLAG return draw_config.FGO_FLAG
if game_name == "onmyoji": if game_name == 'onmyoji':
return ONMYOJI_FLAG return draw_config.ONMYOJI_FLAG
else: else:
return False return False
+44 -33
View File
@@ -1,12 +1,12 @@
from .config import DRAW_PATH from typing import Tuple
from .config import DRAW_DATA_PATH
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from .util import download_img from .util import download_img
from urllib.parse import unquote from urllib.parse import unquote
from services.log import logger
from .util import remove_prohibited_str from .util import remove_prohibited_str
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
from httpx import ConnectTimeout, CloseError from nonebot.log import logger
import bs4 import bs4
import re import re
try: try:
@@ -18,15 +18,16 @@ except ModuleNotFoundError:
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'} 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) -> 'dict, int': 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"
try: try:
with open(DRAW_PATH + f'{game_name}.json', 'r', encoding='utf8') as f: with info_path.open('r', encoding='utf8') as f:
data = json.load(f) data = json.load(f)
except (ValueError, FileNotFoundError): except (ValueError, FileNotFoundError):
data = {} data = {}
try: try:
text = (await AsyncHttpx.get(url)).text response = await AsyncHttpx.get(url, timeout=7)
soup = BeautifulSoup(text, 'lxml') soup = BeautifulSoup(response.text, 'lxml')
_tbody = get_tbody(soup, game_name, url) _tbody = get_tbody(soup, game_name, url)
trs = _tbody.find_all('tr') trs = _tbody.find_all('tr')
att_dict, start_index, index = init_attr(game_name) att_dict, start_index, index = init_attr(game_name)
@@ -58,13 +59,10 @@ async def update_info(url: str, game_name: str, info_list: list = None) -> 'dict
data[name] = member_dict data[name] = member_dict
logger.info(f'{name} is update...') logger.info(f'{name} is update...')
data = await _last_check(data, game_name) data = await _last_check(data, game_name)
except (TimeoutError, ConnectTimeout, CloseError): except TimeoutError:
logger.warning(f'更新 {game_name} 超时...') logger.warning(f'更新 {game_name} 超时...')
return {}, 999 return {}, 999
except Exception as e: with info_path.open('w', encoding='utf8') as wf:
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)) wf.write(json.dumps(data, ensure_ascii=False, indent=4))
return data, 200 return data, 200
@@ -99,21 +97,25 @@ 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): async def _modify_avatar_url(game_name: str, char_name: str):
# if game_name == 'prts': if game_name == 'prts':
# async with session.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7) as res: res = await AsyncHttpx.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7)
# soup = BeautifulSoup(await res.text(), 'lxml') soup = BeautifulSoup(res.text, 'lxml')
# try: try:
# img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2] img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2]
# except KeyError: except KeyError:
# img_url = str(soup.find('img', {'class': 'img-bg'})['src']) img_url = str(soup.find('img', {'class': 'img-bg'})['src'])
# return img_url return img_url
if game_name == 'genshin': if game_name == 'genshin':
return None return None
if game_name == 'pretty_card': if game_name == 'pretty_card':
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/umamusume/{char_name}')).text res = await AsyncHttpx.get(f'https://wiki.biligame.com/umamusume/{char_name}', timeout=7)
soup = BeautifulSoup(text, 'lxml') soup = BeautifulSoup(res.text, 'lxml')
img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src') try:
return img_url 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
if game_name == 'guardian': if game_name == 'guardian':
# 未上传图片太多,换成像素图 # 未上传图片太多,换成像素图
# async with session.get(f'https://wiki.biligame.com/gt/{char_name}', timeout=7) as res: # async with session.get(f'https://wiki.biligame.com/gt/{char_name}', timeout=7) as res:
@@ -124,7 +126,7 @@ async def _modify_avatar_url(game_name: str, char_name: str):
# except KeyError: # except KeyError:
# img_url = str(soup.find('img', {'class': 'img-kk'})['src']) # img_url = str(soup.find('img', {'class': 'img-kk'})['src'])
# except TypeError: # except TypeError:
# logger.info(f'{char_name} 图片还未上传,跳过...') # print(f'{char_name} 图片还未上传,跳过...')
# img_url = '' # img_url = ''
# return img_url # return img_url
return None return None
@@ -133,18 +135,17 @@ async def _modify_avatar_url(game_name: str, char_name: str):
# 数据最后处理(是否需要额外数据或处理数据) # 数据最后处理(是否需要额外数据或处理数据)
async def _last_check(data: dict, game_name: str): async def _last_check(data: dict, game_name: str):
# if game_name == 'prts': # if game_name == 'prts':
# url = 'https://wiki.biligame.com/arknights/'
# tasks = [] # tasks = []
# for key in data.keys(): # for key in data.keys():
# tasks.append(asyncio.ensure_future(_async_update_prts_extra_info(url, key, session))) # tasks.append(asyncio.ensure_future(_async_update_prts_extra_info(key, session)))
# asyResult = await asyncio.gather(*tasks) # asyResult = await asyncio.gather(*tasks)
# for x in asyResult: # for x in asyResult:
# for key in x.keys(): # for key in x.keys():
# data[key]['获取途径'] = x[key]['获取途径'] # data[key]['获取途径'] = x[key]['获取途径']
if game_name == 'genshin': if game_name == 'genshin':
for key in data.keys(): for key in data.keys():
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/ys/{key}')).text res = await AsyncHttpx.get(f'https://wiki.biligame.com/ys/{key}', timeout=7)
soup = BeautifulSoup(text, 'lxml') soup = BeautifulSoup(res.text, 'lxml')
_trs = '' _trs = ''
for table in soup.find_all('table', {'class': 'wikitable'}): for table in soup.find_all('table', {'class': 'wikitable'}):
if str(table).find('常驻/限定') != -1: if str(table).find('常驻/限定') != -1:
@@ -179,10 +180,13 @@ async def _last_check(data: dict, game_name: str):
# 对抓取每行数据是否需要额外处理? # 对抓取每行数据是否需要额外处理?
def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.element.Tag): 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 game_name == 'prts':
if key == '获取途径': if key == '获取途径':
msg = re.search('<td.*?>([\\s\\S]*)</td>', str(td)).group(1).strip() msg = re.search('<td.*?>([\\s\\S]*)</td>', str(td)).group(1).strip()
msg = msg[:-1] if msg[-1] == '\n' else msg msg = msg[:-1] if msg and msg[-1] == '\n' else msg
if msg.find('<a') != -1: if msg.find('<a') != -1:
for a in td.find_all('a'): for a in td.find_all('a'):
msg = msg.replace(str(a), a.text) msg = msg.replace(str(a), a.text)
@@ -190,6 +194,13 @@ def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.elem
if game_name == 'pretty': if game_name == 'pretty':
if key == '初始星级': if key == '初始星级':
member_dict['初始星级'] = len(td.find_all('img')) 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 game_name == 'guardian':
if key == '头像': if key == '头像':
member_dict['星级'] = str(td.find('span').find('img')['alt'])[-5] member_dict['星级'] = str(td.find('span').find('img')['alt'])[-5]
@@ -254,7 +265,7 @@ def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
return _tbody return _tbody
# async def _async_update_prts_extra_info(url: str, key: str, session: aiohttp.ClientSession): # async def _async_update_prts_extra_info(key: str, session: aiohttp.ClientSession):
# for i in range(10): # for i in range(10):
# try: # try:
# async with session.get(f'https://wiki.biligame.com/arknights/{key}', timeout=7) as res: # async with session.get(f'https://wiki.biligame.com/arknights/{key}', timeout=7) as res:
@@ -274,11 +285,11 @@ def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
# if r: # if r:
# text += r.group(1) + ' ' # text += r.group(1) + ' '
# obtain[i] = obtain[i].split('<a')[0] + text[:-1] + obtain[i].split('</a>')[-1] # obtain[i] = obtain[i].split('<a')[0] + text[:-1] + obtain[i].split('</a>')[-1]
# logger.info(f'明日方舟获取额外信息 {key}...{obtain}') # print(f'明日方舟获取额外信息 {key}...{obtain}')
# x = {key: {}} # x = {key: {}}
# x[key]['获取途径'] = obtain # x[key]['获取途径'] = obtain
# return x # return x
# except TimeoutError: # except TimeoutError:
# logger.warning(f'访问{url}{key} 第 {i}次 超时...已再次访问') # print(f'访问 https://wiki.biligame.com/arknights/{key} 第 {i}次 超时...已再次访问')
# return {} # return {}

Some files were not shown because too many files have changed in this diff Show More