Compare commits

..
22 Commits
Author SHA1 Message Date
HibiKier aed770a761 Update README.md 2021-11-23 21:48:11 +08:00
HibiKi 3de487fb24 update 0.0.6.2 2021-11-23 21:44:59 +08:00
HibiKier c802dfda22 Update README.md 2021-11-19 15:47:10 +08:00
HibiKier 3a4378e4c6 Update __init__.py 2021-11-18 14:41:54 +08:00
HibiKier 955a1f8a7f Update __init__.py 2021-11-18 14:41:13 +08:00
HibiKier ab69e5c477 Create README.md 2021-11-17 11:34:40 +08:00
HibiKier 55e42e8334 Update README.md 2021-11-17 11:33:26 +08:00
HibiKier a0f59bc2c2 Update README.md 2021-11-14 17:27:26 +08:00
HibiKier 66dabd0c8a Update plugins_manager.py 2021-11-14 17:25:45 +08:00
HibiKier 915d585e3a Merge pull request #77 from AkashiCoin/main
修复有免费游戏时不能获取免费游戏的问题
2021-11-13 16:12:49 +08:00
HibiKier 979080d281 Merge branch 'main' into main 2021-11-13 16:12:41 +08:00
HibiKier 335f76c532 Update data_source.py 2021-11-12 16:13:16 +08:00
AkashiCoin b50b934a12 Update data_source.py 2021-11-10 22:26:57 +08:00
AkashiCoin 6a1684d277 Update __init__.py 2021-11-10 22:26:29 +08:00
HibiKier 4926e4d69c Update pix_update.py 2021-11-10 21:33:10 +08:00
HibiKier b29a26551a Update README.md 2021-11-10 21:32:54 +08:00
HibiKier d1c1d93ab7 fix 2021-11-10 21:27:49 +08:00
HibiKier 907df4253c Update __version__ 2021-11-10 20:06:44 +08:00
HibiKier 658152fdc9 Update jitang.py 2021-11-10 16:45:19 +08:00
HibiKier 1a68ede632 Update README.md 2021-11-09 18:05:36 +08:00
HibiKier b70851b810 Update __init__.py 2021-11-09 18:04:33 +08:00
HibiKier 17506691a8 Update __init__.py 2021-11-07 20:45:34 +08:00
252 changed files with 14373 additions and 13952 deletions
+46 -8
View File
@@ -25,6 +25,10 @@
## 真寻的帮助 ## 真寻的帮助
请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令' 请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令'
## 提供符合真寻标准的插件仓库
[AkashiCoin/nonebot_plugins_zhenxun_bot](https://github.com/AkashiCoin/nonebot_plugins_zhenxun_bot)
## 功能列表 ## 功能列表
<details> <details>
@@ -96,6 +100,7 @@
- [x] 移动图片 (同上) - [x] 移动图片 (同上)
- [x] 删除图片 (同上) - [x] 删除图片 (同上)
- [x] 群内B站订阅 - [x] 群内B站订阅
- [x] 群词条
### 已实现的超级用户功能 ### 已实现的超级用户功能
- [x] 添加/删除权限(是真寻的管理员权限,不是群管理员) - [x] 添加/删除权限(是真寻的管理员权限,不是群管理员)
@@ -268,8 +273,10 @@
</details> </details>
## 详细配置请前往文档,以下为最简部署和配置,如果你有基础并学习过nonebot2的话
## 部署
## 简单部署
``` ```
@@ -294,8 +301,7 @@ pip install -r requirements.txt
python bot.py python bot.py
``` ```
## 配置 ## 简单配置
在 configs/config.py 中的 USE_CONFIG_FILE,默认为False
``` ```
1.在.env.dev文件中 1.在.env.dev文件中
@@ -303,12 +309,10 @@ python bot.py
SUPERUSERS = [""] # 填写你的QQ SUPERUSERS = [""] # 填写你的QQ
2.在configs/config.py文件中 2.在configs/config.py文件中
必填: * 数据库配置
1. API KEY
2.数据库配置
在./configs/config.py中配置基本配置(除API KEY ,数据库和代理外都含有默认值) 3.在configs/config.yaml文件中 # 该文件需要启动一次后生成
在./configs/path_config.py配置路径(含有默认配置) * 修改插件配置项
``` ```
@@ -317,6 +321,40 @@ python bot.py
## 更新 ## 更新
### 2021/11/23 \[v0.0.6.2]
* 替换cos API
* 提供私聊b了,即跨群b了用户
* 修复游戏抽卡导入角色失败(原神)
* 修复无Pixiv代理时报错
* 将项目中大部分aiohttp替换为httpx
* 删除了丘丘人翻译插件
* 新增群词条
* 修复游戏抽卡碧蓝航线bwiki格式更改导致获取报错
* 首次启动会生成配置文件后停止程序,配置后再次启动即可
### 2021/11/18
* 修复超级用户无法正确拉真寻入群
### 2021/11/14
* 修复功能总开关无法正确开启
### 2021/11/12
* 修复PIX无法url无法正确获取
### 2021/11/10
* 修复PIX表重复创建导致首次无法运行
* 检测Omage图库改为命令方式:检测omega图库
### 2021/11/9
* 修复管理员帮助无法正常响应
* 修复被ban时会一直回复被ban提醒
### 2021/11/5 ### 2021/11/5
* 修复ai没有图灵key时报错 * 修复ai没有图灵key时报错
+1 -1
View File
@@ -1 +1 @@
__version__: v0.0.5.1 __version__: v0.0.6.2
Regular → Executable
View File
+1 -1
View File
@@ -4,7 +4,7 @@ import nonebot
Config.add_plugin_config( Config.add_plugin_config(
"admin_bot_manage:custom_welcome_message", "admin_bot_manage:custom_welcome_message",
"SET_GROUP_WELCOME_MESSAGE_LEVEL", "SET_GROUP_WELCOME_MESSAGE_LEVEL [LEVEL]",
2, 2,
name="群管理员操作", name="群管理员操作",
help_="设置群欢迎消息权限", help_="设置群欢迎消息权限",
+38 -38
View File
@@ -1,38 +1,38 @@
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.cqhttp import Bot, GroupAdminNoticeEvent
from nonebot.typing import T_State 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
__zx_plugin_name__ = "群管理员变动监测 [Hidden]" __zx_plugin_name__ = "群管理员变动监测 [Hidden]"
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
admin_notice = on_notice(priority=5) admin_notice = on_notice(priority=5)
@admin_notice.handle() @admin_notice.handle()
async def _(bot: Bot, event: GroupAdminNoticeEvent, state: T_State): async def _(bot: Bot, event: GroupAdminNoticeEvent, state: T_State):
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)
).user_name ).user_name
except AttributeError: except AttributeError:
nickname = event.user_id nickname = event.user_id
if event.sub_type == "set": if event.sub_type == "set":
await LevelUser.set_level( await LevelUser.set_level(
event.user_id, event.user_id,
event.group_id, event.group_id,
Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"), Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"),
) )
logger.info( logger.info(
f"为新晋管理员 {nickname}({event.user_id}) " f"为新晋管理员 {nickname}({event.user_id}) "
f"添加权限等级:{Config.get_config('admin_bot_manage', 'ADMIN_DEFAULT_AUTH')}" f"添加权限等级:{Config.get_config('admin_bot_manage', 'ADMIN_DEFAULT_AUTH')}"
) )
elif event.sub_type == "unset": elif event.sub_type == "unset":
await LevelUser.delete_level(event.user_id, event.group_id) await LevelUser.delete_level(event.user_id, event.group_id)
logger.info(f"将非管理员 {nickname}({event.user_id}) 取消权限等级") logger.info(f"将非管理员 {nickname}({event.user_id}) 取消权限等级")
+51 -51
View File
@@ -1,51 +1,51 @@
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_text, get_message_imgs
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from .data_source import custom_group_welcome from .data_source import custom_group_welcome
from nonebot.adapters.cqhttp.permission import GROUP from nonebot.adapters.cqhttp.permission import GROUP
from configs.config import Config from configs.config import Config
from services.log import logger from services.log import logger
__zx_plugin_name__ = "自定义进群欢迎消息 [Admin]" __zx_plugin_name__ = "自定义进群欢迎消息 [Admin]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
指令: 指令:
自定义进群欢迎消息 ?[文本] ?[图片] 自定义进群欢迎消息 ?[文本] ?[图片]
示例:自定义进群欢迎消息 欢迎新人![图片] 示例:自定义进群欢迎消息 欢迎新人![图片]
Note:可以通过[at]来确认是否艾特新成员 Note:可以通过[at]来确认是否艾特新成员
示例:自定义进群欢迎消息 欢迎你[at] 示例:自定义进群欢迎消息 欢迎你[at]
""".strip() """.strip()
__plugin_des__ = '简易的自定义群欢迎消息' __plugin_des__ = '简易的自定义群欢迎消息'
__plugin_cmd__ = ['自定义群欢迎消息 ?[文本] ?[图片]'] __plugin_cmd__ = ['自定义群欢迎消息 ?[文本] ?[图片]']
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = 'HibiKier'
__plugin_settings__ = { __plugin_settings__ = {
"admin_level": Config.get_config("admin_bot_manage", "SET_GROUP_WELCOME_MESSAGE_LEVEL"), "admin_level": Config.get_config("admin_bot_manage", "SET_GROUP_WELCOME_MESSAGE_LEVEL"),
} }
custom_welcome = on_command( custom_welcome = on_command(
"自定义进群欢迎消息", "自定义进群欢迎消息",
aliases={"自定义欢迎消息", "自定义群欢迎消息", "设置群欢迎消息"}, aliases={"自定义欢迎消息", "自定义群欢迎消息", "设置群欢迎消息"},
permission=GROUP, permission=GROUP,
priority=5, priority=5,
block=True, block=True,
) )
@custom_welcome.handle() @custom_welcome.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
try: try:
msg = get_message_text(event.json()) msg = get_message_text(event.json())
imgs = get_message_imgs(event.json()) imgs = get_message_imgs(event.json())
if not msg and not imgs: if not msg and not imgs:
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, imgs, 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}")
except Exception as e: except Exception as e:
logger.error(f"自定义进群欢迎消息发生错误 {type(e)}:{e}") logger.error(f"自定义进群欢迎消息发生错误 {type(e)}:{e}")
await custom_welcome.send("发生了一些未知错误...") await custom_welcome.send("发生了一些未知错误...")
+290 -296
View File
@@ -1,296 +1,290 @@
from typing import List from typing import List
from nonebot.adapters.cqhttp.message import MessageSegment from nonebot.adapters.cqhttp.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_local_proxy, get_bot
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 CreateImg from utils.image_utils import CreateImg
import aiofiles from utils.http_utils import AsyncHttpx
import aiohttp 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 os.path.exists(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg"): os.remove(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
os.remove(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg") if not custom_welcome_msg_json.exists():
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(img, DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
async with aiohttp.ClientSession() as session: img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
async with session.get(img, proxy=get_local_proxy()) as response: logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
async with aiofiles.open( except Exception as e:
DATA_PATH + f"custom_welcome_msg/{group_id}.jpg", "wb" logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}")
) as f: return "替换群消息失败.."
await f.write(await response.read()) return f"替换群欢迎消息成功:\n{result}" + img_result
img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
except Exception as e: task_data = None
logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}")
return "替换群消息失败.."
return f"替换群欢迎消息成功:\n{result}" + img_result async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
global task_data
"""
task_data = None 修改群功能状态
:param cmd: 功能名称
:param group_id: 群号
async def change_group_switch(cmd: str, group_id: int, is_super: bool = False): :param is_super: 是否位超级用户,超级用户用于私聊开关功能状态
global task_data """
""" if not task_data:
修改群功能状态 task_data = group_manager.get_task_data()
:param cmd: 功能名称 group_help_file = Path(DATA_PATH) / "group_help" / f"{group_id}.png"
:param group_id: 群号 status = cmd[:2]
:param is_super: 是否位超级用户,超级用户用于私聊开关功能状态 cmd = cmd[2:]
""" type_ = "plugin"
if not task_data: modules = plugins2settings_manager.get_plugin_module(cmd, True)
task_data = group_manager.get_task_data() if cmd == "全部被动":
group_help_file = Path(DATA_PATH) / "group_help" / f"{group_id}.png" for task in task_data:
status = cmd[:2] if status == "开启":
cmd = cmd[2:] if not await group_manager.check_group_task_status(group_id, task):
type_ = "plugin" await group_manager.open_group_task(group_id, task)
modules = plugins2settings_manager.get_plugin_module(cmd, True) else:
if cmd == "全部被动": if await group_manager.check_group_task_status(group_id, task):
for task in task_data: await group_manager.close_group_task(group_id, task)
if status == "开启": return f"已 {status} 全部被动技能!"
if not await group_manager.check_group_task_status(group_id, task): if cmd in [task_data[x] for x in task_data.keys()]:
await group_manager.open_group_task(group_id, task) type_ = "task"
else: modules = [x for x in task_data.keys() if task_data[x] == cmd]
if await group_manager.check_group_task_status(group_id, task): for module in modules:
await group_manager.close_group_task(group_id, task) if is_super:
return f"已 {status} 全部被动技能!" module = f"{module}:super"
if cmd in [task_data[x] for x in task_data.keys()]: if status == "开启":
type_ = "task" if type_ == "task":
modules = [x for x in task_data.keys() if task_data[x] == cmd] if await group_manager.check_group_task_status(group_id, module):
for module in modules: return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
if is_super: await group_manager.open_group_task(group_id, module)
module = f"{module}:super" else:
if status == "开启": if group_manager.get_plugin_status(module, group_id):
if type_ == "task": return f"功能 {cmd} 正处于开启状态!不要重复开启."
if await group_manager.check_group_task_status(group_id, module): group_manager.unblock_plugin(module, group_id)
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启." else:
await group_manager.open_group_task(group_id, module) if type_ == "task":
else: if not await group_manager.check_group_task_status(group_id, module):
if group_manager.get_plugin_status(module, group_id): return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
return f"功能 {cmd} 正处于开启状态!不要重复开启." await group_manager.close_group_task(group_id, module)
group_manager.unblock_plugin(module, group_id) else:
else: if not group_manager.get_plugin_status(module, group_id):
if type_ == "task": return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
if not await group_manager.check_group_task_status(group_id, module): group_manager.block_plugin(module, group_id)
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭." if group_help_file.exists():
await group_manager.close_group_task(group_id, module) group_help_file.unlink()
else: if is_super:
if not group_manager.get_plugin_status(module, group_id): for file in os.listdir(Path(DATA_PATH) / 'group_help'):
return f"功能 {cmd} 正处于关闭状态!不要重复关闭." file = Path(DATA_PATH) / 'group_help' / file
group_manager.block_plugin(module, group_id) file.unlink()
if group_help_file.exists(): else:
group_help_file.unlink() _help_image = Path(DATA_PATH) / 'group_help' / f"{group_id}.png"
if is_super: if _help_image.exists():
for file in os.listdir(Path(DATA_PATH) / 'group_help'): _help_image.unlink()
file = Path(DATA_PATH) / 'group_help' / file return f"{status} {cmd} 功能!"
file.unlink()
else:
_help_image = Path(DATA_PATH) / 'group_help' / f"{group_id}.png" def set_plugin_status(cmd: str, block_type: str = "all"):
if _help_image.exists(): """
_help_image.unlink() 设置插件功能状态(超级用户使用)
return f"{status} {cmd} 功能!" :param cmd: 功能名称
:param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊
"""
def set_plugin_status(cmd: str, block_type: str = "all"): status = cmd[:2]
""" cmd = cmd[2:]
设置插件功能状态(超级用户使用) module = plugins2settings_manager.get_plugin_module(cmd)
:param cmd: 功能名称 if status == "开启":
:param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊 plugins_manager.unblock_plugin(module)
""" else:
status = cmd[:2] plugins_manager.block_plugin(module, block_type=block_type)
cmd = cmd[2:] for file in os.listdir(Path(DATA_PATH) / 'group_help'):
module = plugins2settings_manager.get_plugin_module(cmd) file = Path(DATA_PATH) / 'group_help' / file
if status == "开启": file.unlink()
plugins_manager.unblock_plugin(module)
else:
plugins_manager.block_plugin(module, block_type=block_type) async def get_plugin_status():
for file in os.listdir(Path(DATA_PATH) / 'group_help'): """
file = Path(DATA_PATH) / 'group_help' / file 获取功能状态
file.unlink() """
return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status)
async def get_plugin_status():
""" def _get_plugin_status() -> MessageSegment:
获取功能状态 """
""" 合成功能状态图片
return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status) """
rst = "\t功能\n"
flag_str = "状态".rjust(4) + "\n"
def _get_plugin_status() -> MessageSegment: for module in plugins_manager.get_data():
""" flag = plugins_manager.get_plugin_block_type(module)
合成功能状态图片 flag = flag.upper() + " CLOSE" if flag else "OPEN"
""" try:
rst = "\t功能\n" plugin_name = plugins_manager.get(module)["plugin_name"]
flag_str = "状态".rjust(4) + "\n" if (
for module in plugins_manager.get_data(): "[Hidden]" in plugin_name
flag = plugins_manager.get_plugin_block_type(module) or "[Admin]" in plugin_name
flag = flag.upper() + " CLOSE" if flag else "OPEN" or "[Superuser]" in plugin_name
try: ):
plugin_name = plugins_manager.get(module)["plugin_name"] continue
if ( rst += f"{plugin_name}"
"[Hidden]" in plugin_name except KeyError:
or "[Admin]" in plugin_name rst += f"{module}"
or "[Superuser]" in plugin_name if plugins_manager.get(module)["error"]:
): rst += "[ERROR]"
continue rst += "\n"
rst += f"{plugin_name}" flag_str += f"{flag}\n"
except KeyError: height = len(rst.split("\n")) * 24
rst += f"{module}" a = CreateImg(250, height, font_size=20)
if plugins_manager.get(module)["error"]: a.text((10, 10), rst)
rst += "[ERROR]" b = CreateImg(200, height, font_size=20)
rst += "\n" b.text((10, 10), flag_str)
flag_str += f"{flag}\n" A = CreateImg(500, height)
height = len(rst.split("\n")) * 24 A.paste(a)
a = CreateImg(250, height, font_size=20) A.paste(b, (270, 0))
a.text((10, 10), rst) return image(b64=A.pic2bs4())
b = CreateImg(200, height, font_size=20)
b.text((10, 10), flag_str)
A = CreateImg(500, height) async def update_member_info(group_id: int, remind_superuser: bool = False) -> bool:
A.paste(a) """
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)
更新群成员信息 _error_member_list = []
:param group_id: 群号 _exist_member_list = []
:param remind_superuser: 失败信息提醒超级用户 # try:
""" for user_info in _group_user_list:
bot = get_bot() if user_info["card"] == "":
_group_user_list = await bot.get_group_member_list(group_id=group_id) nickname = user_info["nickname"]
_error_member_list = [] else:
_exist_member_list = [] nickname = user_info["card"]
# try: async with db.transaction():
for user_info in _group_user_list: # 更新权限
if user_info["card"] == "": if (
nickname = user_info["nickname"] user_info["role"]
else: in [
nickname = user_info["card"] "owner",
async with db.transaction(): "admin",
# 更新权限 ]
if ( and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
user_info["role"] ):
in [ await LevelUser.set_level(
"owner", user_info["user_id"],
"admin", user_info["group_id"],
] Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"),
and not await LevelUser.is_group_flag(user_info["user_id"], group_id) )
): if str(user_info["user_id"]) in bot.config.superusers:
await LevelUser.set_level( await LevelUser.set_level(
user_info["user_id"], user_info["user_id"], user_info["group_id"], 9
user_info["group_id"], )
Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH"), user = await GroupInfoUser.get_member_info(
) user_info["user_id"], user_info["group_id"]
if str(user_info["user_id"]) in bot.config.superusers: )
await LevelUser.set_level( if user:
user_info["user_id"], user_info["group_id"], 9 if user.user_name != nickname:
) await user.update(user_name=nickname).apply()
user = await GroupInfoUser.get_member_info( logger.info(
user_info["user_id"], user_info["group_id"] f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功"
) )
if user: _exist_member_list.append(int(user_info["user_id"]))
if user.user_name != nickname: continue
await user.update(user_name=nickname).apply() join_time = datetime.strptime(
logger.info( time.strftime(
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功" "%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])
) ),
_exist_member_list.append(int(user_info["user_id"])) "%Y-%m-%d %H:%M:%S",
continue )
join_time = datetime.strptime( if await GroupInfoUser.add_member_info(
time.strftime( user_info["user_id"],
"%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"]) user_info["group_id"],
), nickname,
"%Y-%m-%d %H:%M:%S", join_time,
) ):
if await GroupInfoUser.add_member_info( _exist_member_list.append(int(user_info["user_id"]))
user_info["user_id"], logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
user_info["group_id"], else:
nickname, _error_member_list.append(
join_time, f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n"
): )
_exist_member_list.append(int(user_info["user_id"])) _del_member_list = list(
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功") set(_exist_member_list).difference(
else: set(await GroupInfoUser.get_group_member_id_list(group_id))
_error_member_list.append( )
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n" )
) if _del_member_list:
_del_member_list = list( for del_user in _del_member_list:
set(_exist_member_list).difference( if await GroupInfoUser.delete_member_info(del_user, group_id):
set(await GroupInfoUser.get_group_member_id_list(group_id)) logger.info(f"退群用户{del_user} 所属{group_id} 已删除")
) else:
) logger.info(f"退群用户{del_user} 所属{group_id} 删除失败")
if _del_member_list: if _error_member_list and remind_superuser:
for del_user in _del_member_list: result = ""
if await GroupInfoUser.delete_member_info(del_user, group_id): for error_user in _error_member_list:
logger.info(f"退群用户{del_user} 所属{group_id} 已删除") result += error_user
else: await bot.send_private_msg(
logger.info(f"退群用户{del_user} 所属{group_id} 删除失败") user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
if _error_member_list and remind_superuser: )
result = "" return True
for error_user in _error_member_list:
result += error_user
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
)
return True
View File
+107 -107
View File
@@ -1,107 +1,107 @@
from nonebot import on_command, on_message from nonebot import on_command, on_message
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent, GROUP 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,
group_current_status, group_current_status,
) )
from services.log import logger 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 .rule import switch_rule from .rule import switch_rule
__zx_plugin_name__ = "群功能开关 [Admin]" __zx_plugin_name__ = "群功能开关 [Admin]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
群内功能与被动技能开关 群内功能与被动技能开关
指令: 指令:
开启/关闭[功能] 开启/关闭[功能]
群被动状态 群被动状态
开启全部被动 开启全部被动
关闭全部被动 关闭全部被动
示例:开启/关闭色图 示例:开启/关闭色图
""".strip() """.strip()
__plugin_superuser_usage__ = """ __plugin_superuser_usage__ = """
usage: usage:
功能总开关与指定群禁用 功能总开关与指定群禁用
指令: 指令:
功能状态 功能状态
开启/关闭[功能] [group] 开启/关闭[功能] [group]
开启/关闭[功能] ['private'/'group'] 开启/关闭[功能] ['private'/'group']
""".strip() """.strip()
__plugin_des__ = "群内功能开关" __plugin_des__ = "群内功能开关"
__plugin_cmd__ = [ __plugin_cmd__ = [
"开启/关闭[功能]", "开启/关闭[功能]",
"群被动状态", "群被动状态",
"开启全部被动", "开启全部被动",
"关闭全部被动", "关闭全部被动",
"功能状态 [_superuser]", "功能状态 [_superuser]",
"开启/关闭[功能] [group] [_superuser]", "开启/关闭[功能] [group] [_superuser]",
"开启/关闭[功能] ['private'/'group'] [_superuser]", "开启/关闭[功能] ['private'/'group'] [_superuser]",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"admin_level": Config.get_config("admin_bot_manage", "CHANGE_GROUP_SWITCH_LEVEL"), "admin_level": Config.get_config("admin_bot_manage", "CHANGE_GROUP_SWITCH_LEVEL"),
"cmd": ["开启功能", "关闭功能", "开关"] "cmd": ["开启功能", "关闭功能", "开关"]
} }
switch_rule_matcher = on_message(rule=switch_rule, priority=4, block=True) switch_rule_matcher = on_message(rule=switch_rule, priority=4, block=True)
plugins_status = on_command("功能状态", permission=SUPERUSER, priority=5, block=True) plugins_status = on_command("功能状态", permission=SUPERUSER, priority=5, block=True)
group_task_status = on_command("群被动状态", permission=GROUP, priority=5, block=True) group_task_status = on_command("群被动状态", permission=GROUP, priority=5, block=True)
@switch_rule_matcher.handle() @switch_rule_matcher.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
_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))
logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {_cmd}") logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {_cmd}")
else: else:
if str(event.user_id) in bot.config.superusers: if str(event.user_id) in bot.config.superusers:
block_type = " ".join(get_message_text(event.json()).split()[1:]) block_type = " ".join(get_message_text(event.json()).split()[1:])
block_type = block_type if block_type else "a" block_type = block_type if block_type else "a"
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(self_id=int(bot.self_id))
]: ]:
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)
group_name = (await bot.get_group_info(group_id=int(block_type)))[ group_name = (await bot.get_group_info(group_id=int(block_type)))[
"group_name" "group_name"
] ]
await switch_rule_matcher.send( await switch_rule_matcher.send(
f"已禁用群聊 {group_name}({block_type}) 的 {_cmd[2:]} 功能" f"已禁用群聊 {group_name}({block_type}) 的 {_cmd[2:]} 功能"
) )
elif block_type in ["all", "private", "group", "a", "p", "g"]: elif block_type in ["all", "private", "group", "a", "p", "g"]:
block_type = "all" if block_type == "a" else block_type block_type = "all" if block_type == "a" else block_type
block_type = "private" if block_type == "p" else block_type block_type = "private" if block_type == "p" else block_type
block_type = "group" if block_type == "g" else block_type block_type = "group" if block_type == "g" else block_type
set_plugin_status(_cmd, block_type) set_plugin_status(_cmd, block_type)
if block_type == "all": if block_type == "all":
await switch_rule_matcher.send(f"已{_cmd[:2]}功能:{_cmd[2:]}") await switch_rule_matcher.send(f"已{_cmd[:2]}功能:{_cmd[2:]}")
elif block_type == "private": elif block_type == "private":
await switch_rule_matcher.send(f"已在私聊中{_cmd[:2]}功能:{_cmd[2:]}") await switch_rule_matcher.send(f"已在私聊中{_cmd[:2]}功能:{_cmd[2:]}")
else: else:
await switch_rule_matcher.send(f"已在群聊中{_cmd[:2]}功能:{_cmd[2:]}") await switch_rule_matcher.send(f"已在群聊中{_cmd[:2]}功能:{_cmd[2:]}")
else: else:
await switch_rule_matcher.finish("格式错误:关闭[功能] [group]/[p/g]") await switch_rule_matcher.finish("格式错误:关闭[功能] [group]/[p/g]")
logger.info(f"USER {event.user_id} 使用功能管理命令 {_cmd} | {block_type}") logger.info(f"USER {event.user_id} 使用功能管理命令 {_cmd} | {block_type}")
@plugins_status.handle() @plugins_status.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
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 _(bot: Bot, event: GroupMessageEvent, state: T_State):
await group_task_status.send(await group_current_status(event.group_id)) await group_task_status.send(await group_current_status(event.group_id))
+51 -51
View File
@@ -1,51 +1,51 @@
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
__zx_plugin_name__ = '管理方面定时任务 [Hidden]' __zx_plugin_name__ = '管理方面定时任务 [Hidden]'
__plugin_usage__ = '无' __plugin_usage__ = '无'
__plugin_des__ = '成员信息和管理权限的定时更新' __plugin_des__ = '成员信息和管理权限的定时更新'
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = 'HibiKier'
# 自动更新群员信息 # 自动更新群员信息
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=2, hour=2,
minute=1, minute=1,
) )
async def _(): async def _():
bot = get_bot() bot = get_bot()
if bot: if 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]
for g in gl: for g in gl:
try: try:
await update_member_info(g) await update_member_info(g)
logger.info(f"更新群组 g:{g} 成功") logger.info(f"更新群组 g:{g} 成功")
except Exception as e: except Exception as e:
logger.error(f"更新群组错误 g:{g} e:{e}") logger.error(f"更新群组错误 g:{g} e:{e}")
# 快速更新群员信息以及管理员权限 # 快速更新群员信息以及管理员权限
@scheduler.scheduled_job( @scheduler.scheduled_job(
"interval", "interval",
minutes=5, minutes=5,
) )
async def _(): async def _():
try: try:
bot = get_bot() bot = get_bot()
if bot: if 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]
all_group = [x.group_id for x in await GroupInfo.get_all_group()] all_group = [x.group_id for x in await GroupInfo.get_all_group()]
for g in gl: for g in gl:
if g not in all_group: if g not in all_group:
await update_member_info(g, False) await update_member_info(g, False)
logger.info(f"快速更新群信息以及权限:{g}") logger.info(f"快速更新群信息以及权限:{g}")
except (IndexError, ConnectionDoesNotExistError, UndefinedColumnError): except (IndexError, ConnectionDoesNotExistError, UndefinedColumnError):
pass pass
+41 -41
View File
@@ -1,41 +1,41 @@
from nonebot import on_command, on_notice from nonebot import on_command, on_notice
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp 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__ = """
usage: usage:
更新群组成员的基本信息 更新群组成员的基本信息
指令: 指令:
更新群组成员列表/更新群组成员信息 更新群组成员列表/更新群组成员信息
""".strip() """.strip()
__plugin_des__ = '更新群组成员列表' __plugin_des__ = '更新群组成员列表'
__plugin_cmd__ = ['更新群组成员列表'] __plugin_cmd__ = ['更新群组成员列表']
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = 'HibiKier'
__plugin_settings__ = { __plugin_settings__ = {
"admin_level": 1, "admin_level": 1,
} }
refresh_member_group = on_command( refresh_member_group = on_command(
"更新群组成员列表", aliases={"更新群组成员信息"}, permission=GROUP, priority=5, block=True "更新群组成员列表", aliases={"更新群组成员信息"}, permission=GROUP, priority=5, block=True
) )
@refresh_member_group.handle() @refresh_member_group.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
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:
await refresh_member_group.finish("更新群员信息失败!", at_sender=True) await refresh_member_group.finish("更新群员信息失败!", at_sender=True)
group_increase_handle = on_notice(priority=1, block=False) 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, state: dict):
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)
+27 -27
View File
@@ -1,27 +1,27 @@
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.cqhttp 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
__zx_plugin_name__ = '管理帮助 [Admin]' __zx_plugin_name__ = '管理帮助 [Admin]'
__plugin_usage__ = '管理员帮助,在群内回复“管理员帮助”' __plugin_usage__ = '管理员帮助,在群内回复“管理员帮助”'
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = 'HibiKier'
__plugin_settings__ = { __plugin_settings__ = {
"admin_level": 1, "admin_level": 1,
} }
admin_help = on_command("管理员帮助", aliases={"管理帮助"}, priority=5, block=True) admin_help = on_command("管理员帮助", aliases={"管理帮助"}, priority=5, block=True)
if admin_help_image.exists(): if admin_help_image.exists():
admin_help_image.unlink() admin_help_image.unlink()
@admin_help.handle() @admin_help.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if not admin_help_image.exists(): if not admin_help_image.exists():
await create_help_image() await create_help_image()
await admin_help.send(image('admin_help_img.png')) await admin_help.send(image('admin_help_img.png'))
+94 -94
View File
@@ -1,94 +1,94 @@
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
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 utils.manager import group_manager from utils.manager import group_manager
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
from pathlib import Path from pathlib import Path
from nonebot import Driver from nonebot import Driver
import asyncio import asyncio
import nonebot import nonebot
driver: Driver = nonebot.get_driver() driver: Driver = nonebot.get_driver()
background = Path(IMAGE_PATH) / "background" / "0.png" background = Path(IMAGE_PATH) / "background" / "0.png"
admin_help_image = Path(IMAGE_PATH) / 'admin_help_img.png' admin_help_image = Path(IMAGE_PATH) / 'admin_help_img.png'
@driver.on_bot_connect @driver.on_bot_connect
async def init_task(bot: Bot = None): async def init_task(bot: Bot = None):
if not group_manager.get_task_data(): if not group_manager.get_task_data():
await group_manager.init_group_task() await group_manager.init_group_task()
logger.info(f'已成功加载 {len(group_manager.get_task_data())} 个被动技能.') logger.info(f'已成功加载 {len(group_manager.get_task_data())} 个被动技能.')
async def create_help_image(): async def create_help_image():
""" """
创建管理员帮助图片 创建管理员帮助图片
""" """
await asyncio.get_event_loop().run_in_executor( await asyncio.get_event_loop().run_in_executor(
None, _create_help_image None, _create_help_image
) )
def _create_help_image(): def _create_help_image():
""" """
创建管理员帮助图片 创建管理员帮助图片
""" """
_matchers = get_matchers() _matchers = get_matchers()
_plugin_name_list = [] _plugin_name_list = []
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.module)
_module = _plugin.module _module = _plugin.module
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
except AttributeError: except AttributeError:
continue continue
try: try:
if ( if (
"[admin]" in plugin_name.lower() "[admin]" in plugin_name.lower()
and plugin_name not in _plugin_name_list and plugin_name not in _plugin_name_list
and plugin_name != "管理帮助 [Admin]" and plugin_name != "管理帮助 [Admin]"
): ):
_plugin_name_list.append(plugin_name) _plugin_name_list.append(plugin_name)
plugin_settings = _module.__getattribute__("__plugin_settings__") plugin_settings = _module.__getattribute__("__plugin_settings__")
plugin_des = _module.__getattribute__("__plugin_des__") plugin_des = _module.__getattribute__("__plugin_des__")
plugin_cmd = _module.__getattribute__("__plugin_cmd__") plugin_cmd = _module.__getattribute__("__plugin_cmd__")
plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x] plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x]
admin_level = int(plugin_settings["admin_level"]) admin_level = int(plugin_settings["admin_level"])
if _plugin_level.get(admin_level): if _plugin_level.get(admin_level):
_plugin_level[admin_level].append( _plugin_level[admin_level].append(
f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd) f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)
) )
else: else:
_plugin_level[admin_level] = [ _plugin_level[admin_level] = [
f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd) f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)
] ]
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.module}: {plugin_name} 设置失败...")
help_str = "* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" \ help_str = "* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" \
"[权限等级] 管理员帮助:\n\n" "[权限等级] 管理员帮助:\n\n"
x = list(_plugin_level.keys()) x = list(_plugin_level.keys())
x.sort() x.sort()
for level in x: for level in x:
for help_ in _plugin_level[level]: for help_ in _plugin_level[level]:
help_str += f"\t{help_}\n\n" help_str += f"\t{help_}\n\n"
help_str += '-----[被动技能开关]-----\n\n' help_str += '-----[被动技能开关]-----\n\n'
task_data = group_manager.get_task_data() task_data = group_manager.get_task_data()
for i, x in enumerate(task_data.keys()): for i, x in enumerate(task_data.keys()):
help_str += f'{i+1}.开启/关闭{task_data[x]}\n\n' help_str += f'{i+1}.开启/关闭{task_data[x]}\n\n'
height = len(help_str.split("\n")) * 33 height = len(help_str.split("\n")) * 33
A = CreateImg(width, height, font_size=24) A = CreateImg(width, height, font_size=24)
_background = CreateImg(width, height, background=background) _background = CreateImg(width, height, background=background)
A.text((150, 110), help_str) A.text((150, 110), help_str)
A.paste(_background, alpha=True) A.paste(_background, alpha=True)
A.save(admin_help_image) A.save(admin_help_image)
logger.info(f'已成功加载 {len(_plugin_name_list)} 条管理员命令') logger.info(f'已成功加载 {len(_plugin_name_list)} 条管理员命令')
+195 -195
View File
@@ -1,195 +1,195 @@
from utils.message_builder import image from utils.message_builder import image
from utils.utils import scheduler, get_bot from utils.utils import scheduler, get_bot
from nonebot import on_message 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.cqhttp.exception import ActionFailed
from configs.config import NICKNAME from configs.config import NICKNAME
from utils.manager import group_manager from utils.manager import group_manager
__zx_plugin_name__ = "定时任务相关 [Hidden]" __zx_plugin_name__ = "定时任务相关 [Hidden]"
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_task__ = {'zwa': '早晚安'} __plugin_task__ = {'zwa': '早晚安'}
x = on_message(priority=9, block=False) x = on_message(priority=9, block=False)
# 早上好 # 早上好
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=6, hour=6,
minute=1, minute=1,
) )
async def _(): async def _():
try: try:
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]
for g in gl: for g in gl:
if await group_manager.check_group_task_status(g, 'zwa'): 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="早上好" + 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}")
# 睡觉了 # 睡觉了
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=23, hour=23,
minute=59, minute=59,
) )
async def _(): async def _():
try: try:
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]
for g in gl: for g in gl:
if await group_manager.check_group_task_status(g, 'zwa'): 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"{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}")
# 自动更新群组信息 # 自动更新群组信息
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=3, hour=3,
minute=1, minute=1,
) )
async def _(): async def _():
try: try:
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]
for g in gl: for g in gl:
group_info = await bot.get_group_info(group_id=g) group_info = await bot.get_group_info(group_id=g)
await GroupInfo.add_group_info( await GroupInfo.add_group_info(
group_info["group_id"], group_info["group_id"],
group_info["group_name"], group_info["group_name"],
group_info["max_member_count"], group_info["max_member_count"],
group_info["member_count"], group_info["member_count"],
) )
logger.info(f"自动更新群组 {g} 信息成功") logger.info(f"自动更新群组 {g} 信息成功")
except Exception as e: except Exception as e:
logger.error(f"自动更新群组信息错误 e:{e}") logger.error(f"自动更新群组信息错误 e:{e}")
# 自动更新好友信息 # 自动更新好友信息
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=3, hour=3,
minute=1, minute=1,
) )
async def _(): async def _():
try: try:
bot = get_bot() bot = get_bot()
fl = await bot.get_friend_list() fl = await bot.get_friend_list()
for f in fl: for f in fl:
if await FriendUser.add_friend_info(f["user_id"], f["nickname"]): if await FriendUser.add_friend_info(f["user_id"], f["nickname"]):
logger.info(f'自动更新好友 {f["user_id"]} 信息成功') logger.info(f'自动更新好友 {f["user_id"]} 信息成功')
else: else:
logger.warning(f'自动更新好友 {f["user_id"]} 信息失败') logger.warning(f'自动更新好友 {f["user_id"]} 信息失败')
except Exception as e: except Exception as e:
logger.error(f"自动更新群组信息错误 e:{e}") logger.error(f"自动更新群组信息错误 e:{e}")
# 一次性任务 # 一次性任务
# 固定时间触发,仅触发一次: # 固定时间触发,仅触发一次:
# #
# from datetime import datetime # from datetime import datetime
# #
# @nonebot.scheduler.scheduled_job( # @nonebot.scheduler.scheduled_job(
# 'date', # 'date',
# run_date=datetime(2021, 1, 1, 0, 0), # run_date=datetime(2021, 1, 1, 0, 0),
# # timezone=None, # # timezone=None,
# ) # )
# async def _(): # async def _():
# await bot.send_group_msg(group_id=123456, # await bot.send_group_msg(group_id=123456,
# message="2021,新年快乐!") # message="2021,新年快乐!")
# 定期任务 # 定期任务
# 从 start_date 开始到 end_date 结束,根据类似 Cron # 从 start_date 开始到 end_date 结束,根据类似 Cron
# #
# 的规则触发任务: # 的规则触发任务:
# #
# @nonebot.scheduler.scheduled_job( # @nonebot.scheduler.scheduled_job(
# 'cron', # 'cron',
# # year=None, # # year=None,
# # month=None, # # month=None,
# # day=None, # # day=None,
# # week=None, # # week=None,
# day_of_week="mon,tue,wed,thu,fri", # day_of_week="mon,tue,wed,thu,fri",
# hour=7, # hour=7,
# # minute=None, # # minute=None,
# # second=None, # # second=None,
# # start_date=None, # # start_date=None,
# # end_date=None, # # end_date=None,
# # timezone=None, # # timezone=None,
# ) # )
# async def _(): # async def _():
# await bot.send_group_msg(group_id=123456, # await bot.send_group_msg(group_id=123456,
# message="起床啦!") # message="起床啦!")
# 间隔任务 # 间隔任务
# #
# interval 触发器 # interval 触发器
# #
# 从 start_date 开始,每间隔一段时间触发,到 end_date 结束: # 从 start_date 开始,每间隔一段时间触发,到 end_date 结束:
# #
# @nonebot.scheduler.scheduled_job( # @nonebot.scheduler.scheduled_job(
# 'interval', # 'interval',
# # weeks=0, # # weeks=0,
# # days=0, # # days=0,
# # hours=0, # # hours=0,
# minutes=5, # minutes=5,
# # seconds=0, # # seconds=0,
# # start_date=time.now(), # # start_date=time.now(),
# # end_date=None, # # end_date=None,
# ) # )
# async def _(): # async def _():
# has_new_item = check_new_item() # has_new_item = check_new_item()
# if has_new_item: # if has_new_item:
# await bot.send_group_msg(group_id=123456, # await bot.send_group_msg(group_id=123456,
# message="XX有更新啦!") # message="XX有更新啦!")
# 动态的计划任务 # 动态的计划任务
# import datetime # import datetime
# #
# from apscheduler.triggers.date import DateTrigger # 一次性触发器 # from apscheduler.triggers.date import DateTrigger # 一次性触发器
# # from apscheduler.triggers.cron import CronTrigger # 定期触发器 # # from apscheduler.triggers.cron import CronTrigger # 定期触发器
# # from apscheduler.triggers.interval import IntervalTrigger # 间隔触发器 # # from apscheduler.triggers.interval import IntervalTrigger # 间隔触发器
# from nonebot import on_command, scheduler # from nonebot import on_command, scheduler
# #
# @on_command('赖床') # @on_command('赖床')
# async def _(session: CommandSession): # async def _(session: CommandSession):
# await session.send('我会在5分钟后再喊你') # await session.send('我会在5分钟后再喊你')
# #
# # 制作一个“5分钟后”触发器 # # 制作一个“5分钟后”触发器
# delta = datetime.timedelta(minutes=5) # delta = datetime.timedelta(minutes=5)
# trigger = DateTrigger( # trigger = DateTrigger(
# run_date=datetime.datetime.now() + delta # run_date=datetime.datetime.now() + delta
# ) # )
# #
# # 添加任务 # # 添加任务
# scheduler.add_job( # scheduler.add_job(
# func=session.send, # 要添加任务的函数,不要带参数 # func=session.send, # 要添加任务的函数,不要带参数
# trigger=trigger, # 触发器 # trigger=trigger, # 触发器
# args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号 # args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号
# # kwargs=None, # # kwargs=None,
# misfire_grace_time=60, # 允许的误差时间,建议不要省略 # misfire_grace_time=60, # 允许的误差时间,建议不要省略
# # jobstore='default', # 任务储存库,在下一小节中说明 # # jobstore='default', # 任务储存库,在下一小节中说明
# ) # )
Regular → Executable
+207 -197
View File
@@ -1,197 +1,207 @@
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 nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent, MessageEvent
from utils.utils import get_message_at, get_message_text, is_number 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 services.log import logger from services.log import logger
__zx_plugin_name__ = "封禁Ban用户 [Admin]" __zx_plugin_name__ = "封禁Ban用户 [Admin]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
将用户拉入或拉出黑名单 将用户拉入或拉出黑名单
指令: 指令:
.ban [at] ?[小时] ?[分钟] .ban [at] ?[小时] ?[分钟]
.unban .unban
示例:.ban @user 示例:.ban @user
示例:.ban @user 6 示例:.ban @user 6
示例:.ban @user 3 10 示例:.ban @user 3 10
示例:.unban @user 示例:.unban @user
""".strip() """.strip()
__plugin_superuser_usage__ = """ __plugin_superuser_usage__ = """
usage: usage:
屏蔽用户消息,相当于最上级.ban b了=屏蔽用户消息,相当于最上级.ban
指令: 跨群ban以及跨群b了
b了 [at] 指令:
示例:b了 @user b了 [at/qq]
""".strip() .ban [user_id] ?[小时] ?[分钟]
__plugin_des__ = '你被逮捕了!丢进小黑屋!' 示例:b了 @user
__plugin_cmd__ = ['.ban [at] ?[小时] ?[分钟]', '.unban [at]', 'b了 [at] [_superuser]'] 示例:b了 1234567
__plugin_version__ = 0.1 示例:.ban 12345567
__plugin_author__ = 'HibiKier' """.strip()
__plugin_settings__ = { __plugin_des__ = '你被逮捕了!丢进小黑屋!'
"admin_level": Config.get_config("ban", "BAN_LEVEL"), __plugin_cmd__ = ['.ban [at] ?[小时] ?[分钟]', '.unban [at]', 'b了 [at] [_superuser]']
"cmd": ['.ban', '.unban', 'ban', 'unban'] __plugin_version__ = 0.1
} __plugin_author__ = 'HibiKier'
__plugin_configs__ = { __plugin_settings__ = {
"BAN_LEVEL [LEVEL]": { "admin_level": Config.get_config("ban", "BAN_LEVEL"),
"value": 5, "cmd": ['.ban', '.unban', 'ban', 'unban']
"help": "ban/unban所需要的管理员权限等级", }
"default_value": 5 __plugin_configs__ = {
} "BAN_LEVEL [LEVEL]": {
} "value": 5,
"help": "ban/unban所需要的管理员权限等级",
"default_value": 5
ban = on_command( }
".ban", }
aliases={".unban", "/ban", "/unban"},
priority=5,
block=True, ban = on_command(
) ".ban",
aliases={".unban", "/ban", "/unban"},
super_ban = on_command('b了', permission=SUPERUSER, priority=5, block=True) priority=5,
block=True,
)
@ban.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): super_ban = on_command('b了', permission=SUPERUSER, priority=5, block=True)
result = ""
qq = get_message_at(event.json())
if qq: @ban.handle()
qq = qq[0] async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
user_name = await bot.get_group_member_info(group_id=event.group_id, user_id=qq) result = ""
user_name = user_name['card'] if user_name['card'] else user_name['nickname'] qq = get_message_at(event.json())
msg = get_message_text(event.json()) if qq:
if msg: qq = qq[0]
msg = msg.split() user_name = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
if len(msg) == 2: user_name = user_name['card'] if user_name['card'] else user_name['nickname']
if not is_number(msg[0].strip()) or not is_number(msg[1].strip()): msg = get_message_text(event.json())
await ban.finish("参数必须是数字!", at_sender=True) if msg:
time = int(msg[0]) * 60 * 60 + int(msg[1]) * 60 msg = msg.split()
else: if len(msg) == 2:
if not is_number(msg[0].strip()): if not is_number(msg[0].strip()) or not is_number(msg[1].strip()):
await ban.finish("参数必须是数字!", at_sender=True) await ban.finish("参数必须是数字!", at_sender=True)
time = int(msg[0]) * 60 * 60 time = int(msg[0]) * 60 * 60 + int(msg[1]) * 60
else: else:
time = -1 if not is_number(msg[0].strip()):
if state["_prefix"]["raw_command"] in [".ban", "/ban"]: await ban.finish("参数必须是数字!", at_sender=True)
if ( time = int(msg[0]) * 60 * 60
await LevelUser.get_user_level(event.user_id, event.group_id) else:
<= await LevelUser.get_user_level(qq, event.group_id) time = -1
and str(event.user_id) not in bot.config.superusers if state["_prefix"]["raw_command"] in [".ban", "/ban"]:
): if (
await ban.finish( await LevelUser.get_user_level(event.user_id, event.group_id)
f"您的权限等级比对方低或相等, {NICKNAME}不能为您使用此功能!", <= await LevelUser.get_user_level(qq, event.group_id)
at_sender=True, and str(event.user_id) not in bot.config.superusers
) ):
if await BanUser.ban( await ban.finish(
qq, await LevelUser.get_user_level(event.user_id, event.group_id), time f"您的权限等级比对方低或相等, {NICKNAME}不能为您使用此功能!",
): at_sender=True,
logger.info( )
f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time/60} 分钟" if await BanUser.ban(
) qq, await LevelUser.get_user_level(event.user_id, event.group_id), time
result = f"已经将 {user_name} 加入{NICKNAME}的黑名单了!" ):
if time != -1: logger.info(
result += f"将在 {time/60} 分钟后解封" f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
else: )
time = await BanUser.check_ban_time(qq) result = f"已经将 {user_name} 加入{NICKNAME}的黑名单了!"
if is_number(time): if time != -1:
time = abs(int(time)) result += f"将在 {time/60} 分钟后解封"
if time < 60: else:
time = str(time) + " 秒" time = await BanUser.check_ban_time(qq)
else: if is_number(time):
time = str(int(time / 60)) + " 分钟" time = abs(int(time))
else: if time < 60:
time += " 分钟" time = str(time) + " 秒"
result = f"{user_name} 已在黑名单!预计 {time}后解封" else:
else: time = str(int(time / 60)) + " 分钟"
if ( else:
await BanUser.check_ban_level( time += " 分钟"
qq, await LevelUser.get_user_level(event.user_id, event.group_id) result = f"{user_name} 已在黑名单!预计 {time}后解封"
) else:
and str(event.user_id) not in bot.config.superusers if (
): await BanUser.check_ban_level(
await ban.finish( qq, await LevelUser.get_user_level(event.user_id, event.group_id)
f"ban掉 {user_name} 的管理员权限比您高,无法进行unban", at_sender=True )
) and str(event.user_id) not in bot.config.superusers
if await BanUser.unban(qq): ):
logger.info( await ban.finish(
f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 解禁" f"ban掉 {user_name} 的管理员权限比您高,无法进行unban", at_sender=True
) )
result = f"已经把 {user_name} 从黑名单中删除了!" if await BanUser.unban(qq):
else: logger.info(
result = f"{user_name} 不在黑名单!" f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 解禁"
else: )
await ban.finish("艾特人了吗??", at_sender=True) result = f"已经把 {user_name} 从黑名单中删除了!"
await ban.finish(result, at_sender=True) else:
result = f"{user_name} 不在黑名单!"
else:
@ban.handle() await ban.finish("艾特人了吗??", at_sender=True)
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): await ban.finish(result, at_sender=True)
if str(event.user_id) in bot.config.superusers:
msg = get_message_text(event.json())
msg = msg.split() @ban.handle()
if is_number(msg[0]): async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
qq = int(msg[0]) if str(event.user_id) in bot.config.superusers:
if state["_prefix"]["raw_command"] in [".ban", "/ban"]: msg = get_message_text(event.json())
hour = 0 msg = msg.split()
minute = 0 if is_number(msg[0]):
if len(msg) > 1 and is_number(msg[1]): qq = int(msg[0])
hour = int(msg[1]) if state["_prefix"]["raw_command"] in [".ban", "/ban"]:
if len(msg) > 2 and is_number(msg[2]): hour = 0
minute = int(msg[2]) minute = 0
time = hour * 60 * 60 + minute * 60 if len(msg) > 1 and is_number(msg[1]):
time = time if time else -1 hour = int(msg[1])
if await BanUser.ban( if len(msg) > 2 and is_number(msg[2]):
qq, 9, time minute = int(msg[2])
): time = hour * 60 * 60 + minute * 60
logger.info( time = time if time else -1
f"USER {event.user_id} 将 USER {qq} 封禁 时长 {time/60} 分钟" if await BanUser.ban(
) qq, 9, time
result = f"已经将 {qq} 加入{NICKNAME}的黑名单了!" ):
if time != -1: logger.info(
result += f"将在 {time/60} 分钟后解封" f"USER {event.user_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
else: )
result += f"将在 ∞ 分钟后解封" result = f"已经将 {qq} 加入{NICKNAME}的黑名单了!"
await ban.send(result) if time != -1:
else: result += f"将在 {time/60} 分钟后解封"
time = await BanUser.check_ban_time(qq) else:
if is_number(time): result += f"将在 ∞ 分钟后解封"
time = abs(int(time)) await ban.send(result)
if time < 60: else:
time = str(time) + " 秒" time = await BanUser.check_ban_time(qq)
else: if is_number(time):
time = str(int(time / 60)) + " 分钟" time = abs(int(time))
else: if time < 60:
time += " 分钟" time = str(time) + " 秒"
await ban.send(f"{qq} 已在黑名单!预计 {time}后解封") else:
else: time = str(int(time / 60)) + " 分钟"
if await BanUser.unban(qq): else:
logger.info( time += " 分钟"
f"USER {event.user_id} 将 USER {qq} 解禁" await ban.send(f"{qq} 已在黑名单!预计 {time}后解封")
) else:
result = f"已经把 {qq} 从黑名单中删除了!" if await BanUser.unban(qq):
else: logger.info(
result = f"{qq} 不在黑名单!" f"USER {event.user_id} 将 USER {qq} 解禁"
await ban.send(result) )
else: result = f"已经把 {qq} 从黑名单中删除了!"
await ban.finish('qq号必须是数字!\n格式:.ban [qq] [hour]? [minute]?', at_sender=True) else:
result = f"{qq} 不在黑名单!"
await ban.send(result)
@super_ban.handle() else:
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): await ban.finish('qq号必须是数字!\n格式:.ban [qq] [hour]? [minute]?', at_sender=True)
qq = get_message_at(event.json())
if qq:
qq = qq[0] @super_ban.handle()
user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq) async def _(bot: Bot, event: MessageEvent, state: T_State):
user_name = user['card'] if user['card'] else user['nickname'] if isinstance(event, GroupMessageEvent):
if not await BanUser.ban(qq, 10, 99999999): qq = get_message_at(event.json())
await BanUser.unban(qq) else:
await BanUser.ban(qq, 10, 99999999) qq = get_message_text(event.json())
await ban.send(f"已将 {user_name} 拉入黑名单!") if not is_number(qq):
else: await super_ban.finish("对象qq必须为纯数字...")
await super_ban.send('需要艾特被super ban的对象..') qq = [qq]
if qq:
qq = qq[0]
user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
user_name = user['card'] if user['card'] else user['nickname']
if not await BanUser.ban(qq, 10, 99999999):
await BanUser.unban(qq)
await BanUser.ban(qq, 10, 99999999)
await ban.send(f"已将 {user_name} 拉入黑名单!")
else:
await super_ban.send('需要艾特被super ban的对象..')
+59 -59
View File
@@ -1,59 +1,59 @@
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, Event from nonebot.adapters import Bot, Event
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
import asyncio import asyncio
from utils.utils import get_message_text, get_message_imgs from utils.utils import get_message_text, get_message_imgs
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
__zx_plugin_name__ = "广播 [Superuser]" __zx_plugin_name__ = "广播 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
指令: 指令:
广播- ?[消息] ?[图片] 广播- ?[消息] ?[图片]
示例:广播- 你们好! 示例:广播- 你们好!
""".strip() """.strip()
__plugin_des__ = "昭告天下!" __plugin_des__ = "昭告天下!"
__plugin_cmd__ = ["广播-"] __plugin_cmd__ = ["广播-"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_task__ = {"broadcast": "广播"} __plugin_task__ = {"broadcast": "广播"}
broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True) 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: Event, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
imgs = get_message_imgs(event.json()) imgs = get_message_imgs(event.json())
rst = "" rst = ""
for img in imgs: for img in imgs:
rst += image(img) rst += image(img)
sid = bot.self_id sid = bot.self_id
gl = await bot.get_group_list(self_id=sid) 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
if await group_manager.check_group_task_status(g["group_id"], "broadcast") if await group_manager.check_group_task_status(g["group_id"], "broadcast")
] ]
g_cnt = len(gl) g_cnt = len(gl)
cnt = 0 cnt = 0
error = "" error = ""
x = 0.25 x = 0.25
for g in gl: for g in gl:
cnt += 1 cnt += 1
if cnt / g_cnt > x: if cnt / g_cnt > x:
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(self_id=sid, 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)}")
error += f"GROUP {g} 投递广播失败:{type(e)}\n" error += f"GROUP {g} 投递广播失败:{type(e)}\n"
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
await broadcast.send(f"已播报至 100% 的群聊") await broadcast.send(f"已播报至 100% 的群聊")
if error: if error:
await broadcast.send(f"播报时错误:{error}") await broadcast.send(f"播报时错误:{error}")
+184 -184
View File
@@ -1,184 +1,184 @@
from nonebot import on_notice, on_request from nonebot import on_notice, on_request
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 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.cqhttp import (
Bot, Bot,
GroupIncreaseNoticeEvent, GroupIncreaseNoticeEvent,
GroupDecreaseNoticeEvent, GroupDecreaseNoticeEvent,
) )
from nonebot.adapters.cqhttp.exception import ActionFailed from nonebot.adapters.cqhttp.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
from utils.utils import FreqLimiter from utils.utils import FreqLimiter
from configs.config import Config from configs.config import Config
from pathlib import Path from pathlib import Path
import random import random
import os import os
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
__zx_plugin_name__ = "群事件处理 [Hidden]" __zx_plugin_name__ = "群事件处理 [Hidden]"
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_task__ = {"group_welcome": "进群欢迎", "refund_group_remind": "退群提醒"} __plugin_task__ = {"group_welcome": "进群欢迎", "refund_group_remind": "退群提醒"}
Config.add_plugin_config( Config.add_plugin_config(
"auto_invite", "message", f"请不要未经同意就拉{NICKNAME}入群!告辞!", help_="强制拉群后进群回复的内容.." "invite_manager", "message", f"请不要未经同意就拉{NICKNAME}入群!告辞!", help_="强制拉群后进群回复的内容.."
) )
Config.add_plugin_config( Config.add_plugin_config(
"auto_invite", "flag", True, help_="被强制拉群后是否直接退出", default_value=True "invite_manager", "flag", True, help_="被强制拉群后是否直接退出", default_value=True
) )
Config.add_plugin_config( Config.add_plugin_config(
"auto_invite", "welcome_msg_cd", 5, help_="群欢迎消息cd", default_value=5 "invite_manager", "welcome_msg_cd", 5, help_="群欢迎消息cd", default_value=5
) )
_flmt = FreqLimiter(Config.get_config("auto_invite", "welcome_msg_cd")) _flmt = FreqLimiter(Config.get_config("invite_manager", "welcome_msg_cd"))
# 群员增加处理 # 群员增加处理
group_increase_handle = on_notice(priority=1, block=False) group_increase_handle = on_notice(priority=1, block=False)
# 群员减少处理 # 群员减少处理
group_decrease_handle = on_notice(priority=1, block=False) group_decrease_handle = on_notice(priority=1, block=False)
# (群管理)加群同意请求 # (群管理)加群同意请求
add_group = on_request(priority=1, block=False) 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, state: dict):
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)
# 群聊不存在或被强制拉群,退出该群 # 群聊不存在或被强制拉群,退出该群
if (not group or group.group_flag == 0) and Config.get_config( if (not group or group.group_flag == 0) and Config.get_config(
"auto_invite", "flag" "invite_manager", "flag"
): ):
try: try:
msg = Config.get_config("auto_invite", "message") msg = Config.get_config("invite_manager", "message")
if msg: if msg:
await bot.send_group_msg(group_id=event.group_id, message=msg) await bot.send_group_msg(group_id=event.group_id, message=msg)
await bot.set_group_leave(group_id=event.group_id) await bot.set_group_leave(group_id=event.group_id)
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"触发强制入群保护,已成功退出群聊 {event.group_id}..", message=f"触发强制入群保护,已成功退出群聊 {event.group_id}..",
) )
logger.info(f"强制拉群或未有群信息,退出群聊 {group} 成功") logger.info(f"强制拉群或未有群信息,退出群聊 {group} 成功")
requests_manager.remove_request("group", event.group_id) requests_manager.remove_request("group", event.group_id)
except Exception as e: except Exception as e:
logger.info(f"强制拉群或未有群信息,退出群聊 {group} 失败 e:{e}") logger.info(f"强制拉群或未有群信息,退出群聊 {group} 失败 e:{e}")
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"触发强制入群保护,退出群聊 {event.group_id} 失败..", message=f"触发强制入群保护,退出群聊 {event.group_id} 失败..",
) )
# 默认群功能开关 # 默认群功能开关
elif event.group_id not in group_manager["group_manager"].keys(): elif event.group_id not in group_manager["group_manager"].keys():
data = plugins2settings_manager.get_data() data = plugins2settings_manager.get_data()
for plugin in data.keys(): for plugin in data.keys():
if not data[plugin]["default_status"]: if not data[plugin]["default_status"]:
group_manager.block_plugin(plugin, event.group_id) group_manager.block_plugin(plugin, event.group_id)
else: else:
join_time = datetime.now() join_time = datetime.now()
user_info = await bot.get_group_member_info( user_info = await bot.get_group_member_info(
group_id=event.group_id, user_id=event.user_id group_id=event.group_id, user_id=event.user_id
) )
if await GroupInfoUser.add_member_info( if await GroupInfoUser.add_member_info(
user_info["user_id"], user_info["user_id"],
user_info["group_id"], user_info["group_id"],
user_info["nickname"], user_info["nickname"],
join_time, join_time,
): ):
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功") logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
else: else:
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 await group_manager.check_group_task_status(
event.group_id, "group_welcome" event.group_id, "group_welcome"
) and _flmt.check(event.group_id): ) and _flmt.check(event.group_id):
_flmt.start_cd(event.group_id) _flmt.start_cd(event.group_id)
msg = "" msg = ""
img = "" img = ""
at_flag = False at_flag = False
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"
) )
if custom_welcome_msg_json.exists(): if custom_welcome_msg_json.exists():
data = json.load(open(custom_welcome_msg_json, "r")) data = json.load(open(custom_welcome_msg_json, "r"))
if data.get(str(event.group_id)): if data.get(str(event.group_id)):
msg = data[str(event.group_id)] msg = data[str(event.group_id)]
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 os.path.exists(DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"):
img = image( img = image(
abspath=DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg" abspath=DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"
) )
if msg or img: if msg or img:
await group_increase_handle.send( await group_increase_handle.send(
"\n" + msg.strip() + img, at_sender=at_flag "\n" + msg.strip() + img, at_sender=at_flag
) )
else: else:
await group_increase_handle.send( await group_increase_handle.send(
"新人快跑啊!!本群现状↓(快使用自定义!)" "新人快跑啊!!本群现状↓(快使用自定义!)"
+ 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, state: dict):
# 被踢出群 # 被踢出群
if event.sub_type == "kick_me": if event.sub_type == "kick_me":
group_id = event.group_id group_id = event.group_id
operator_id = event.operator_id operator_id = event.operator_id
try: try:
operator_name = ( operator_name = (
await GroupInfoUser.get_member_info(event.operator_id, event.group_id) await GroupInfoUser.get_member_info(event.operator_id, event.group_id)
).user_name ).user_name
except AttributeError: except AttributeError:
operator_name = "None" operator_name = "None"
group = await GroupInfo.get_group_info(group_id) group = await GroupInfo.get_group_info(group_id)
group_name = group.group_name if group else "" group_name = group.group_name if group else ""
coffee = int(list(bot.config.superusers)[0]) coffee = int(list(bot.config.superusers)[0])
await bot.send_private_msg( await bot.send_private_msg(
user_id=coffee, user_id=coffee,
message=f"****呜..一份踢出报告****\n" message=f"****呜..一份踢出报告****\n"
f"我被 {operator_name}({operator_id})\n" f"我被 {operator_name}({operator_id})\n"
f"踢出了 {group_name}({group_id})\n" f"踢出了 {group_name}({group_id})\n"
f"日期:{str(datetime.now()).split('.')[0]}", f"日期:{str(datetime.now()).split('.')[0]}",
) )
return return
if event.user_id == int(bot.self_id): if event.user_id == int(bot.self_id):
group_manager.delete_group(event.group_id) group_manager.delete_group(event.group_id)
return return
try: try:
user_name = ( user_name = (
await GroupInfoUser.get_member_info(event.user_id, event.group_id) await GroupInfoUser.get_member_info(event.user_id, event.group_id)
).user_name ).user_name
except AttributeError: except AttributeError:
user_name = str(event.user_id) user_name = str(event.user_id)
if await GroupInfoUser.delete_member_info(event.user_id, event.group_id): if await GroupInfoUser.delete_member_info(event.user_id, event.group_id):
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( if await group_manager.check_group_task_status(
event.group_id, "refund_group_remind" event.group_id, "refund_group_remind"
): ):
rst = "" rst = ""
if event.sub_type == "leave": if event.sub_type == "leave":
rst = f"{user_name}离开了我们..." rst = f"{user_name}离开了我们..."
if event.sub_type == "kick": if event.sub_type == "kick":
operator = await bot.get_group_member_info( operator = await bot.get_group_member_info(
user_id=event.operator_id, group_id=event.group_id user_id=event.operator_id, group_id=event.group_id
) )
operator_name = ( operator_name = (
operator["card"] if operator["card"] else operator["nickname"] operator["card"] if operator["card"] else operator["nickname"]
) )
rst = f"{user_name} 被 {operator_name} 送走了." rst = f"{user_name} 被 {operator_name} 送走了."
try: try:
await group_decrease_handle.send(f"{rst}") await group_decrease_handle.send(f"{rst}")
except ActionFailed: except ActionFailed:
return return
Regular → Executable
+73 -73
View File
@@ -1,73 +1,73 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import ( from nonebot.adapters.cqhttp import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent GroupMessageEvent
) )
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 utils.utils import get_message_text
from pathlib import Path 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 = Path(DATA_PATH) / "group_help"
help_image = Path(IMAGE_PATH) / "help.png" help_image = Path(IMAGE_PATH) / "help.png"
simple_help_image = Path(IMAGE_PATH) / "simple_help.png" simple_help_image = Path(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():
simple_help_image.unlink() simple_help_image.unlink()
group_help_path.mkdir(exist_ok=True, parents=True) group_help_path.mkdir(exist_ok=True, parents=True)
for x in os.listdir(group_help_path): for x in os.listdir(group_help_path):
group_help_image = group_help_path / x group_help_image = group_help_path / x
group_help_image.unlink() group_help_image.unlink()
_help = on_command("详细功能", rule=to_me(), aliases={"详细帮助"}, priority=1, block=True) _help = on_command("详细功能", rule=to_me(), aliases={"详细帮助"}, priority=1, block=True)
simple_help = on_command("功能", rule=to_me(), aliases={"help", "帮助"}, priority=1, block=True) simple_help = on_command("功能", rule=to_me(), aliases={"help", "帮助"}, priority=1, block=True)
@_help.handle() @_help.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
if not help_image.exists(): if not help_image.exists():
if help_image.exists(): if help_image.exists():
help_image.unlink() help_image.unlink()
if simple_help_image.exists(): if simple_help_image.exists():
simple_help_image.unlink() simple_help_image.unlink()
await create_help_img(None, help_image, simple_help_image) await create_help_img(None, help_image, simple_help_image)
await _help.finish(image("help.png")) await _help.finish(image("help.png"))
@simple_help.handle() @simple_help.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
is_super = False is_super = False
if msg: if msg:
if '-super' in msg: if '-super' in msg:
if str(event.user_id) in bot.config.superusers: if str(event.user_id) in bot.config.superusers:
is_super = True is_super = True
msg = msg.replace('-super', '').strip() msg = msg.replace('-super', '').strip()
msg = get_plugin_help(msg, is_super) msg = get_plugin_help(msg, is_super)
if msg: if msg:
await _help.send(image(b64=msg)) await _help.send(image(b64=msg))
else: else:
await _help.send("没有此功能的帮助信息...") await _help.send("没有此功能的帮助信息...")
else: else:
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
_image_path = group_help_path / f"{event.group_id}.png" _image_path = group_help_path / f"{event.group_id}.png"
if not _image_path.exists(): if not _image_path.exists():
await create_help_img(event.group_id, help_image, _image_path) await create_help_img(event.group_id, help_image, _image_path)
await simple_help.send(image(_image_path)) await simple_help.send(image(_image_path))
else: else:
if not simple_help_image.exists(): if not simple_help_image.exists():
if help_image.exists(): if help_image.exists():
help_image.unlink() help_image.unlink()
if simple_help_image.exists(): if simple_help_image.exists():
simple_help_image.unlink() simple_help_image.unlink()
await create_help_img(None, help_image, simple_help_image) await create_help_img(None, help_image, simple_help_image)
await _help.finish(image("simple_help.png")) await _help.finish(image("simple_help.png"))
+367 -367
View File
@@ -1,367 +1,367 @@
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.manager import ( from utils.manager import (
plugins2settings_manager, plugins2settings_manager,
admin_manager, admin_manager,
plugins_manager, plugins_manager,
group_manager, group_manager,
) )
from typing import Optional from typing import Optional
from services.log import logger from services.log import logger
from pathlib import Path from pathlib import Path
from utils.utils import get_matchers from utils.utils import get_matchers
import random import random
import asyncio import asyncio
import nonebot import nonebot
import os import os
random_bk_path = Path(IMAGE_PATH) / "background" / "help" / "simple_help" random_bk_path = Path(IMAGE_PATH) / "background" / "help" / "simple_help"
background = Path(IMAGE_PATH) / "background" / "0.png" background = Path(IMAGE_PATH) / "background" / "0.png"
async def create_help_img( async def create_help_img(
group_id: Optional[int], help_image: Path, simple_help_image: Path group_id: Optional[int], help_image: Path, simple_help_image: Path
): ):
""" """
生成帮助图片 生成帮助图片
:param group_id: 群号 :param group_id: 群号
:param help_image: 图片路径 :param help_image: 图片路径
:param simple_help_image: 简易帮助图片路径 :param simple_help_image: 简易帮助图片路径
""" """
return await asyncio.get_event_loop().run_in_executor( return await asyncio.get_event_loop().run_in_executor(
None, _create_help_img, group_id, help_image, simple_help_image None, _create_help_img, group_id, help_image, simple_help_image
) )
def _create_help_img( def _create_help_img(
group_id: Optional[int], help_image: Path, simple_help_image: Path group_id: Optional[int], help_image: Path, simple_help_image: Path
): ):
""" """
生成帮助图片 生成帮助图片
:param group_id: 群号 :param group_id: 群号
:param help_image: 图片路径 :param help_image: 图片路径
:param simple_help_image: 简易帮助图片路径 :param simple_help_image: 简易帮助图片路径
""" """
_matchers = get_matchers() _matchers = get_matchers()
width = 0 width = 0
matchers_data = {} matchers_data = {}
_des_tmp = {} _des_tmp = {}
_plugin_name_tmp = [] _plugin_name_tmp = []
_tmp = [] _tmp = []
tmp_img = CreateImg(0, 0, plain_text="1", font_size=24) tmp_img = CreateImg(0, 0, plain_text="1", font_size=24)
font_height = tmp_img.h font_height = tmp_img.h
# 插件分类 # 插件分类
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.module)
_module = _plugin.module _module = _plugin.module
try: try:
plugin_name = _module.__getattribute__("__zx_plugin_name__") plugin_name = _module.__getattribute__("__zx_plugin_name__")
try: try:
plugin_des = _module.__getattribute__("__plugin_des__") plugin_des = _module.__getattribute__("__plugin_des__")
except AttributeError: except AttributeError:
plugin_des = "_" plugin_des = "_"
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 plugin_name in _plugin_name_tmp or plugin_name in _plugin_name_tmp
or plugin_name == "帮助" or plugin_name == "帮助"
): ):
continue continue
plugin_type = ("normal",) plugin_type = ("normal",)
text_type = 0 text_type = 0
if plugins2settings_manager.get( if plugins2settings_manager.get(
matcher.module matcher.module
) and plugins2settings_manager[matcher.module].get("plugin_type"): ) and plugins2settings_manager[matcher.module].get("plugin_type"):
plugin_type = tuple( plugin_type = tuple(
plugins2settings_manager.get_plugin_data(matcher.module)[ plugins2settings_manager.get_plugin_data(matcher.module)[
"plugin_type" "plugin_type"
] ]
) )
else: else:
try: try:
plugin_type = _module.__getattribute__("__plugin_type__") plugin_type = _module.__getattribute__("__plugin_type__")
except AttributeError: except AttributeError:
pass pass
if len(plugin_type) > 1: if len(plugin_type) > 1:
try: try:
text_type = int(plugin_type[1]) text_type = int(plugin_type[1])
except ValueError as e: except ValueError as e:
logger.warning(f"生成列向帮助排列失败 {plugin_name}: {type(e)}: {e}") logger.warning(f"生成列向帮助排列失败 {plugin_name}: {type(e)}: {e}")
plugin_type = plugin_type[0] plugin_type = plugin_type[0]
else: else:
plugin_type = plugin_type[0] plugin_type = plugin_type[0]
try: try:
plugin_cmd = _module.__getattribute__("__plugin_cmd__") plugin_cmd = _module.__getattribute__("__plugin_cmd__")
plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x] plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x]
except AttributeError: except AttributeError:
plugin_cmd = [] plugin_cmd = []
if plugin_type not in matchers_data.keys(): if plugin_type not in matchers_data.keys():
matchers_data[plugin_type] = {} matchers_data[plugin_type] = {}
if plugin_des in _des_tmp.keys(): if plugin_des in _des_tmp.keys():
try: try:
matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"] = ( matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"] = (
matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"] matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"]
+ plugin_cmd + plugin_cmd
) )
except KeyError as e: except KeyError as e:
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, "module": matcher.module,
"des": plugin_des, "des": plugin_des,
"cmd": plugin_cmd, "cmd": plugin_cmd,
"text_type": text_type, "text_type": text_type,
} }
try: try:
if text_type == 0: if text_type == 0:
x = tmp_img.getsize( x = tmp_img.getsize(
f'{plugin_name}: {matchers_data[plugin_type][plugin_name]["des"]} ->' f'{plugin_name}: {matchers_data[plugin_type][plugin_name]["des"]} ->'
+ " / ".join(matchers_data[plugin_type][plugin_name]["cmd"]) + " / ".join(matchers_data[plugin_type][plugin_name]["cmd"])
)[0] )[0]
width = width if width > x else x width = width if width > x else x
except KeyError: except KeyError:
pass pass
if plugin_des not in _des_tmp: if plugin_des not in _des_tmp:
_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.module}: {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 = []
simple_help_img_list = [] simple_help_img_list = []
types = list(matchers_data.keys()) types = list(matchers_data.keys())
types.sort() types.sort()
ix = 0 ix = 0
# 详细帮助 # 详细帮助
for type_ in types: for type_ in types:
keys = list(matchers_data[type_].keys()) keys = list(matchers_data[type_].keys())
keys.sort() keys.sort()
help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n" help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n"
simple_help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n" simple_help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n"
for i, k in enumerate(keys): for i, k in enumerate(keys):
# 禁用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]["module"], "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]["module"], "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]['module'], 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:
_x = tmp_img.getsize( _x = tmp_img.getsize(
f"{i+1}".rjust(5) f"{i+1}".rjust(5)
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} ' + f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
)[0] )[0]
_str = ( _str = (
f"{i+1}".rjust(5) f"{i+1}".rjust(5)
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} ' + f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
) )
_str += matchers_data[type_][k]["cmd"][0] + "\n" _str += matchers_data[type_][k]["cmd"][0] + "\n"
for c in matchers_data[type_][k]["cmd"][1:]: for c in matchers_data[type_][k]["cmd"][1:]:
_str += "".rjust(int(_x * 0.125) + 1) + f"{c}\n" _str += "".rjust(int(_x * 0.125) + 1) + f"{c}\n"
help_str += _str help_str += _str
else: else:
help_str += ( help_str += (
f"{i+1}".rjust(5) f"{i+1}".rjust(5)
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} ' + f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
+ " / ".join(matchers_data[type_][k]["cmd"]) + " / ".join(matchers_data[type_][k]["cmd"])
+ "\n" + "\n"
) )
height = len(help_str.split("\n")) * (font_height + 5) height = len(help_str.split("\n")) * (font_height + 5)
simple_height = len(simple_help_str.split("\n")) * (font_height + 5) simple_height = len(simple_help_str.split("\n")) * (font_height + 5)
A = CreateImg( A = CreateImg(
width + 150, height, font_size=24, color="white" if not ix % 2 else "black" width + 150, height, font_size=24, color="white" if not ix % 2 else "black"
) )
A.text((10, 10), help_str, (255, 255, 255) if ix % 2 else (0, 0, 0)) A.text((10, 10), help_str, (255, 255, 255) if ix % 2 else (0, 0, 0))
# 生成各个分类的插件简易帮助图片 # 生成各个分类的插件简易帮助图片
simple_width = 0 simple_width = 0
for x in [ for x in [
tmp_img.getsize(x.split("<|_|~|>")[0])[0] tmp_img.getsize(x.split("<|_|~|>")[0])[0]
for x in simple_help_str.split("\n") for x in simple_help_str.split("\n")
]: ]:
simple_width = simple_width if simple_width > x else x simple_width = simple_width if simple_width > x else x
bk = CreateImg(simple_width + 20, simple_height, font_size=24, color="#6495ED") bk = CreateImg(simple_width + 20, simple_height, font_size=24, color="#6495ED")
B = CreateImg( B = CreateImg(
simple_width + 20, simple_width + 20,
simple_height, simple_height,
font_size=24, font_size=24,
color="white" if not ix % 2 else "black", color="white" if not ix % 2 else "black",
) )
# 切分,判断插件开关状态 # 切分,判断插件开关状态
_s_height = 10 _s_height = 10
for _s in simple_help_str.split("\n"): for _s in simple_help_str.split("\n"):
text_color = (255, 255, 255) if ix % 2 else (0, 0, 0) text_color = (255, 255, 255) if ix % 2 else (0, 0, 0)
_line_flag = False _line_flag = False
if "<|_|~|>" in _s: if "<|_|~|>" in _s:
_x = _s.split("<|_|~|>") _x = _s.split("<|_|~|>")
_flag_sp = _x[-1].split("|") _flag_sp = _x[-1].split("|")
if group_id: if group_id:
if _flag_sp[0].lower() != "true": if _flag_sp[0].lower() != "true":
text_color = (252, 75, 13) text_color = (252, 75, 13)
if _flag_sp[1].lower() == "true": if _flag_sp[1].lower() == "true":
_line_flag = True _line_flag = True
_s = _x[0] _s = _x[0]
B.text((10, _s_height), _s, text_color) B.text((10, _s_height), _s, text_color)
if _line_flag: if _line_flag:
B.line( B.line(
( (
7, 7,
_s_height + int(B.getsize(_s)[1] / 2) + 2, _s_height + int(B.getsize(_s)[1] / 2) + 2,
B.getsize(_s)[0] + 11, B.getsize(_s)[0] + 11,
_s_height + int(B.getsize(_s)[1] / 2) + 2, _s_height + int(B.getsize(_s)[1] / 2) + 2,
), ),
(236, 66, 7), (236, 66, 7),
3, 3,
) )
_s_height += B.getsize("1")[1] + 5 _s_height += B.getsize("1")[1] + 5
# B.text((10, 10), simple_help_str, (255, 255, 255) if ix % 2 else (0, 0, 0)) # B.text((10, 10), simple_help_str, (255, 255, 255) if ix % 2 else (0, 0, 0))
bk.paste(B, center_type="center") bk.paste(B, center_type="center")
bk.transparent(2) bk.transparent(2)
ix += 1 ix += 1
help_img_list.append(A) help_img_list.append(A)
simple_help_img_list.append(bk) simple_help_img_list.append(bk)
height = 0 height = 0
for img in help_img_list: for img in help_img_list:
height += img.h height += img.h
if not group_id: if not group_id:
A = CreateImg(width + 150, height + 50, font_size=24) A = CreateImg(width + 150, height + 50, font_size=24)
A.text( A.text(
(10, 10), '* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" "功能名: 功能简介 -> 指令\n\n' (10, 10), '* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" "功能名: 功能简介 -> 指令\n\n'
) )
current_height = 50 current_height = 50
for img in help_img_list: for img in help_img_list:
A.paste(img, (0, current_height)) A.paste(img, (0, current_height))
current_height += img.h current_height += img.h
A.save(help_image) A.save(help_image)
# 详细帮助生成完毕 # 详细帮助生成完毕
# 简易帮助图片合成 # 简易帮助图片合成
height = 0 height = 0
width = 0 width = 0
for img in simple_help_img_list: for img in simple_help_img_list:
if img.h > height: if img.h > height:
height = img.h height = img.h
width += img.w + 10 width += img.w + 10
B = CreateImg(width + 100, height + 250, font_size=24) B = CreateImg(width + 100, height + 250, font_size=24)
width, _ = get_max_width_or_paste(simple_help_img_list, B) width, _ = get_max_width_or_paste(simple_help_img_list, B)
bk = None bk = None
random_bk = os.listdir(random_bk_path) random_bk = os.listdir(random_bk_path)
if random_bk: if random_bk:
bk = random.choice(random_bk) bk = random.choice(random_bk)
x = max(width + 50, height + 250) x = max(width + 50, height + 250)
B = CreateImg( B = CreateImg(
x, x,
x, x,
font_size=24, font_size=24,
color="#FFEFD5", color="#FFEFD5",
background=random_bk_path / bk, background=random_bk_path / bk,
) )
B.filter("GaussianBlur", 10) B.filter("GaussianBlur", 10)
_, B = get_max_width_or_paste(simple_help_img_list, B, True) _, B = get_max_width_or_paste(simple_help_img_list, B, True)
w = 10 w = 10
h = 10 h = 10
for msg in ["目前支持的功能列表:", "可以通过 ‘帮助[功能名称]’ 来获取对应功能的使用方法", "或者使用 ‘详细帮助’ 来获取所有功能方法"]: for msg in ["目前支持的功能列表:", "可以通过 ‘帮助[功能名称]’ 来获取对应功能的使用方法", "或者使用 ‘详细帮助’ 来获取所有功能方法"]:
text = CreateImg( text = CreateImg(
0, 0,
0, 0,
plain_text=msg, plain_text=msg,
font_size=24, font_size=24,
font="yuanshen.ttf", font="yuanshen.ttf",
) )
B.paste(text, (w, h), True) B.paste(text, (w, h), True)
h += 50 h += 50
if msg == "目前支持的功能列表:": if msg == "目前支持的功能列表:":
w += 50 w += 50
B.paste( B.paste(
CreateImg( CreateImg(
0, 0,
0, 0,
plain_text="注: 红字代表功能被群管理员禁用,红线代表功能正在维护", plain_text="注: 红字代表功能被群管理员禁用,红线代表功能正在维护",
font_size=24, font_size=24,
font="yuanshen.ttf", font="yuanshen.ttf",
font_color=(231, 74, 57) font_color=(231, 74, 57)
), ),
(300, 10), (300, 10),
True, True,
) )
B.save(simple_help_image) B.save(simple_help_image)
def get_max_width_or_paste( def get_max_width_or_paste(
simple_help_img_list: list, B: CreateImg = None, is_paste: bool = False simple_help_img_list: list, B: CreateImg = None, is_paste: bool = False
) -> "int, CreateImg": ) -> "int, CreateImg":
""" """
获取最大宽度,或直接贴图 获取最大宽度,或直接贴图
:param simple_help_img_list: 简单帮助图片列表 :param simple_help_img_list: 简单帮助图片列表
:param B: 背景图 :param B: 背景图
:param is_paste: 是否直接贴图 :param is_paste: 是否直接贴图
""" """
current_width = 50 current_width = 50
current_height = 180 current_height = 180
max_width = simple_help_img_list[0].w max_width = simple_help_img_list[0].w
for i in range(len(simple_help_img_list)): for i in range(len(simple_help_img_list)):
try: try:
if is_paste and B: if is_paste and B:
B.paste(simple_help_img_list[i], (current_width, current_height), True) B.paste(simple_help_img_list[i], (current_width, current_height), True)
current_height += simple_help_img_list[i].h + 40 current_height += simple_help_img_list[i].h + 40
if current_height + simple_help_img_list[i + 1].h > B.h - 10: if current_height + simple_help_img_list[i + 1].h > B.h - 10:
current_height = 180 current_height = 180
current_width += max_width + 30 current_width += max_width + 30
max_width = 0 max_width = 0
elif simple_help_img_list[i].w > max_width: elif simple_help_img_list[i].w > max_width:
max_width = simple_help_img_list[i].w max_width = simple_help_img_list[i].w
except IndexError: except IndexError:
pass pass
if current_width > simple_help_img_list[0].w + 50: if current_width > simple_help_img_list[0].w + 50:
current_width += simple_help_img_list[-1].w current_width += simple_help_img_list[-1].w
return current_width, B return current_width, B
def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]: def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]:
""" """
获取功能的帮助信息 获取功能的帮助信息
:param msg: 功能cmd :param msg: 功能cmd
:param is_super: 是否为超级用户 :param is_super: 是否为超级用户
""" """
module = plugins2settings_manager.get_plugin_module(msg) module = plugins2settings_manager.get_plugin_module(msg)
if not module: if not module:
module = admin_manager.get_plugin_module(msg) module = admin_manager.get_plugin_module(msg)
if module: if module:
try: try:
plugin = nonebot.plugin.get_plugin(module) plugin = nonebot.plugin.get_plugin(module)
if plugin: if plugin:
if is_super: if is_super:
result = plugin.module.__getattribute__( result = plugin.module.__getattribute__(
"__plugin_superuser_usage__" "__plugin_superuser_usage__"
) )
else: else:
result = plugin.module.__getattribute__("__plugin_usage__") result = plugin.module.__getattribute__("__plugin_usage__")
if result: if result:
width = 0 width = 0
for x in result.split("\n"): for x in result.split("\n"):
_width = len(x) * 24 _width = len(x) * 24
width = width if width > _width else _width width = width if width > _width else _width
height = len(result.split("\n")) * 45 height = len(result.split("\n")) * 45
A = CreateImg(width, height, font_size=24) A = CreateImg(width, height, font_size=24)
bk = CreateImg( bk = CreateImg(
width, width,
height, height,
background=Path(IMAGE_PATH) / "background" / "1.png", background=Path(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)
return A.pic2bs4() return A.pic2bs4()
except AttributeError: except AttributeError:
pass pass
return None return None
Regular → Executable
+38 -38
View File
@@ -1,38 +1,38 @@
from configs.config import Config from configs.config import Config
import nonebot import nonebot
Config.add_plugin_config( Config.add_plugin_config(
"hook", "hook",
"CHECK_NOTICE_INFO_CD", "CHECK_NOTICE_INFO_CD",
300, 300,
name="基础hook配置", name="基础hook配置",
help_="群检测,个人权限检测等各种检测提示信息cd", help_="群检测,个人权限检测等各种检测提示信息cd",
default_value=300 default_value=300
) )
Config.add_plugin_config( Config.add_plugin_config(
"hook", "hook",
"MALICIOUS_BAN_TIME", "MALICIOUS_BAN_TIME",
30, 30,
help_="恶意命令触发检测触发后ban的时长(分钟)", help_="恶意命令触发检测触发后ban的时长(分钟)",
default_value=30 default_value=30
) )
Config.add_plugin_config( Config.add_plugin_config(
"hook", "hook",
"MALICIOUS_CHECK_TIME", "MALICIOUS_CHECK_TIME",
5, 5,
help_="恶意命令触发检测规定时间内(秒)", help_="恶意命令触发检测规定时间内(秒)",
default_value=5 default_value=5
) )
Config.add_plugin_config( Config.add_plugin_config(
"hook", "hook",
"MALICIOUS_BAN_COUNT", "MALICIOUS_BAN_COUNT",
6, 6,
help_="恶意命令触发检测最大触发次数", help_="恶意命令触发检测最大触发次数",
default_value=6 default_value=6
) )
nonebot.load_plugins("basic_plugins/hooks") nonebot.load_plugins("basic_plugins/hooks")
Regular → Executable
+210 -210
View File
@@ -1,210 +1,210 @@
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.cqhttp.exception import ActionFailed
from utils.manager import ( from utils.manager import (
plugins2settings_manager, plugins2settings_manager,
admin_manager, admin_manager,
group_manager, group_manager,
plugins_manager, plugins_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 nonebot.adapters.cqhttp import ( from nonebot.adapters.cqhttp import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent, GroupMessageEvent,
PokeNotifyEvent, PokeNotifyEvent,
) )
from configs.config import Config from configs.config import Config
from models.ban_user import BanUser from models.ban_user import BanUser
from utils.utils import FreqLimiter from utils.utils import FreqLimiter
from utils.message_builder import at from utils.message_builder import at
from models.level_user import LevelUser from models.level_user import LevelUser
_flmt = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
_flmt_g = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_g = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
_flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
_flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
ignore_rst_module = ["ai", "poke", "dialogue"] 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.module
plugins2info_dict = plugins2settings_manager.get_data() plugins2info_dict = plugins2settings_manager.get_data()
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
# 群黑名单检测 # 群黑名单检测
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
if group_manager.get_group_level(event.group_id) < 0: if group_manager.get_group_level(event.group_id) < 0:
raise IgnoredException("群黑名单") raise IgnoredException("群黑名单")
if module in admin_manager.keys() and matcher.priority not in [1, 9]: if module in admin_manager.keys() and matcher.priority not in [1, 9]:
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):
_flmt.start_cd(event.user_id) _flmt.start_cd(event.user_id)
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
set_block_limit_false(event, module) set_block_limit_false(event, module)
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.group_id) status_message_manager.add(event.group_id)
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(
user_id=event.user_id, user_id=event.user_id,
message=f"你的权限不足喔,该功能需要的权限等级:{admin_manager.get_plugin_level(module)}", message=f"你的权限不足喔,该功能需要的权限等级:{admin_manager.get_plugin_level(module)}",
) )
except ActionFailed: except ActionFailed:
pass pass
set_block_limit_false(event, module) set_block_limit_false(event, module)
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.user_id) status_message_manager.add(event.user_id)
raise IgnoredException("权限不足") raise IgnoredException("权限不足")
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:
_flmt_g.start_cd(event.user_id) _flmt_g.start_cd(event.user_id)
await bot.send_group_msg( await bot.send_group_msg(
group_id=event.group_id, message="群权限不足..." group_id=event.group_id, message="群权限不足..."
) )
except ActionFailed: except ActionFailed:
pass pass
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.group_id) status_message_manager.add(event.group_id)
set_block_limit_false(event, module) set_block_limit_false(event, module)
raise IgnoredException("群权限不足") raise IgnoredException("群权限不足")
# 插件状态 # 插件状态
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(
group_id=event.group_id, message="该群未开启此功能.." group_id=event.group_id, message="该群未开启此功能.."
) )
except ActionFailed: except ActionFailed:
pass pass
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.group_id) status_message_manager.add(event.group_id)
set_block_limit_false(event, module) set_block_limit_false(event, module)
raise IgnoredException("未开启此功能...") raise IgnoredException("未开启此功能...")
# 管理员禁用 # 管理员禁用
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(
group_id=event.group_id, message="管理员禁用了此群该功能..." group_id=event.group_id, message="管理员禁用了此群该功能..."
) )
except ActionFailed: except ActionFailed:
pass pass
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.group_id) status_message_manager.add(event.group_id)
set_block_limit_false(event, module) set_block_limit_false(event, module)
raise IgnoredException("管理员禁用了此群该功能...") raise IgnoredException("管理员禁用了此群该功能...")
# 群聊禁用 # 群聊禁用
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(
group_id=event.group_id, message="该功能在群聊中已被禁用..." group_id=event.group_id, message="该功能在群聊中已被禁用..."
) )
except ActionFailed: except ActionFailed:
pass pass
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.group_id) status_message_manager.add(event.group_id)
set_block_limit_false(event, module) set_block_limit_false(event, module)
raise IgnoredException("该插件在群聊中已被禁用...") raise IgnoredException("该插件在群聊中已被禁用...")
else: else:
# 私聊禁用 # 私聊禁用
if not plugins_manager.get_plugin_status(module, block_type="private"): if not plugins_manager.get_plugin_status(module, block_type="private"):
try: try:
if _flmt_c.check(event.user_id): if _flmt_c.check(event.user_id):
_flmt_c.start_cd(event.user_id) _flmt_c.start_cd(event.user_id)
await bot.send_private_msg( await bot.send_private_msg(
user_id=event.user_id, message="该功能在私聊中已被禁用..." user_id=event.user_id, message="该功能在私聊中已被禁用..."
) )
except ActionFailed: except ActionFailed:
pass pass
if event.is_tome(): if event.is_tome():
status_message_manager.add(event.user_id) status_message_manager.add(event.user_id)
set_block_limit_false(event, module) set_block_limit_false(event, module)
raise IgnoredException("该插件在私聊中已被禁用...") raise IgnoredException("该插件在私聊中已被禁用...")
# 维护 # 维护
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(
group_id=event.group_id, message="此功能正在维护..." group_id=event.group_id, message="此功能正在维护..."
) )
else: else:
await bot.send_private_msg( await bot.send_private_msg(
user_id=event.user_id, message="此功能正在维护..." user_id=event.user_id, message="此功能正在维护..."
) )
except ActionFailed: except ActionFailed:
pass pass
if event.is_tome(): if event.is_tome():
id_ = ( id_ = (
event.group_id event.group_id
if isinstance(event, GroupMessageEvent) if isinstance(event, GroupMessageEvent)
else event.user_id else event.user_id
) )
status_message_manager.add(id_) status_message_manager.add(id_)
set_block_limit_false(event, module) set_block_limit_false(event, module)
raise IgnoredException("此功能正在维护...") raise IgnoredException("此功能正在维护...")
Regular → Executable
+82 -82
View File
@@ -1,83 +1,83 @@
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.cqhttp.exception import ActionFailed
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import ( from nonebot.adapters.cqhttp import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent, GroupMessageEvent,
) )
from configs.config import Config from configs.config import Config
from models.ban_user import BanUser from models.ban_user import BanUser
from utils.utils import is_number, static_flmt from utils.utils import is_number, static_flmt
from utils.message_builder import at from utils.message_builder import at
Config.add_plugin_config( Config.add_plugin_config(
"hook", "hook",
"BAN_RESULT", "BAN_RESULT",
"才不会给你发消息.", "才不会给你发消息.",
help_="对被ban用户发送的消息", help_="对被ban用户发送的消息",
) )
# 检查是否被ban # 检查是否被ban
@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):
try: try:
if ( if (
await BanUser.is_super_ban(event.user_id) await BanUser.is_super_ban(event.user_id)
and str(event.user_id) not in bot.config.superusers and str(event.user_id) not in bot.config.superusers
): ):
raise IgnoredException("用户处于超级黑名单中") raise IgnoredException("用户处于超级黑名单中")
except AttributeError: except AttributeError:
pass pass
if not isinstance(event, MessageEvent): if not isinstance(event, MessageEvent):
return return
if matcher.type == "message" and matcher.priority not in [1, 9]: if matcher.type == "message" and matcher.priority not in [1, 9]:
if ( if (
await BanUser.is_ban(event.user_id) 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
): ):
time = await BanUser.check_ban_time(event.user_id) time = await BanUser.check_ban_time(event.user_id)
if is_number(time): if is_number(time):
time = abs(int(time)) time = abs(int(time))
if time < 60: if time < 60:
time = str(time) + " 秒" time = str(time) + " 秒"
else: else:
time = str(int(time / 60)) + " 分钟" time = str(int(time / 60)) + " 分钟"
else: else:
time = str(time) + " 分钟" time = str(time) + " 分钟"
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
if not static_flmt.check(event.user_id): if not static_flmt.check(event.user_id):
raise IgnoredException("用户处于黑名单中") raise IgnoredException("用户处于黑名单中")
static_flmt.start_cd(event.user_id) static_flmt.start_cd(event.user_id)
if matcher.priority != 9: if matcher.priority != 9:
try: try:
ban_result = Config.get_config("hook", "BAN_RESULT") ban_result = Config.get_config("hook", "BAN_RESULT")
if ban_result: if ban_result:
await bot.send_group_msg( await bot.send_group_msg(
group_id=event.group_id, group_id=event.group_id,
message=at(event.user_id) message=at(event.user_id)
+ ban_result + ban_result
+ f" 在..在 {time} 后才会理你喔", + f" 在..在 {time} 后才会理你喔",
) )
except ActionFailed: except ActionFailed:
pass pass
else: else:
if not static_flmt.check(event.user_id): if not static_flmt.check(event.user_id):
raise IgnoredException("用户处于黑名单中") raise IgnoredException("用户处于黑名单中")
static_flmt.start_cd(event.user_id) static_flmt.start_cd(event.user_id)
if matcher.priority != 9: if matcher.priority != 9:
try: try:
ban_result = Config.get_config("hook", "BAN_RESULT") ban_result = Config.get_config("hook", "BAN_RESULT")
if ban_result: if ban_result:
await bot.send_private_msg( await bot.send_private_msg(
user_id=event.user_id, user_id=event.user_id,
message=at(event.user_id) message=at(event.user_id)
+ ban_result + ban_result
+ f" 在..在 {time}后才会理你喔", + f" 在..在 {time}后才会理你喔",
) )
except ActionFailed: except ActionFailed:
pass pass
raise IgnoredException("用户处于黑名单中") raise IgnoredException("用户处于黑名单中")
+54 -54
View File
@@ -1,54 +1,54 @@
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.cqhttp.exception import ActionFailed
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import ( from nonebot.adapters.cqhttp import (
Bot, Bot,
MessageEvent, MessageEvent,
GroupMessageEvent, GroupMessageEvent,
) )
from configs.config import Config from configs.config import Config
from models.ban_user import BanUser from models.ban_user import BanUser
from utils.utils import BanCheckLimiter from utils.utils import BanCheckLimiter
from utils.message_builder import at from utils.message_builder import at
from services.log import logger from services.log import logger
_blmt = BanCheckLimiter( _blmt = BanCheckLimiter(
Config.get_config("hook", "MALICIOUS_CHECK_TIME"), Config.get_config("hook", "MALICIOUS_CHECK_TIME"),
Config.get_config("hook", "MALICIOUS_BAN_COUNT"), Config.get_config("hook", "MALICIOUS_BAN_COUNT"),
) )
# 恶意触发命令检测 # 恶意触发命令检测
@run_preprocessor @run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: GroupMessageEvent, state: T_State): async def _(matcher: Matcher, bot: Bot, event: GroupMessageEvent, state: T_State):
if not isinstance(event, MessageEvent): if not isinstance(event, MessageEvent):
return return
if matcher.type == "message" and matcher.priority not in [1, 9]: if matcher.type == "message" and matcher.priority not in [1, 9]:
if state["_prefix"]["raw_command"]: if state["_prefix"]["raw_command"]:
if _blmt.check(f'{event.user_id}{state["_prefix"]["raw_command"]}'): if _blmt.check(f'{event.user_id}{state["_prefix"]["raw_command"]}'):
if await BanUser.ban( if await BanUser.ban(
event.user_id, event.user_id,
9, 9,
Config.get_config("hook", "MALICIOUS_BAN_TIME") * 60, Config.get_config("hook", "MALICIOUS_BAN_TIME") * 60,
): ):
logger.info(f"USER {event.user_id} 触发了恶意触发检测") logger.info(f"USER {event.user_id} 触发了恶意触发检测")
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
try: try:
await bot.send_group_msg( await bot.send_group_msg(
group_id=event.group_id, group_id=event.group_id,
message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟", message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟",
) )
except ActionFailed: except ActionFailed:
pass pass
else: else:
try: try:
await bot.send_private_msg( await bot.send_private_msg(
user_id=event.user_id, user_id=event.user_id,
message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟", message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟",
) )
except ActionFailed: except ActionFailed:
pass pass
raise IgnoredException("检测到恶意触发命令") raise IgnoredException("检测到恶意触发命令")
_blmt.add(f'{event.user_id}{state["_prefix"]["raw_command"]}') _blmt.add(f'{event.user_id}{state["_prefix"]["raw_command"]}')
+146 -146
View File
@@ -1,146 +1,146 @@
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.cqhttp.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 utils.message_builder import at from utils.message_builder import at
from .utils import status_message_manager, set_block_limit_false from .utils import status_message_manager, set_block_limit_false
from utils.manager import ( from utils.manager import (
plugins2cd_manager, plugins2cd_manager,
plugins2block_manager, plugins2block_manager,
plugins2count_manager, plugins2count_manager,
) )
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 ( from nonebot.adapters.cqhttp import (
Bot, Bot,
Event, Event,
MessageEvent, MessageEvent,
PrivateMessageEvent, PrivateMessageEvent,
GroupMessageEvent, GroupMessageEvent,
Message, Message,
) )
# 命令cd | 命令阻塞 | 命令次数 # 命令cd | 命令阻塞 | 命令次数
@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):
if not isinstance(event, MessageEvent) and matcher.module != "poke": if not isinstance(event, MessageEvent) and matcher.module != "poke":
return return
module = matcher.module module = matcher.module
if ( if (
isinstance(event, GroupMessageEvent) isinstance(event, GroupMessageEvent)
and status_message_manager.get(event.group_id) is None and status_message_manager.get(event.group_id) is None
): ):
status_message_manager.delete(event.group_id) status_message_manager.delete(event.group_id)
# 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"]
rst = plugin_count_data["rst"] rst = plugin_count_data["rst"]
count_type_ = event.user_id count_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent): if limit_type == "group" and isinstance(event, GroupMessageEvent):
count_type_ = event.group_id count_type_ = event.group_id
if not plugins2count_manager.check(module, count_type_): if not plugins2count_manager.check(module, count_type_):
if rst: if rst:
rst = await init_rst(rst, event) rst = await init_rst(rst, event)
await send_msg(rst, bot, event) await send_msg(rst, bot, event)
raise IgnoredException(f"{module} count次数限制...") raise IgnoredException(f"{module} count次数限制...")
else: else:
plugins2count_manager.increase(module, count_type_) plugins2count_manager.increase(module, count_type_)
# 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)
check_type = plugin_cd_data["check_type"] check_type = plugin_cd_data["check_type"]
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 cd_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent): if limit_type == "group" and isinstance(event, GroupMessageEvent):
cd_type_ = event.group_id cd_type_ = event.group_id
if not plugins2cd_manager.check(module, cd_type_): if not plugins2cd_manager.check(module, cd_type_):
if rst: if rst:
rst = await init_rst(rst, event) rst = await init_rst(rst, event)
await send_msg(rst, bot, event) await send_msg(rst, bot, event)
raise IgnoredException(f"{module} 正在cd中...") raise IgnoredException(f"{module} 正在cd中...")
else: else:
plugins2cd_manager.start_cd(module, cd_type_) plugins2cd_manager.start_cd(module, cd_type_)
# Block # Block
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"]
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):
block_type_ = event.group_id block_type_ = event.group_id
if plugins2block_manager.check(block_type_, module): if plugins2block_manager.check(block_type_, module):
if rst: if rst:
rst = await init_rst(rst, event) rst = await init_rst(rst, event)
await send_msg(rst, bot, event) await send_msg(rst, bot, event)
raise IgnoredException(f"{event.user_id}正在调用{module}....") raise IgnoredException(f"{event.user_id}正在调用{module}....")
else: else:
plugins2block_manager.set_true(block_type_, module) plugins2block_manager.set_true(block_type_, module)
async def send_msg(rst: str, bot: Bot, event: MessageEvent): async def send_msg(rst: str, bot: Bot, event: MessageEvent):
""" """
发送信息 发送信息
:param rst: pass :param rst: pass
:param bot: pass :param bot: pass
:param event: pass :param event: pass
""" """
rst = await init_rst(rst, event) rst = await init_rst(rst, event)
try: try:
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
status_message_manager.add(event.group_id) status_message_manager.add(event.group_id)
await bot.send_group_msg(group_id=event.group_id, message=Message(rst)) await bot.send_group_msg(group_id=event.group_id, message=Message(rst))
else: else:
status_message_manager.add(event.user_id) status_message_manager.add(event.user_id)
await bot.send_private_msg(user_id=event.user_id, message=Message(rst)) await bot.send_private_msg(user_id=event.user_id, message=Message(rst))
except ActionFailed: except ActionFailed:
pass pass
# 解除命令block阻塞 # 解除命令block阻塞
@run_postprocessor @run_postprocessor
async def _( async def _(
matcher: Matcher, matcher: Matcher,
exception: Optional[Exception], exception: Optional[Exception],
bot: Bot, bot: Bot,
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.module != "poke":
return return
module = matcher.module module = matcher.module
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 if event.sender.card else 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):
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
) )
else: else:
nickname = await FriendUser.get_friend_nickname(event.user_id) nickname = await FriendUser.get_friend_nickname(event.user_id)
rst = rst.replace("[nickname]", nickname) rst = rst.replace("[nickname]", nickname)
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
+41 -41
View File
@@ -1,41 +1,41 @@
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.cqhttp import (
Bot, Bot,
MessageEvent, MessageEvent,
PrivateMessageEvent, PrivateMessageEvent,
GroupMessageEvent, GroupMessageEvent,
) )
# 为什么AI会自己和自己聊天 # 为什么AI会自己和自己聊天
@run_preprocessor @run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(matcher: Matcher, bot: Bot, event: PrivateMessageEvent, state: T_State):
if not isinstance(event, MessageEvent): if not isinstance(event, MessageEvent):
return return
if event.user_id == int(bot.self_id): if event.user_id == int(bot.self_id):
raise IgnoredException("为什么AI会自己和自己聊天") raise IgnoredException("为什么AI会自己和自己聊天")
# 有命令就别说话了 # 有命令就别说话了
@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):
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.module == "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)
): ):
status_message_manager.delete(event.group_id) status_message_manager.delete(event.group_id)
raise IgnoredException("有命令就别说话了") raise IgnoredException("有命令就别说话了")
elif ( elif (
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) print(status_message_manager)
status_message_manager.delete(event.user_id) status_message_manager.delete(event.user_id)
raise IgnoredException("有命令就别说话了") raise IgnoredException("有命令就别说话了")
Regular → Executable
+48 -48
View File
@@ -1,48 +1,48 @@
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.cqhttp 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)
+28 -28
View File
@@ -1,28 +1,28 @@
from nonebot.matcher import Matcher 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.cqhttp import Bot, Event
from utils.manager import withdraw_message_manager from utils.manager import withdraw_message_manager
import asyncio import asyncio
# 消息撤回 # 消息撤回
@run_postprocessor @run_postprocessor
async def _( async def _(
matcher: Matcher, matcher: Matcher,
exception: Optional[Exception], exception: Optional[Exception],
bot: Bot, bot: Bot,
event: Event, event: Event,
state: T_State, state: T_State,
): ):
tasks = [] tasks = []
for id_, time in withdraw_message_manager.data: for id_, time in withdraw_message_manager.data:
tasks.append(asyncio.ensure_future(_withdraw_message(bot, id_, time))) tasks.append(asyncio.ensure_future(_withdraw_message(bot, id_, time)))
withdraw_message_manager.remove((id_, time)) withdraw_message_manager.remove((id_, time))
await asyncio.gather(*tasks) await asyncio.gather(*tasks)
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_, self_id=int(bot.self_id))
+9
View File
@@ -9,10 +9,12 @@ from .init_plugins_limit import (
init_plugins_count_limit, init_plugins_count_limit,
init_plugins_cd_limit, init_plugins_cd_limit,
) )
from .init import init
from .check_plugin_status import check_plugin_status from .check_plugin_status import check_plugin_status
from nonebot.adapters.cqhttp 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 nonebot import Driver from nonebot import Driver
import nonebot import nonebot
@@ -30,6 +32,11 @@ def _():
""" """
初始化数据 初始化数据
""" """
_flag = False
config_file = Path(DATA_PATH) / "configs" / "plugins2config.yaml"
if not config_file.exists():
_flag = True
init()
init_plugins_settings(DATA_PATH) init_plugins_settings(DATA_PATH)
init_plugins_cd_limit(DATA_PATH) init_plugins_cd_limit(DATA_PATH)
init_plugins_block_limit(DATA_PATH) init_plugins_block_limit(DATA_PATH)
@@ -42,6 +49,8 @@ def _():
if x: if x:
for key in x.keys(): for key in x.keys():
plugins_manager.block_plugin(key, block_type=x[key]) plugins_manager.block_plugin(key, block_type=x[key])
if _flag:
raise Exception("首次运行,已在configs目录下生成配置文件config.yaml,修改后重启即可...")
logger.info("初始化数据完成...") logger.info("初始化数据完成...")
+18 -18
View File
@@ -1,18 +1,18 @@
from utils.manager import plugins_manager from utils.manager import plugins_manager
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
async def check_plugin_status(bot: Bot): async def check_plugin_status(bot: Bot):
""" """
遍历查看插件加载情况 遍历查看插件加载情况
""" """
rst = "" rst = ""
for plugin in plugins_manager.keys(): for plugin in plugins_manager.keys():
data = plugins_manager.get(plugin) data = plugins_manager.get(plugin)
if data.get("error") or data.get("error") is None: if data.get("error") or data.get("error") is None:
rst += f'{plugin}:{data["plugin_name"]}\n' rst += f'{plugin}:{data["plugin_name"]}\n'
if rst: if rst:
rst = "以下插件加载失败..\n" + rst rst = "以下插件加载失败..\n" + rst
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=rst[:-1] user_id=int(list(bot.config.superusers)[0]), message=rst[:-1]
) )
+14
View File
@@ -0,0 +1,14 @@
from utils.manager import plugins2settings_manager
def init():
if plugins2settings_manager.get("update_pic"):
plugins2settings_manager["update_picture"] = plugins2settings_manager["update_pic"]
plugins2settings_manager.delete("update_pic")
if plugins2settings_manager.get("white2black_img"):
plugins2settings_manager["white2black_image"] = plugins2settings_manager["white2black_img"]
plugins2settings_manager.delete("white2black_img")
if plugins2settings_manager.get("send_img"):
plugins2settings_manager["send_image"] = plugins2settings_manager["send_img"]
plugins2settings_manager.delete("send_img")
+73 -73
View File
@@ -1,73 +1,73 @@
from pathlib import Path from pathlib import Path
from utils.manager import group_manager from utils.manager import group_manager
from services.db_context import db from services.db_context import db
from asyncpg.exceptions import DuplicateColumnError from asyncpg.exceptions import DuplicateColumnError
from services.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
try: try:
from models.group_remind import GroupRemind from models.group_remind import GroupRemind
except ModuleNotFoundError: except ModuleNotFoundError:
pass pass
async def init_group_manager(): async def init_group_manager():
""" """
旧数据格式替换为新格式 旧数据格式替换为新格式
初始化数据 初始化数据
""" """
old_group_level_file = Path() / "data" / "manager" / "group_level.json" old_group_level_file = Path() / "data" / "manager" / "group_level.json"
old_plugin_list_file = Path() / "data" / "manager" / "plugin_list.json" old_plugin_list_file = Path() / "data" / "manager" / "plugin_list.json"
if old_group_level_file.exists(): if old_group_level_file.exists():
data = json.load(open(old_group_level_file, "r", encoding="utf8")) data = json.load(open(old_group_level_file, "r", encoding="utf8"))
for key in data.keys(): for key in data.keys():
group = key group = key
level = data[key] level = data[key]
group_manager.set_group_level(group, level) group_manager.set_group_level(group, level)
old_group_level_file.unlink() old_group_level_file.unlink()
group_manager.save() group_manager.save()
if old_plugin_list_file.exists(): if old_plugin_list_file.exists():
data = json.load(open(old_plugin_list_file, "r", encoding="utf8")) data = json.load(open(old_plugin_list_file, "r", encoding="utf8"))
for plugin in data.keys(): for plugin in data.keys():
for group in data[plugin].keys(): for group in data[plugin].keys():
if group == "default" and not data[plugin]["default"]: if group == "default" and not data[plugin]["default"]:
group_manager.block_plugin(plugin) group_manager.block_plugin(plugin)
elif not data[plugin][group]: elif not data[plugin][group]:
group_manager.block_plugin(plugin, group) group_manager.block_plugin(plugin, group)
old_plugin_list_file.unlink() old_plugin_list_file.unlink()
old_data_table = Path() / "models" / "group_remind.py" old_data_table = Path() / "models" / "group_remind.py"
try: try:
if old_data_table.exists(): if old_data_table.exists():
b = { b = {
"hy": "group_welcome", "hy": "group_welcome",
"kxcz": "open_case_reset_remind", "kxcz": "open_case_reset_remind",
"zwa": "zwa", "zwa": "zwa",
"blpar": "bilibili_parse", "blpar": "bilibili_parse",
"epic": "epic_free_game", "epic": "epic_free_game",
"pa": "pa", "pa": "pa",
"almanac": "genshin_alc", "almanac": "genshin_alc",
} }
for group in group_manager.get_data()["group_manager"]: for group in group_manager.get_data()["group_manager"]:
for remind in b: for remind in b:
try: try:
status = await GroupRemind.get_status(int(group), remind) status = await GroupRemind.get_status(int(group), remind)
if status is not None: if status is not None:
if status: if status:
await group_manager.open_group_task(group, b[remind]) await group_manager.open_group_task(group, b[remind])
logger.info(f"读取旧数据-->{group} 开启 {b[remind]}") logger.info(f"读取旧数据-->{group} 开启 {b[remind]}")
else: else:
await group_manager.close_group_task(group, b[remind]) await group_manager.close_group_task(group, b[remind])
logger.info(f"读取旧数据-->{group} 关闭 {b[remind]}") logger.info(f"读取旧数据-->{group} 关闭 {b[remind]}")
except Exception as e: except Exception as e:
pass pass
query = db.text("DROP TABLE group_reminds;") query = db.text("DROP TABLE group_reminds;")
await db.first(query) await db.first(query)
old_data_table.unlink() old_data_table.unlink()
logger.info("旧数据读取完毕,删除了舍弃表 group_reminds...") logger.info("旧数据读取完毕,删除了舍弃表 group_reminds...")
except (ModuleNotFoundError, DuplicateColumnError): except (ModuleNotFoundError, DuplicateColumnError):
pass pass
group_manager.save() group_manager.save()
+45 -45
View File
@@ -1,45 +1,45 @@
from utils.manager import ( from utils.manager import (
none_plugin_count_manager, none_plugin_count_manager,
plugins2count_manager, plugins2count_manager,
plugins2cd_manager, plugins2cd_manager,
plugins2settings_manager, plugins2settings_manager,
plugins2block_manager, plugins2block_manager,
plugins_manager, plugins_manager,
resources_manager resources_manager
) )
from services.log import logger from services.log import logger
from utils.utils import get_matchers from utils.utils import get_matchers
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
def init_none_plugin_count_manager(): def init_none_plugin_count_manager():
""" """
清除已删除插件数据 清除已删除插件数据
""" """
modules = [x.module for x in get_matchers()] modules = [x.module for x in get_matchers()]
for module in none_plugin_count_manager.keys(): for module in none_plugin_count_manager.keys():
if module not in modules: if module not in modules:
none_plugin_count_manager.add_count(module) none_plugin_count_manager.add_count(module)
else: else:
none_plugin_count_manager.reset(module) none_plugin_count_manager.reset(module)
if none_plugin_count_manager.check(module): if none_plugin_count_manager.check(module):
try: try:
plugin_name = plugins_manager.get(module)["plugin_name"] plugin_name = plugins_manager.get(module)["plugin_name"]
except (AttributeError, KeyError): except (AttributeError, KeyError):
plugin_name = "" plugin_name = ""
try: try:
plugins2settings_manager.delete(module) plugins2settings_manager.delete(module)
plugins2count_manager.delete(module) plugins2count_manager.delete(module)
plugins2cd_manager.delete(module) plugins2cd_manager.delete(module)
plugins2block_manager.delete(module) plugins2block_manager.delete(module)
plugins_manager.delete(module) plugins_manager.delete(module)
resources_manager.remove_resource(module) resources_manager.remove_resource(module)
logger.info(f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据...") logger.info(f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据...")
except Exception as e: except Exception as e:
logger.error( logger.error(
f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据失败...{type(e)}:{e}" f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据失败...{type(e)}:{e}"
) )
+147 -147
View File
@@ -1,147 +1,147 @@
from pathlib import Path from pathlib import Path
from ruamel.yaml import round_trip_load, round_trip_dump, YAML from ruamel.yaml import round_trip_load, round_trip_dump, YAML
from utils.manager import admin_manager, plugins_manager from utils.manager import admin_manager, plugins_manager
from configs.config import Config from configs.config import Config
from services.log import logger from services.log import logger
from utils.utils import get_matchers from utils.utils import get_matchers
from ruamel import yaml from ruamel import yaml
import nonebot import nonebot
_yaml = YAML(typ="safe") _yaml = YAML(typ="safe")
def init_plugins_config(data_path): def init_plugins_config(data_path):
""" """
初始化插件数据配置 初始化插件数据配置
""" """
plugins2config_file = Path(data_path) / "configs" / "plugins2config.yaml" plugins2config_file = Path(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.module)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
continue continue
try: try:
plugin_version = _module.__getattribute__("__plugin_version__") plugin_version = _module.__getattribute__("__plugin_version__")
except AttributeError: except AttributeError:
plugin_version = None plugin_version = None
try: try:
plugin_configs = _module.__getattribute__("__plugin_configs__") plugin_configs = _module.__getattribute__("__plugin_configs__")
except AttributeError: except AttributeError:
continue continue
# 插件配置版本更新或为Version为None或不在存储配置内 # 插件配置版本更新或为Version为None或不在存储配置内
if ( if (
plugin_version is None plugin_version is None
or ( or (
_data.get(matcher.module) _data.get(matcher.module)
and _data[matcher.module].keys() != plugin_configs.keys() and _data[matcher.module].keys() != plugin_configs.keys()
) )
or plugin_version > plugins_manager.get(matcher.module)["version"] or plugin_version > plugins_manager.get(matcher.module)["version"]
or matcher.module not in _data.keys() or matcher.module 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.module,
key, key,
plugin_configs[key].get("value"), plugin_configs[key].get("value"),
help_=plugin_configs[key].get("help"), help_=plugin_configs[key].get("help"),
default_value=plugin_configs[key].get("default_value"), default_value=plugin_configs[key].get("default_value"),
_override=True, _override=True,
) )
else: else:
Config.add_plugin_config(matcher.module, key, plugin_configs[key]) Config.add_plugin_config(matcher.module, key, plugin_configs[key])
else: else:
plugin_configs = _data[matcher.module] plugin_configs = _data[matcher.module]
for key in plugin_configs: for key in plugin_configs:
Config.add_plugin_config( Config.add_plugin_config(
matcher.module, matcher.module,
key, key,
plugin_configs[key]["value"], plugin_configs[key]["value"],
help_=plugin_configs[key]["help"], help_=plugin_configs[key]["help"],
default_value=plugin_configs[key]["default_value"], default_value=plugin_configs[key]["default_value"],
_override=True, _override=True,
) )
if not Config.is_empty(): if not Config.is_empty():
Config.save() Config.save()
_data = round_trip_load(open(plugins2config_file, encoding="utf8")) _data = round_trip_load(open(plugins2config_file, encoding="utf8"))
for plugin in _data.keys(): for plugin in _data.keys():
try: try:
plugin_name = plugins_manager.get(plugin)["plugin_name"] plugin_name = plugins_manager.get(plugin)["plugin_name"]
except (AttributeError, TypeError): except (AttributeError, TypeError):
plugin_name = plugin plugin_name = plugin
_data[plugin].yaml_set_start_comment(plugin_name, indent=2) _data[plugin].yaml_set_start_comment(plugin_name, indent=2)
# 初始化未设置的管理员权限等级 # 初始化未设置的管理员权限等级
for k, v in Config.get_admin_level_data(): for k, v in Config.get_admin_level_data():
admin_manager.set_admin_level(k, v) admin_manager.set_admin_level(k, v)
# 存完插件基本设置 # 存完插件基本设置
with open(plugins2config_file, "w", encoding="utf8") as wf: with open(plugins2config_file, "w", encoding="utf8") as wf:
round_trip_dump( round_trip_dump(
_data, wf, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True _data, wf, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True
) )
# 再开始读取用户配置 # 再开始读取用户配置
user_config_file = Path() / "configs" / "config.yaml" user_config_file = Path() / "configs" / "config.yaml"
_data = {} _data = {}
_tmp_data = {} _tmp_data = {}
if user_config_file.exists(): if user_config_file.exists():
with open(user_config_file, "r", encoding="utf8") as f: with open(user_config_file, "r", encoding="utf8") as f:
_data = _yaml.load(f) _data = _yaml.load(f)
for plugin in Config.keys(): for plugin in Config.keys():
_tmp_data[plugin] = {} _tmp_data[plugin] = {}
for k in Config[plugin].keys(): for k in Config[plugin].keys():
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])
_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"
try: try:
with open(temp_file, "w", encoding="utf8") as wf: with open(temp_file, "w", encoding="utf8") as wf:
yaml.dump( yaml.dump(
_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True _tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True
) )
with open(temp_file, "r", encoding="utf8") as rf: with open(temp_file, "r", encoding="utf8") as rf:
_data = round_trip_load(rf) _data = round_trip_load(rf)
# 添加注释 # 添加注释
for plugin in _data.keys(): for plugin in _data.keys():
rst = "" rst = ""
plugin_name = None plugin_name = None
try: try:
plugin_data = Config.get(plugin) plugin_data = Config.get(plugin)
for x in list(Config.get(plugin).keys()): for x in list(Config.get(plugin).keys()):
try: try:
_x = plugin_data[x].get("name") _x = plugin_data[x].get("name")
if _x: if _x:
plugin_name = _x plugin_name = _x
except AttributeError: except AttributeError:
pass pass
except (KeyError, AttributeError): except (KeyError, AttributeError):
plugin_name = None plugin_name = None
if not plugin_name: if not plugin_name:
try: try:
plugin_name = plugins_manager.get(plugin)["plugin_name"] plugin_name = plugins_manager.get(plugin)["plugin_name"]
except (AttributeError, TypeError): except (AttributeError, TypeError):
plugin_name = plugin plugin_name = plugin
plugin_name = ( plugin_name = (
plugin_name.replace("[Hidden]", "") plugin_name.replace("[Hidden]", "")
.replace("[Superuser]", "") .replace("[Superuser]", "")
.replace("[Admin]", "") .replace("[Admin]", "")
.strip() .strip()
) )
rst += plugin_name + "\n" rst += plugin_name + "\n"
for k in _data[plugin].keys(): for k in _data[plugin].keys():
rst += f'{k}: {Config[plugin][k]["help"]}' + "\n" rst += f'{k}: {Config[plugin][k]["help"]}' + "\n"
_data[plugin].yaml_set_start_comment(rst[:-1], indent=2) _data[plugin].yaml_set_start_comment(rst[:-1], indent=2)
with open(Path() / "configs" / "config.yaml", "w", encoding="utf8") as wf: with open(Path() / "configs" / "config.yaml", "w", encoding="utf8") as wf:
round_trip_dump( round_trip_dump(
_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True _data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True
) )
except Exception as e: except Exception as e:
logger.error(f"生成简易配置注释错误 {type(e)}:{e}") logger.error(f"生成简易配置注释错误 {type(e)}:{e}")
if temp_file.exists(): if temp_file.exists():
temp_file.unlink() temp_file.unlink()
+82 -82
View File
@@ -1,82 +1,82 @@
from pathlib import Path from pathlib import Path
from ruamel.yaml import YAML from ruamel.yaml import YAML
from utils.manager import plugins_manager from utils.manager import plugins_manager
from utils.utils import get_matchers from utils.utils import get_matchers
import nonebot import nonebot
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
_yaml = YAML(typ="safe") _yaml = YAML(typ="safe")
def init_plugins_data(data_path): def init_plugins_data(data_path):
""" """
初始化插件数据信息 初始化插件数据信息
""" """
plugin2data_file = Path(data_path) / "manager" / "plugin_manager.json" plugin2data_file = Path(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.module)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
if matcher.module not in _data.keys(): if matcher.module not in _data.keys():
plugins_manager.add_plugin_data( plugins_manager.add_plugin_data(
matcher.module, matcher.module, error=True matcher.module, matcher.module, error=True
) )
else: else:
plugins_manager.set_module_data(matcher.module, "error", True) plugins_manager.set_module_data(matcher.module, "error", True)
plugin_data = plugins_manager.get(matcher.module) plugin_data = plugins_manager.get(matcher.module)
if plugin_data: if plugin_data:
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "version", plugin_data.get("version") matcher.module, "version", plugin_data.get("version")
) )
else: else:
try: try:
plugin_version = _module.__getattribute__("__plugin_version__") plugin_version = _module.__getattribute__("__plugin_version__")
except AttributeError: except AttributeError:
plugin_version = None plugin_version = None
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.module
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.module in plugins_manager.keys():
plugins_manager.set_module_data(matcher.module, "error", False) plugins_manager.set_module_data(matcher.module, "error", False)
if matcher.module not in plugins_manager.keys(): if matcher.module not in plugins_manager.keys():
plugins_manager.add_plugin_data( plugins_manager.add_plugin_data(
matcher.module, matcher.module,
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.module]["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.module]["version"]
): ):
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "plugin_name", plugin_name matcher.module, "plugin_name", plugin_name
) )
plugins_manager.set_module_data(matcher.module, "author", plugin_author) plugins_manager.set_module_data(matcher.module, "author", plugin_author)
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "version", plugin_version matcher.module, "version", plugin_version
) )
if matcher.module in _data.keys(): if matcher.module in _data.keys():
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "error", _data[matcher.module]["error"] matcher.module, "error", _data[matcher.module]["error"]
) )
plugins_manager.set_module_data( plugins_manager.set_module_data(
matcher.module, "plugin_name", _data[matcher.module]["plugin_name"] matcher.module, "plugin_name", _data[matcher.module]["plugin_name"]
) )
plugins_manager.save() plugins_manager.save()
+157 -157
View File
@@ -1,157 +1,157 @@
from pathlib import Path from pathlib import Path
from ruamel.yaml import round_trip_load, round_trip_dump, YAML from ruamel.yaml import round_trip_load, round_trip_dump, YAML
from utils.manager import ( from utils.manager import (
plugins2cd_manager, plugins2cd_manager,
plugins2block_manager, plugins2block_manager,
plugins2count_manager, plugins2count_manager,
) )
from utils.utils import get_matchers from utils.utils import get_matchers
from ruamel import yaml from ruamel import yaml
import nonebot import nonebot
_yaml = YAML(typ="safe") _yaml = YAML(typ="safe")
def init_plugins_cd_limit(data_path): def init_plugins_cd_limit(data_path):
""" """
加载 cd 限制 加载 cd 限制
""" """
plugins2cd_file = Path(data_path) / "configs" / "plugins2cd.yaml" plugins2cd_file = Path(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.module):
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.module)
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.module, data_dict=plugin_cd_limit
) )
except AttributeError: except AttributeError:
pass pass
if not plugins2cd_manager.keys(): if not plugins2cd_manager.keys():
plugins2cd_manager.add_cd_limit( plugins2cd_manager.add_cd_limit(
"这是一个示例" "这是一个示例"
) )
_tmp_data = {"PluginCdLimit": plugins2cd_manager.get_data()} _tmp_data = {"PluginCdLimit": plugins2cd_manager.get_data()}
with open(plugins2cd_file, "w", encoding="utf8") as wf: with open(plugins2cd_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)
_data = round_trip_load(open(plugins2cd_file, encoding="utf8")) _data = round_trip_load(open(plugins2cd_file, encoding="utf8"))
_data["PluginCdLimit"].yaml_set_start_comment( _data["PluginCdLimit"].yaml_set_start_comment(
"""# 需要cd的功能 """# 需要cd的功能
# 自定义的功能需要cd也可以在此配置 # 自定义的功能需要cd也可以在此配置
# key:模块名称 # key:模块名称
# cd:cd 时长(秒) # cd:cd 时长(秒)
# status:此限制的开关状态 # status:此限制的开关状态
# check_type:'private'/'group'/'all',限制私聊/群聊/全部 # check_type:'private'/'group'/'all',限制私聊/群聊/全部
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id # limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
# 示例:'user':用户N秒内触发1次,'group':群N秒内触发1次 # 示例:'user':用户N秒内触发1次,'group':群N秒内触发1次
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称 # rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
# rst 为 "" 或 None 时则不回复 # rst 为 "" 或 None 时则不回复
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]" # rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批" # rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""", # 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
indent=2, indent=2,
) )
with open(plugins2cd_file, "w", encoding="utf8") as wf: with open(plugins2cd_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True) round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
plugins2cd_manager.reload_cd_limit() plugins2cd_manager.reload_cd_limit()
def init_plugins_block_limit(data_path): def init_plugins_block_limit(data_path):
""" """
加载阻塞限制 加载阻塞限制
""" """
plugins2block_file = Path(data_path) / "configs" / "plugins2block.yaml" plugins2block_file = Path(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.module):
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.module)
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.module, data_dict=plugin_block_limit
) )
except AttributeError: except AttributeError:
pass pass
if not plugins2block_manager.keys(): if not plugins2block_manager.keys():
plugins2block_manager.add_block_limit( plugins2block_manager.add_block_limit(
"这是一个示例" "这是一个示例"
) )
_tmp_data = {"PluginBlockLimit": plugins2block_manager.get_data()} _tmp_data = {"PluginBlockLimit": plugins2block_manager.get_data()}
with open(plugins2block_file, "w", encoding="utf8") as wf: with open(plugins2block_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)
_data = round_trip_load(open(plugins2block_file, encoding="utf8")) _data = round_trip_load(open(plugins2block_file, encoding="utf8"))
_data["PluginBlockLimit"].yaml_set_start_comment( _data["PluginBlockLimit"].yaml_set_start_comment(
"""# 用户调用阻塞 """# 用户调用阻塞
# 即 当用户调用此功能还未结束时 # 即 当用户调用此功能还未结束时
# 用发送消息阻止用户重复调用此命令直到该命令结束 # 用发送消息阻止用户重复调用此命令直到该命令结束
# key:模块名称 # key:模块名称
# status:此限制的开关状态 # status:此限制的开关状态
# check_type:'private'/'group'/'all',限制私聊/群聊/全部 # check_type:'private'/'group'/'all',限制私聊/群聊/全部
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id # limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
# 示例:'user':阻塞用户,'group':阻塞群聊 # 示例:'user':阻塞用户,'group':阻塞群聊
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称 # rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
# rst 为 "" 或 None 时则不回复 # rst 为 "" 或 None 时则不回复
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]" # rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批" # rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""", # 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
indent=2, indent=2,
) )
with open(plugins2block_file, "w", encoding="utf8") as wf: with open(plugins2block_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True) round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
plugins2block_manager.reload_block_limit() plugins2block_manager.reload_block_limit()
def init_plugins_count_limit(data_path): def init_plugins_count_limit(data_path):
""" """
加载次数限制 加载次数限制
""" """
plugins2count_file = Path(data_path) / "configs" / "plugins2count.yaml" plugins2count_file = Path(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.module):
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.module)
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.module, data_dict=plugin_count_limit
) )
except AttributeError: except AttributeError:
pass pass
if not plugins2count_manager.keys(): if not plugins2count_manager.keys():
plugins2count_manager.add_count_limit( plugins2count_manager.add_count_limit(
"这是一个示例" "这是一个示例"
) )
_tmp_data = {"PluginCountLimit": plugins2count_manager.get_data()} _tmp_data = {"PluginCountLimit": plugins2count_manager.get_data()}
with open(plugins2count_file, "w", encoding="utf8") as wf: with open(plugins2count_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)
_data = round_trip_load(open(plugins2count_file, encoding="utf8")) _data = round_trip_load(open(plugins2count_file, encoding="utf8"))
_data["PluginCountLimit"].yaml_set_start_comment( _data["PluginCountLimit"].yaml_set_start_comment(
"""# 命令每日次数限制 """# 命令每日次数限制
# 即 用户/群聊 每日可调用命令的次数 [数据内存存储,重启将会重置] # 即 用户/群聊 每日可调用命令的次数 [数据内存存储,重启将会重置]
# 每日调用直到 00:00 刷新 # 每日调用直到 00:00 刷新
# key:模块名称 # key:模块名称
# max_count: 每日调用上限 # max_count: 每日调用上限
# status:此限制的开关状态 # status:此限制的开关状态
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id # limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
# 示例:'user':用户上限,'group':群聊上限 # 示例:'user':用户上限,'group':群聊上限
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称 # rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
# rst 为 "" 或 None 时则不回复 # rst 为 "" 或 None 时则不回复
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]" # rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批" # rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""", # 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
indent=2, indent=2,
) )
with open(plugins2count_file, "w", encoding="utf8") as wf: with open(plugins2count_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True) round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
plugins2count_manager.reload_count_limit() plugins2count_manager.reload_count_limit()
+43 -43
View File
@@ -1,43 +1,43 @@
from utils.manager import resources_manager from utils.manager import resources_manager
from utils.utils import get_matchers from utils.utils import get_matchers
from services.log import logger from services.log import logger
from pathlib import Path from pathlib import Path
import nonebot import nonebot
def init_plugins_resources(): def init_plugins_resources():
""" """
资源文件路径的移动 资源文件路径的移动
""" """
_tmp = [] _tmp = []
for matcher in get_matchers(): for matcher in get_matchers():
if matcher.module not in _tmp: if matcher.module not in _tmp:
_tmp.append(matcher.module) _tmp.append(matcher.module)
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.module)
try: try:
_module = _plugin.module _module = _plugin.module
except AttributeError: except AttributeError:
logger.warning(f"插件 {matcher.module} 加载失败...,资源控制未加载...") logger.warning(f"插件 {matcher.module} 加载失败...,资源控制未加载...")
else: else:
try: try:
resources = _module.__getattribute__("__plugin_resources__") resources = _module.__getattribute__("__plugin_resources__")
except AttributeError: except AttributeError:
pass pass
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.module, (path / resource).absolute(), resources[resource])
resources_manager.save() resources_manager.save()
resources_manager.start_move() resources_manager.start_move()
+126 -130
View File
@@ -1,130 +1,126 @@
from pathlib import Path from pathlib import Path
from ruamel.yaml import round_trip_load, round_trip_dump, YAML from ruamel.yaml import round_trip_load, round_trip_dump, YAML
from utils.manager import plugins2settings_manager, admin_manager from utils.manager import plugins2settings_manager, admin_manager
from services.log import logger from services.log import logger
from utils.utils import get_matchers from utils.utils import get_matchers
from ruamel import yaml from ruamel import yaml
import nonebot import nonebot
_yaml = YAML(typ="safe") _yaml = YAML(typ="safe")
def init_plugins_settings(data_path: str): 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 = Path(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()
_data = {} _tmp_module = {}
if plugins2settings_file.exists(): _tmp = []
with open(plugins2settings_file, "r", encoding="utf8") as f: for x in plugins2settings_manager.keys():
_data = _yaml.load(f) try:
_data = _data["PluginSettings"] if _data else {} _plugin = nonebot.plugin.get_plugin(x)
_tmp_module = {} _module = _plugin.module
_tmp = [] plugin_name = _module.__getattribute__("__zx_plugin_name__")
for matcher in _matchers: _tmp_module[x] = plugin_name
if matcher.module in _data.keys(): except (KeyError, AttributeError) as e:
plugins2settings_manager.add_plugin_settings( logger.error(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}")
matcher.module, _tmp_module[x] = ""
plugin_type=_data[matcher.module]["plugin_type"], for matcher in _matchers:
data_dict=_data[matcher.module], if matcher.module not in plugins2settings_manager.keys():
) _plugin = nonebot.plugin.get_plugin(matcher.module)
if _data[matcher.module]["cmd"]: try:
_tmp_module[matcher.module] = _data[matcher.module]["cmd"][0] _module = _plugin.module
else: except AttributeError:
_plugin = nonebot.plugin.get_plugin(matcher.module) logger.warning(f"插件 {matcher.module} 加载失败...,插件控制未加载.")
try: else:
_module = _plugin.module try:
except AttributeError: plugin_name = _module.__getattribute__("__zx_plugin_name__")
logger.warning(f"插件 {matcher.module} 加载失败...,插件控制未加载.") if "[admin]" in plugin_name.lower():
else: try:
try: admin_settings = _module.__getattribute__(
plugin_name = _module.__getattribute__("__zx_plugin_name__") "__plugin_settings__"
if "[admin]" in plugin_name.lower(): )
try: level = admin_settings["admin_level"]
admin_settings = _module.__getattribute__( cmd = admin_settings.get("cmd")
"__plugin_settings__" except (AttributeError, KeyError):
) level = 5
level = admin_settings["admin_level"] cmd = None
cmd = admin_settings.get("cmd") if level is None:
except (AttributeError, KeyError): level = 5
level = 5 admin_manager.add_admin_plugin_settings(
cmd = None matcher.module, cmd, level
if not level: )
level = 5 if (
admin_manager.add_admin_plugin_settings( "[hidden]" in plugin_name.lower()
matcher.module, cmd, level or "[admin]" in plugin_name.lower()
) or "[superuser]" in plugin_name.lower()
if ( or matcher.module in plugins2settings_manager.keys()
"[hidden]" in plugin_name.lower() ):
or "[admin]" in plugin_name.lower() continue
or "[superuser]" in plugin_name.lower() except AttributeError:
or matcher.module in plugins2settings_manager.keys() if matcher.module not in _tmp:
): logger.warning(
continue f"获取插件 {matcher.module} __zx_plugin_name__ 失败...,插件控制未加载."
except AttributeError: )
if matcher.module not in _tmp: else:
logger.warning( try:
f"获取插件 {matcher.module} __zx_plugin_name__ 失败...,插件控制未加载." _tmp_module[matcher.module] = plugin_name
) plugin_settings = _module.__getattribute__(
else: "__plugin_settings__"
try: )
_tmp_module[matcher.module] = plugin_name if (
plugin_settings = _module.__getattribute__( plugin_settings["cmd"] is not None
"__plugin_settings__" and plugin_name not in plugin_settings["cmd"]
) ):
if ( plugin_settings["cmd"].append(plugin_name)
plugin_settings["cmd"] if plugins2settings_manager.get(
and plugin_name not in plugin_settings["cmd"] matcher.module
): ) and plugins2settings_manager[matcher.module].get(
plugin_settings["cmd"].append(plugin_name) "plugin_type"
if plugins2settings_manager.get( ):
matcher.module plugin_type = tuple(
) and plugins2settings_manager[matcher.module].get( plugins2settings_manager.get_plugin_data(
"plugin_type" matcher.module
): )["plugin_type"]
plugin_type = tuple( )
plugins2settings_manager.get_plugin_data( else:
matcher.module try:
)["plugin_type"] plugin_type = _module.__getattribute__(
) "__plugin_type__"
else: )
try: except AttributeError:
plugin_type = _module.__getattribute__( plugin_type = ("normal",)
"__plugin_type__" if plugin_settings and matcher.module:
) plugins2settings_manager.add_plugin_settings(
except AttributeError: matcher.module,
plugin_type = ("normal",) plugin_type=plugin_type,
if plugin_settings and matcher.module: data_dict=plugin_settings,
plugins2settings_manager.add_plugin_settings( )
matcher.module, except AttributeError:
plugin_type=plugin_type, pass
data_dict=plugin_settings, _tmp.append(matcher.module)
) _tmp_data = {"PluginSettings": plugins2settings_manager.get_data()}
except AttributeError: with open(plugins2settings_file, "w", encoding="utf8") as wf:
pass yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
_tmp.append(matcher.module) _data = round_trip_load(open(plugins2settings_file, encoding="utf8"))
_tmp_data = {"PluginSettings": plugins2settings_manager.get_data()} _data["PluginSettings"].yaml_set_start_comment(
with open(plugins2settings_file, "w", encoding="utf8") as wf: """# 模块与对应命令和对应群权限
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True) # 用于生成帮助图片 和 开关功能
_data = round_trip_load(open(plugins2settings_file, encoding="utf8")) # key:模块名称
_data["PluginSettings"].yaml_set_start_comment( # level:需要的群等级
"""# 模块与对应命令和对应群权限 # default_status:加入群时功能的默认开关状态
# 用于生成帮助图片 和 开关功能 # limit_superuser: 功能状态是否限制超级用户
# key:模块名称 # cmd: 关闭[cmd] 都会触发命令 关闭对应功能,cmd列表第一个词为统计的功能名称
# level:需要的群等级 # plugin_type: 帮助类别 示例:('原神相关',) 或 ('原神相关', 1),1代表帮助命令列向排列,否则为横向排列""",
# default_status:加入群时功能的默认开关状态 indent=2,
# limit_superuser: 功能状态是否限制超级用户 )
# cmd: 关闭[cmd] 都会触发命令 关闭对应功能,cmd列表第一个词为统计的功能名称 for plugin in _data["PluginSettings"].keys():
# plugin_type: 帮助类别 示例:('原神相关',) 或 ('原神相关', 1),1代表帮助命令列向排列,否则为横向排列""", _data["PluginSettings"][plugin].yaml_set_start_comment(
indent=2, f"{plugin}:{_tmp_module[plugin]}", indent=2
) )
for plugin in _data["PluginSettings"].keys(): with open(plugins2settings_file, "w", encoding="utf8") as wf:
_data["PluginSettings"][plugin].yaml_set_start_comment( round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
f"{plugin}:{_tmp_module[plugin]}", indent=2 logger.info(f"已成功加载 {len(plugins2settings_manager.get_data())} 个非限制插件.")
)
with open(plugins2settings_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
logger.info(f"已成功加载 {len(plugins2settings_manager.get_data())} 个非限制插件.")
+149 -150
View File
@@ -1,150 +1,149 @@
from nonebot import on_request, on_message from nonebot import on_request, on_message
from nonebot.adapters.cqhttp import ( from nonebot.adapters.cqhttp import (
Bot, Bot,
FriendRequestEvent, FriendRequestEvent,
GroupRequestEvent, GroupRequestEvent,
MessageEvent, MessageEvent,
) )
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.cqhttp.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
import asyncio import asyncio
import time import time
import re import re
__zx_plugin_name__ = "好友群聊处理请求 [Hidden]" __zx_plugin_name__ = "好友群聊处理请求 [Hidden]"
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_configs__ = { __plugin_configs__ = {
"AUTO_ADD_FRIEND": {"value": False, "help": "是否自动同意好友添加", "default_value": False} "AUTO_ADD_FRIEND": {"value": False, "help": "是否自动同意好友添加", "default_value": False}
} }
friend_req = on_request(priority=5, block=True) friend_req = on_request(priority=5, block=True)
group_req = on_request(priority=5, block=True) group_req = on_request(priority=5, block=True)
x = on_message(priority=5, block=False) x = on_message(priority=9, block=False)
exists_data = {"private": {}, "group": {}} exists_data = {"private": {}, "group": {}}
@friend_req.handle() @friend_req.handle()
async def _(bot: Bot, event: FriendRequestEvent, state: dict): async def _(bot: Bot, event: FriendRequestEvent, state: dict):
print(event) 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: return
return exists_data["private"][event.user_id] = time.time()
exists_data["private"][event.user_id] = time.time() user = await bot.get_stranger_info(user_id=event.user_id)
user = await bot.get_stranger_info(user_id=event.user_id) nickname = user["nickname"]
nickname = user["nickname"] sex = user["sex"]
sex = user["sex"] age = str(user["age"])
age = str(user["age"]) comment = event.comment
comment = event.comment 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"昵称:{nickname}({event.user_id})\n"
f"昵称:{nickname}({event.user_id})\n" f"自动同意:{'√' if Config.get_config('invite_manager', 'AUTO_ADD_FRIEND') else '×'}\n"
f"自动同意:{'√' if Config.get_config('auto_invite', 'AUTO_ADD_FRIEND') else '×'}\n" f"日期:{str(datetime.now()).split('.')[0]}\n"
f"日期:{str(datetime.now()).split('.')[0]}\n" f"备注:{event.comment}",
f"备注:{event.comment}", )
) if Config.get_config("invite_manager", "AUTO_ADD_FRIEND"):
if Config.get_config("auto_invite", "AUTO_ADD_FRIEND"): await bot.set_friend_add_request(flag=event.flag, approve=True)
await bot.set_friend_add_request(flag=event.flag, approve=True) await FriendUser.add_friend_info(user["user_id"], user["nickname"])
await FriendUser.add_friend_info(user["user_id"], user["nickname"]) else:
else: requests_manager.add_request(
requests_manager.add_request( event.user_id,
event.user_id, "private",
"private", event.flag,
event.flag, nickname=nickname,
nickname=nickname, sex=sex,
sex=sex, age=age,
age=age, comment=comment,
comment=comment, )
)
@group_req.handle()
@group_req.handle() async def _(bot: Bot, event: GroupRequestEvent, state: dict):
async def _(bot: Bot, event: GroupRequestEvent, state: dict): 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: try:
try: if await GroupInfo.get_group_info(event.group_id):
await bot.set_group_add_request( await GroupInfo.set_group_flag(event.group_id, 1)
flag=event.flag, sub_type="invite", approve=True else:
) group_info = await bot.get_group_info(group_id=event.group_id)
if await GroupInfo.get_group_info(event.group_id): await GroupInfo.add_group_info(
await GroupInfo.set_group_flag(event.group_id, 1) group_info["group_id"],
else: group_info["group_name"],
group_info = await bot.get_group_info(group_id=event.group_id) group_info["max_member_count"],
await GroupInfo.add_group_info( group_info["member_count"],
group_info["group_id"], 1,
group_info["group_name"], )
group_info["max_member_count"], await bot.set_group_add_request(
group_info["member_count"], flag=event.flag, sub_type="invite", approve=True
1, )
) except ActionFailed:
except ActionFailed: pass
pass else:
else: user = await bot.get_stranger_info(user_id=event.user_id)
user = await bot.get_stranger_info(user_id=event.user_id) sex = user["sex"]
sex = user["sex"] age = str(user["age"])
age = str(user["age"]) if exists_data["group"].get(f"{event.user_id}:{event.group_id}"):
if exists_data["group"].get(f"{event.user_id}:{event.group_id}"): if (
if ( time.time()
time.time() - exists_data["group"][f"{event.user_id}:{event.group_id}"]
- exists_data["group"][f"{event.user_id}:{event.group_id}"] < 60 * 5
< 60 * 5 ):
): return
return exists_data["group"][f"{event.user_id}:{event.group_id}"] = time.time()
exists_data["group"][f"{event.user_id}:{event.group_id}"] = time.time() nickname = await FriendUser.get_user_name(event.user_id)
nickname = await FriendUser.get_user_name(event.user_id) 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"申请人:{nickname}({event.user_id})\n"
f"申请人:{nickname}({event.user_id})\n" f"群聊:{event.group_id}\n"
f"群聊:{event.group_id}\n" f"邀请日期:{str(datetime.now()).split('.')[0]}",
f"邀请日期:{str(datetime.now()).split('.')[0]}", )
) await bot.send_private_msg(
await bot.send_private_msg( user_id=event.user_id,
user_id=event.user_id, message=f"想要邀请我偷偷入群嘛~已经提醒{NICKNAME}的管理员大人了\n"
message=f"想要邀请我偷偷入群嘛~已经提醒{NICKNAME}的管理员大人了\n" "请确保已经群主或群管理沟通过!\n"
"请确保已经群主或群管理沟通过!\n" "等待管理员处理吧!",
"等待管理员处理吧!", )
) requests_manager.add_request(
requests_manager.add_request( event.user_id,
event.user_id, "group",
"group", event.flag,
event.flag, invite_group=event.group_id,
invite_group=event.group_id, nickname=nickname,
nickname=nickname, sex=sex,
sex=sex, age=age,
age=age, )
)
@x.handle()
@x.handle() async def _(bot: Bot, event: MessageEvent, state: dict):
async def _(bot: Bot, event: MessageEvent, state: dict): 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: group_id = int(r.group(1))
group_id = int(r.group(1)) else:
else: return
return r = re.search(r'groupname="(.*?)"', str(event.get_message()))
r = re.search(r'groupname="(.*?)"', str(event.get_message())) if r:
if r: group_name = r.group(1)
group_name = r.group(1) else:
else: group_name = "None"
group_name = "None" requests_manager.set_group_name(group_name, group_id)
requests_manager.set_group_name(group_name, group_id)
@scheduler.scheduled_job(
@scheduler.scheduled_job( "interval",
"interval", minutes=5,
minutes=5, )
) async def _():
async def _(): global exists_data
global exists_data exists_data = {"private": {}, "group": {}}
exists_data = {"private": {}, "group": {}}
Regular → Executable
+194 -194
View File
@@ -1,194 +1,194 @@
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.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 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 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 from configs.config import NICKNAME
__zx_plugin_name__ = "昵称系统" __zx_plugin_name__ = "昵称系统"
__plugin_usage__ = f""" __plugin_usage__ = f"""
usage: usage:
个人昵称系统,群聊 与 私聊 昵称相互独立 个人昵称系统,群聊 与 私聊 昵称相互独立
指令: 指令:
以后叫我 [昵称] 以后叫我 [昵称]
{NICKNAME}我是谁 {NICKNAME}我是谁
""".strip() """.strip()
__plugin_des__ = "区区昵称,才不想叫呢!" __plugin_des__ = "区区昵称,才不想叫呢!"
__plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"] __plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
nickname = on_command( nickname = on_command(
"nickname", "nickname",
aliases={"以后叫我", "以后请叫我", "称呼我", "以后请称呼我", "以后称呼我", "叫我", "请叫我"}, aliases={"以后叫我", "以后请叫我", "称呼我", "以后请称呼我", "以后称呼我", "叫我", "请叫我"},
rule=to_me(), rule=to_me(),
priority=5, priority=5,
block=True, block=True,
) )
my_nickname = on_command( my_nickname = on_command(
"my_name", aliases={"我叫什么", "我是谁", "我的名字"}, rule=to_me(), priority=5, block=True "my_name", aliases={"我叫什么", "我是谁", "我的名字"}, rule=to_me(), priority=5, block=True
) )
cancel_nickname = on_command("取消昵称", rule=to_me(), priority=5, block=True) cancel_nickname = on_command("取消昵称", rule=to_me(), priority=5, block=True)
@nickname.handle() @nickname.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
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:
await nickname.finish("昵称可不能超过10个字!", at_sender=True) await nickname.finish("昵称可不能超过10个字!", at_sender=True)
if await GroupInfoUser.set_group_member_nickname( if await GroupInfoUser.set_group_member_nickname(
event.user_id, event.group_id, msg event.user_id, event.group_id, msg
): ):
if len(msg) < 5: if len(msg) < 5:
if random.random() < 0.5: if random.random() < 0.5:
msg = "~".join(msg) msg = "~".join(msg)
await nickname.send( await nickname.send(
random.choice( random.choice(
[ [
f"好啦好啦,我知道啦,{msg},以后就这么叫你吧", f"好啦好啦,我知道啦,{msg},以后就这么叫你吧",
f"嗯嗯,{NICKNAME}记住你的昵称了哦,{msg}", f"嗯嗯,{NICKNAME}记住你的昵称了哦,{msg}",
f"好突然,突然要叫你昵称什么的...{msg}..", f"好突然,突然要叫你昵称什么的...{msg}..",
f"{NICKNAME}会好好记住的{msg}的,放心吧", f"{NICKNAME}会好好记住的{msg}的,放心吧",
f"好..好.,那窝以后就叫你{msg}了.", f"好..好.,那窝以后就叫你{msg}了.",
] ]
) )
) )
logger.info(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg}") logger.info(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg}")
else: else:
await nickname.send("设置昵称失败,请更新群组成员信息!", at_sender=True) await nickname.send("设置昵称失败,请更新群组成员信息!", at_sender=True)
logger.warning(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg} 失败") logger.warning(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg} 失败")
@nickname.handle() @nickname.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
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:
await nickname.finish("不要超过10个字!", at_sender=True) await nickname.finish("不要超过10个字!", at_sender=True)
if await FriendUser.set_friend_nickname(event.user_id, msg): if await FriendUser.set_friend_nickname(event.user_id, msg):
await nickname.send( await nickname.send(
random.choice( random.choice(
[ [
f"好啦好啦,我知道啦,{msg},以后就这么叫你吧", f"好啦好啦,我知道啦,{msg},以后就这么叫你吧",
f"嗯嗯,{NICKNAME}记住你的昵称了哦,{msg}", f"嗯嗯,{NICKNAME}记住你的昵称了哦,{msg}",
f"好突然,突然要叫你昵称什么的...{msg}..", f"好突然,突然要叫你昵称什么的...{msg}..",
f"{NICKNAME}会好好记住的{msg}的,放心吧", f"{NICKNAME}会好好记住的{msg}的,放心吧",
f"好..好.,那窝以后就叫你{msg}了.", f"好..好.,那窝以后就叫你{msg}了.",
] ]
) )
) )
logger.info(f"USER {event.user_id} 设置昵称 {msg}") logger.info(f"USER {event.user_id} 设置昵称 {msg}")
else: else:
await nickname.send("设置昵称失败了,明天再来试一试!或联系管理员更新好友!", at_sender=True) await nickname.send("设置昵称失败了,明天再来试一试!或联系管理员更新好友!", at_sender=True)
logger.warning(f"USER {event.user_id} 设置昵称 {msg} 失败") logger.warning(f"USER {event.user_id} 设置昵称 {msg} 失败")
@my_nickname.handle() @my_nickname.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
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
) )
except AttributeError: except AttributeError:
nickname_ = "" nickname_ = ""
if nickname_: if nickname_:
await my_nickname.send( await my_nickname.send(
random.choice( random.choice(
[ [
f"我肯定记得你啊,你是{nickname_}啊", f"我肯定记得你啊,你是{nickname_}啊",
f"我不会忘记你的,你也不要忘记我!{nickname_}", f"我不会忘记你的,你也不要忘记我!{nickname_}",
f"哼哼,{NICKNAME}记忆力可是很好的,{nickname_}", f"哼哼,{NICKNAME}记忆力可是很好的,{nickname_}",
f"嗯?你是失忆了嘛...{nickname_}..", f"嗯?你是失忆了嘛...{nickname_}..",
f"不要小看{NICKNAME}的记忆力啊!笨蛋{nickname_}!QAQ", f"不要小看{NICKNAME}的记忆力啊!笨蛋{nickname_}!QAQ",
f"哎?{nickname_}..怎么了吗..突然这样问..", f"哎?{nickname_}..怎么了吗..突然这样问..",
] ]
) )
) )
else: else:
nickname_ = event.sender.card if event.sender.card else event.sender.nickname nickname_ = event.sender.card if event.sender.card else event.sender.nickname
await my_nickname.send( await my_nickname.send(
random.choice( random.choice(
["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"] ["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"]
).format(nickname_) ).format(nickname_)
) )
@my_nickname.handle() @my_nickname.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
nickname_ = await FriendUser.get_friend_nickname(event.user_id) nickname_ = await FriendUser.get_friend_nickname(event.user_id)
if nickname_: if nickname_:
await my_nickname.send( await my_nickname.send(
random.choice( random.choice(
[ [
f"我肯定记得你啊,你是{nickname_}啊", f"我肯定记得你啊,你是{nickname_}啊",
f"我不会忘记你的,你也不要忘记我!{nickname_}", f"我不会忘记你的,你也不要忘记我!{nickname_}",
f"哼哼,{NICKNAME}记忆力可是很好的,{nickname_}", f"哼哼,{NICKNAME}记忆力可是很好的,{nickname_}",
f"嗯?你是失忆了嘛...{nickname_}..", f"嗯?你是失忆了嘛...{nickname_}..",
f"不要小看{NICKNAME}的记忆力啊!笨蛋{nickname_}!QAQ", f"不要小看{NICKNAME}的记忆力啊!笨蛋{nickname_}!QAQ",
f"哎?{nickname_}..怎么了吗..突然这样问..", f"哎?{nickname_}..怎么了吗..突然这样问..",
] ]
) )
) )
else: else:
nickname_ = (await bot.get_stranger_info(user_id=event.user_id))["nickname"] nickname_ = (await bot.get_stranger_info(user_id=event.user_id))["nickname"]
await my_nickname.send( await my_nickname.send(
random.choice( random.choice(
["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"] ["没..没有昵称嘛,{}", "啊,你是{}啊,我想叫你的昵称!", "是{}啊,有什么事吗?", "你是{}?"]
).format(nickname_) ).format(nickname_)
) )
@cancel_nickname.handle() @cancel_nickname.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
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
) )
if nickname_: if nickname_:
await cancel_nickname.send( await cancel_nickname.send(
random.choice( random.choice(
[ [
f"呜..{NICKNAME}睡一觉就会忘记的..和梦一样..{nickname_}", f"呜..{NICKNAME}睡一觉就会忘记的..和梦一样..{nickname_}",
f"窝知道了..{nickname_}..", f"窝知道了..{nickname_}..",
f"是{NICKNAME}哪里做的不好嘛..好吧..晚安{nickname_}", f"是{NICKNAME}哪里做的不好嘛..好吧..晚安{nickname_}",
f"呃,{nickname_},下次我绝对绝对绝对不会再忘记你!", f"呃,{nickname_},下次我绝对绝对绝对不会再忘记你!",
f"可..可恶!{nickname_}!太可恶了!呜", f"可..可恶!{nickname_}!太可恶了!呜",
] ]
) )
) )
await GroupInfoUser.set_group_member_nickname(event.user_id, event.group_id, "") await GroupInfoUser.set_group_member_nickname(event.user_id, event.group_id, "")
await BanUser.ban(event.user_id, 9, 60) await BanUser.ban(event.user_id, 9, 60)
else: else:
await cancel_nickname.send("你在做梦吗?你没有昵称啊", at_sender=True) await cancel_nickname.send("你在做梦吗?你没有昵称啊", at_sender=True)
@cancel_nickname.handle() @cancel_nickname.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
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(
random.choice( random.choice(
[ [
f"呜..{NICKNAME}睡一觉就会忘记的..和梦一样..{nickname_}", f"呜..{NICKNAME}睡一觉就会忘记的..和梦一样..{nickname_}",
f"窝知道了..{nickname_}..", f"窝知道了..{nickname_}..",
f"是{NICKNAME}哪里做的不好嘛..好吧..晚安{nickname_}", f"是{NICKNAME}哪里做的不好嘛..好吧..晚安{nickname_}",
f"呃,{nickname_},下次我绝对绝对绝对不会再忘记你!", f"呃,{nickname_},下次我绝对绝对绝对不会再忘记你!",
f"可..可恶!{nickname_}!太可恶了!呜", f"可..可恶!{nickname_}!太可恶了!呜",
] ]
) )
) )
await FriendUser.get_user_name(event.user_id) await FriendUser.get_user_name(event.user_id)
await BanUser.ban(event.user_id, 9, 60) await BanUser.ban(event.user_id, 9, 60)
else: else:
await cancel_nickname.send("你在做梦吗?你没有昵称啊", at_sender=True) await cancel_nickname.send("你在做梦吗?你没有昵称啊", at_sender=True)
Regular → Executable
+103 -111
View File
@@ -1,111 +1,103 @@
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 asyncpg.exceptions import DuplicateColumnError
from models.group_info import GroupInfo from models.group_info import GroupInfo
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
from utils.user_agent import get_user_agent 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 utils.http_utils import AsyncHttpx
from pathlib import Path from pathlib import Path
import aiohttp import nonebot
import nonebot
try:
try: import ujson as json
import ujson as json except ModuleNotFoundError:
except ModuleNotFoundError: import json
import json
driver: Driver = nonebot.get_driver()
driver: Driver = nonebot.get_driver()
@driver.on_startup
@driver.on_startup async def update_city():
async def update_city(): """
""" 部分插件需要中国省份城市
部分插件需要中国省份城市 这里直接更新,避免插件内代码重复
这里直接更新,避免插件内代码重复 """
:return: china_city = Path(TEXT_PATH) / "china_city.json"
""" data = {}
china_city = Path(TEXT_PATH) / "china_city.json" try:
data = {} res = await AsyncHttpx.get(
try: "http://www.weather.com.cn/data/city3jdata/china.html", timeout=5
async with aiohttp.ClientSession(headers=get_user_agent()) as session: )
async with session.get( res.encoding = "utf8"
"http://www.weather.com.cn/data/city3jdata/china.html", timeout=5 provinces_data = json.loads(res.text)
) as res: for province in provinces_data.keys():
provinces_data = json.loads(await res.text(encoding="utf8")) data[provinces_data[province]] = []
for province in provinces_data.keys(): res = await AsyncHttpx.get(
data[provinces_data[province]] = [] f"http://www.weather.com.cn/data/city3jdata/provshi/{province}.html",
async with session.get( timeout=5,
f"http://www.weather.com.cn/data/city3jdata/provshi/{province}.html", )
timeout=5, res.encoding = "utf8"
) as res: city_data = json.loads(res.text)
city_data = json.loads(await res.text(encoding="utf8")) for city in city_data.keys():
for city in city_data.keys(): data[provinces_data[province]].append(city_data[city])
data[provinces_data[province]].append(city_data[city]) with open(china_city, "w", encoding="utf8") as f:
with open(china_city, "w", encoding="utf8") as f: json.dump(data, f, indent=4, ensure_ascii=False)
json.dump(data, f, indent=4, ensure_ascii=False) logger.info("自动更新城市列表完成.....")
logger.info("自动更新城市列表完成.....") except TimeoutError:
except TimeoutError: logger.warning("自动更新城市列表超时.....")
logger.info("自动更新城市列表超时.....") except ValueError:
logger.warning("自动城市列表失败.....")
except Exception as e:
@driver.on_startup logger.error(f"自动城市列表未知错误 {type(e)}:{e}")
async def _():
"""
数据库表结构变换 @driver.on_startup
""" async def _():
sql_str = [ """
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag 数据库表结构变换
] """
for sql in sql_str: sql_str = [
try: "ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag
query = db.text(sql) ]
await db.first(query) for sql in sql_str:
except DuplicateColumnError: try:
pass query = db.text(sql)
await db.first(query)
except DuplicateColumnError:
@driver.on_bot_connect pass
async def _(bot: Bot):
"""
版本某些需要的变换 @driver.on_bot_connect
""" async def _(bot: Bot):
# 清空不存在的群聊信息,并将已所有已存在的群聊group_flag设置为1(认证所有已存在的群) """
if not await GroupInfo.get_group_info(114514): 版本某些需要的变换
# 标识符,该功能只需执行一次 """
await GroupInfo.add_group_info( # 清空不存在的群聊信息,并将已所有已存在的群聊group_flag设置为1(认证所有已存在的群)
114514, if not await GroupInfo.get_group_info(114514):
"114514", # 标识符,该功能只需执行一次
114514, await GroupInfo.add_group_info(114514, "114514", 114514, 114514, 1)
114514, group_list = await bot.get_group_list()
1 group_list = [g["group_id"] for g in group_list]
) _gl = [x.group_id for x in await GroupInfo.get_all_group()]
group_list = await bot.get_group_list() if 114514 in _gl:
group_list = [g["group_id"] for g in group_list] _gl.remove(114514)
_gl = [x.group_id for x in await GroupInfo.get_all_group()] for group_id in _gl:
if 114514 in _gl: if group_id in group_list:
_gl.remove(114514) if await GroupInfo.get_group_info(group_id):
for group_id in _gl: await GroupInfo.set_group_flag(group_id, 1)
if group_id in group_list: else:
if await GroupInfo.get_group_info(group_id): group_info = await bot.get_group_info(group_id=group_id)
await GroupInfo.set_group_flag(group_id, 1) await GroupInfo.add_group_info(
else: group_info["group_id"],
group_info = await bot.get_group_info(group_id=group_id) group_info["group_name"],
await GroupInfo.add_group_info( group_info["max_member_count"],
group_info["group_id"], group_info["member_count"],
group_info["group_name"], 1,
group_info["max_member_count"], )
group_info["member_count"], logger.info(f"已将群聊 {group_id} 添加认证...")
1 else:
) await GroupInfo.delete_group_info(group_id)
logger.info(f"已将群聊 {group_id} 添加认证...") logger.info(f"移除不存在的群聊信息:{group_id}")
else:
await GroupInfo.delete_group_info(group_id)
logger.info(f"移除不存在的群聊信息:{group_id}")
+10 -10
View File
@@ -1,10 +1,10 @@
import nonebot import nonebot
nonebot.load_plugins('basic_plugins/super_cmd') nonebot.load_plugins('basic_plugins/super_cmd')
+152 -152
View File
@@ -1,152 +1,152 @@
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.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message from nonebot.adapters.cqhttp import Bot, MessageEvent, Message
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 get_message_text, 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
__zx_plugin_name__ = "显示所有好友群组 [Superuser]" __zx_plugin_name__ = "显示所有好友群组 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
显示所有好友群组 显示所有好友群组
指令: 指令:
查看所有好友/查看所有群组 查看所有好友/查看所有群组
同意好友请求 [id] 同意好友请求 [id]
拒绝好友请求 [id] 拒绝好友请求 [id]
同意群聊请求 [id] 同意群聊请求 [id]
拒绝群聊请求 [id] 拒绝群聊请求 [id]
查看所有请求 查看所有请求
清空所有请求 清空所有请求
""".strip() """.strip()
__plugin_des__ = "显示所有好友群组" __plugin_des__ = "显示所有好友群组"
__plugin_cmd__ = [ __plugin_cmd__ = [
"查看所有好友/查看所有群组", "查看所有好友/查看所有群组",
"同意好友请求 [id]", "同意好友请求 [id]",
"拒绝好友请求 [id]", "拒绝好友请求 [id]",
"同意群聊请求 [id]", "同意群聊请求 [id]",
"拒绝群聊请求 [id]", "拒绝群聊请求 [id]",
"查看所有请求", "查看所有请求",
"清空所有请求", "清空所有请求",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
cls_group = on_command( cls_group = on_command(
"查看所有群组", rule=to_me(), permission=SUPERUSER, priority=1, block=True "查看所有群组", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
cls_friend = on_command( cls_friend = on_command(
"查看所有好友", rule=to_me(), permission=SUPERUSER, priority=1, block=True "查看所有好友", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
friend_handle = on_command( friend_handle = on_command(
"同意好友请求", aliases={"拒绝好友请求"}, permission=SUPERUSER, priority=1, block=True "同意好友请求", aliases={"拒绝好友请求"}, permission=SUPERUSER, priority=1, block=True
) )
group_handle = on_command( group_handle = on_command(
"同意群聊请求", aliases={"拒绝群聊请求"}, permission=SUPERUSER, priority=1, block=True "同意群聊请求", aliases={"拒绝群聊请求"}, permission=SUPERUSER, priority=1, block=True
) )
clear_request = on_command("清空所有请求", permission=SUPERUSER, priority=1, block=True) clear_request = on_command("清空所有请求", permission=SUPERUSER, priority=1, block=True)
cls_request = on_command("查看所有请求", permission=SUPERUSER, priority=1, block=True) cls_request = on_command("查看所有请求", permission=SUPERUSER, priority=1, block=True)
@cls_group.handle() @cls_group.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
gl = await bot.get_group_list(self_id=int(bot.self_id)) gl = await bot.get_group_list(self_id=int(bot.self_id))
msg = ["{group_id} {group_name}".format_map(g) for g in gl] msg = ["{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 bot.send_private_msg(
self_id=int(bot.self_id), self_id=int(bot.self_id),
user_id=int(list(bot.config.superusers)[0]), user_id=int(list(bot.config.superusers)[0]),
message=msg, message=msg,
) )
@cls_friend.handle() @cls_friend.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
gl = await bot.get_friend_list(self_id=int(bot.self_id)) gl = await bot.get_friend_list(self_id=int(bot.self_id))
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 bot.send_private_msg(
self_id=int(bot.self_id), self_id=int(bot.self_id),
user_id=int(list(bot.config.superusers)[0]), user_id=int(list(bot.config.superusers)[0]),
message=msg, message=msg,
) )
@friend_handle.handle() @friend_handle.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
id_ = get_message_text(event.json()) id_ = get_message_text(event.json())
if is_number(id_): if is_number(id_):
id_ = int(id_) id_ = int(id_)
if state["_prefix"]["raw_command"][:2] == "同意": if state["_prefix"]["raw_command"][: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:
await friend_handle.send("同意好友请求失败,可能是未找到此id的请求..") await friend_handle.send("同意好友请求失败,可能是未找到此id的请求..")
else: else:
if await requests_manager.refused(bot, id_, "private"): if await requests_manager.refused(bot, id_, "private"):
await friend_handle.send("拒绝好友请求成功..") await friend_handle.send("拒绝好友请求成功..")
else: else:
await friend_handle.send("拒绝好友请求失败,可能是未找到此id的请求..") await friend_handle.send("拒绝好友请求失败,可能是未找到此id的请求..")
else: else:
await friend_handle.send("id必须为纯数字!") await friend_handle.send("id必须为纯数字!")
@group_handle.handle() @group_handle.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
id_ = get_message_text(event.json()) id_ = get_message_text(event.json())
if is_number(id_): if is_number(id_):
id_ = int(id_) id_ = int(id_)
if state["_prefix"]["raw_command"][:2] == "同意": if state["_prefix"]["raw_command"][: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("同意群聊请求成功..")
if await GroupInfo.get_group_info(rid): if await GroupInfo.get_group_info(rid):
await GroupInfo.set_group_flag(rid, 1) await GroupInfo.set_group_flag(rid, 1)
else: else:
group_info = await bot.get_group_info(group_id=rid) group_info = await bot.get_group_info(group_id=rid)
await GroupInfo.add_group_info( await GroupInfo.add_group_info(
rid, rid,
group_info["group_name"], group_info["group_name"],
group_info["max_member_count"], group_info["max_member_count"],
group_info["member_count"], group_info["member_count"],
1 1
) )
else: else:
await friend_handle.send("同意群聊请求失败,可能是未找到此id的请求..") await friend_handle.send("同意群聊请求失败,可能是未找到此id的请求..")
else: else:
if await requests_manager.refused(bot, id_, "group"): if await requests_manager.refused(bot, id_, "group"):
await friend_handle.send("拒绝群聊请求成功..") await friend_handle.send("拒绝群聊请求成功..")
else: else:
await friend_handle.send("拒绝群聊请求失败,可能是未找到此id的请求..") await friend_handle.send("拒绝群聊请求失败,可能是未找到此id的请求..")
else: else:
await friend_handle.send("id必须为纯数字!") await friend_handle.send("id必须为纯数字!")
@cls_request.handle() @cls_request.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
_str = "" _str = ""
for type_ in ["private", "group"]: for type_ in ["private", "group"]:
msg = await requests_manager.show(type_) msg = await requests_manager.show(type_)
if msg: if msg:
_str += image(b64=msg) _str += image(b64=msg)
else: else:
_str += "没有任何好友请求.." if type_ == "private" else "没有任何群聊请求.." _str += "没有任何好友请求.." if type_ == "private" else "没有任何群聊请求.."
if type_ == "private": if type_ == "private":
_str += '\n--------------------\n' _str += '\n--------------------\n'
await cls_request.send(Message(_str)) await cls_request.send(Message(_str))
@clear_request.handle() @clear_request.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
requests_manager.clear() requests_manager.clear()
await cls_request.send("已清空所有好友/群聊请求..") await cls_request.send("已清空所有好友/群聊请求..")
+67 -67
View File
@@ -1,67 +1,67 @@
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.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent 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
from services.log import logger from services.log import logger
from utils.manager import resources_manager from utils.manager import resources_manager
import asyncio import asyncio
import time import time
import os import os
__zx_plugin_name__ = "清理临时数据 [Superuser]" __zx_plugin_name__ = "清理临时数据 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
清理临时数据 清理临时数据
指令: 指令:
清理临时数据 清理临时数据
""".strip() """.strip()
__plugin_des__ = "清理临时数据" __plugin_des__ = "清理临时数据"
__plugin_cmd__ = [ __plugin_cmd__ = [
"清理临时数据", "清理临时数据",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
clear_data = on_command( clear_data = on_command(
"清理临时数据", rule=to_me(), permission=SUPERUSER, priority=1, block=True "清理临时数据", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
resources_manager.add_temp_dir(TEMP_PATH) resources_manager.add_temp_dir(TEMP_PATH)
@clear_data.handle() @clear_data.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
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))
def _clear_data() -> float: def _clear_data() -> float:
size = 0 size = 0
for dir_ in resources_manager.get_temp_data_dir(): for dir_ in resources_manager.get_temp_data_dir():
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: try:
if time.time() - os.path.getatime(file) > 300: if time.time() - os.path.getatime(file) > 300:
file_size = os.path.getsize(file) file_size = os.path.getsize(file)
file.unlink() file.unlink()
size += file_size size += file_size
except Exception as e: except Exception as e:
logger.error(f"清理临时数据错误...{type(e)}:{e}") logger.error(f"清理临时数据错误...{type(e)}:{e}")
return float(size) return float(size)
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=1, hour=1,
minute=1, minute=1,
) )
async def _(): async def _():
size = await asyncio.get_event_loop().run_in_executor(None, _clear_data) size = await asyncio.get_event_loop().run_in_executor(None, _clear_data)
logger.info("自动清理临时数据完成," + "共清理了 {:.2f}MB 的数据...".format(size / 1024 / 1024)) logger.info("自动清理临时数据完成," + "共清理了 {:.2f}MB 的数据...".format(size / 1024 / 1024))
+74 -74
View File
@@ -1,74 +1,74 @@
# async def open_remind(group: int, name: str) -> str: # async def open_remind(group: int, name: str) -> str:
# _name = "" # _name = ""
# if name == "zwa": # if name == "zwa":
# _name = "早晚安" # _name = "早晚安"
# if name == "dz": # if name == "dz":
# _name = "地震播报" # _name = "地震播报"
# if name == "hy": # if name == "hy":
# _name = "群欢迎" # _name = "群欢迎"
# if name == "kxcz": # if name == "kxcz":
# _name = "开箱重置提醒" # _name = "开箱重置提醒"
# if name == "gb": # if name == "gb":
# _name = "广播" # _name = "广播"
# if await GroupRemind.get_status(group, name): # if await GroupRemind.get_status(group, name):
# return f"该群已经开启过 {_name} 通知,请勿重复开启!" # return f"该群已经开启过 {_name} 通知,请勿重复开启!"
# if await GroupRemind.set_status(group, name, True): # if await GroupRemind.set_status(group, name, True):
# return f"成功开启 {_name} 通知!0v0" # return f"成功开启 {_name} 通知!0v0"
# else: # else:
# return f"开启 {_name} 通知失败了..." # return f"开启 {_name} 通知失败了..."
# #
# #
# async def close_remind(group: int, name: str) -> str: # async def close_remind(group: int, name: str) -> str:
# _name = "" # _name = ""
# if name == "zwa": # if name == "zwa":
# _name = "早晚安" # _name = "早晚安"
# if name == "dz": # if name == "dz":
# _name = "地震播报" # _name = "地震播报"
# if name == "hy": # if name == "hy":
# _name = "群欢迎" # _name = "群欢迎"
# if name == "kxcz": # if name == "kxcz":
# _name = "开箱重置提醒" # _name = "开箱重置提醒"
# if name == "gb": # if name == "gb":
# _name = "广播" # _name = "广播"
# if not await GroupRemind.get_status(group, name): # if not await GroupRemind.get_status(group, name):
# return f"该群已经取消过 {_name} 通知,请勿重复取消!" # return f"该群已经取消过 {_name} 通知,请勿重复取消!"
# if await GroupRemind.set_status(group, name, False): # if await GroupRemind.set_status(group, name, False):
# return f"成功关闭 {_name} 通知!0v0" # return f"成功关闭 {_name} 通知!0v0"
# else: # else:
# return f"关闭 {_name} 通知失败了..." # return f"关闭 {_name} 通知失败了..."
# cmd_list = ['总开关', '签到', '发送图片', '色图', '黑白草图', 'coser', '鸡汤/语录', '骂我', '开箱', '鲁迅说', '假消息', '商店系统', # cmd_list = ['总开关', '签到', '发送图片', '色图', '黑白草图', 'coser', '鸡汤/语录', '骂我', '开箱', '鲁迅说', '假消息', '商店系统',
# '操作图片', '查询皮肤', '天气', '疫情', '识番', '搜番', '点歌', 'pixiv', 'rss', '方舟一井', '查干员', '骰子娘', '原神一井'] # '操作图片', '查询皮肤', '天气', '疫情', '识番', '搜番', '点歌', 'pixiv', 'rss', '方舟一井', '查干员', '骰子娘', '原神一井']
# #
# #
# def check_group_switch_json(group_id): # def check_group_switch_json(group_id):
# if not os.path.exists(DATA_PATH + f'rule/group_switch/'): # if not os.path.exists(DATA_PATH + f'rule/group_switch/'):
# os.mkdir(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'): # 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: # with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as f:
# data = {} # data = {}
# for cmd in cmd_list: # for cmd in cmd_list:
# data[cmd] = True # data[cmd] = True
# f.write(json.dumps(data, ensure_ascii=False)) # f.write(json.dumps(data, ensure_ascii=False))
# else: # else:
# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'r', encoding='utf8') as f: # with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'r', encoding='utf8') as f:
# try: # try:
# data = json.load(f) # data = json.load(f)
# except ValueError: # except ValueError:
# data = {} # data = {}
# if len(data.keys()) - 1 != len(cmd_list): # if len(data.keys()) - 1 != len(cmd_list):
# for cmd in cmd_list: # for cmd in cmd_list:
# if cmd not in data.keys(): # if cmd not in data.keys():
# data[cmd] = True # data[cmd] = True
# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as wf: # with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as wf:
# wf.write(json.dumps(data, ensure_ascii=False)) # wf.write(json.dumps(data, ensure_ascii=False))
# reload(data) # reload(data)
# for file in os.listdir(DATA_PATH + 'group_help'): # for file in os.listdir(DATA_PATH + 'group_help'):
# os.remove(DATA_PATH + f'group_help/{file}') # os.remove(DATA_PATH + f'group_help/{file}')
def reload(data): def reload(data):
static_group_dict = data static_group_dict = data
+200 -200
View File
@@ -1,200 +1,200 @@
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.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 get_message_text, 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.cqhttp.exception import ActionFailed
__zx_plugin_name__ = "管理群操作 [Superuser]" __zx_plugin_name__ = "管理群操作 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
群权限 | 群白名单 | 退出群 操作 群权限 | 群白名单 | 退出群 操作
指令: 指令:
退群 [group_id] 退群 [group_id]
修改群权限 [group_id] [等级] 修改群权限 [group_id] [等级]
添加群白名单 *[group_id] 添加群白名单 *[group_id]
删除群白名单 *[group_id] 删除群白名单 *[group_id]
添加群认证 *[group_id] 添加群认证 *[group_id]
删除群认证 *[group_id] 删除群认证 *[group_id]
查看群白名单 查看群白名单
""".strip() """.strip()
__plugin_des__ = "管理群操作" __plugin_des__ = "管理群操作"
__plugin_cmd__ = [ __plugin_cmd__ = [
"退群 [group_id]", "退群 [group_id]",
"修改群权限 [group_id] [等级]", "修改群权限 [group_id] [等级]",
"添加群白名单 *[group_id]", "添加群白名单 *[group_id]",
"删除群白名单 *[group_id]", "删除群白名单 *[group_id]",
"添加群认证 *[group_id]", "添加群认证 *[group_id]",
"删除群认证 *[group_id]", "删除群认证 *[group_id]",
"查看群白名单", "查看群白名单",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
del_group = on_command("退群", rule=to_me(), permission=SUPERUSER, priority=1, block=True) del_group = on_command("退群", rule=to_me(), permission=SUPERUSER, priority=1, block=True)
add_group_level = on_command("修改群权限", priority=1, permission=SUPERUSER, block=True) add_group_level = on_command("修改群权限", priority=1, permission=SUPERUSER, block=True)
my_group_level = on_command( my_group_level = on_command(
"查看群权限", aliases={"群权限"}, priority=5, permission=GROUP, block=True "查看群权限", aliases={"群权限"}, priority=5, permission=GROUP, block=True
) )
what_up_group_level = on_regex( what_up_group_level = on_regex(
".*?(提高|提升|升高|增加|加上)(.*?)群权限.*?", ".*?(提高|提升|升高|增加|加上)(.*?)群权限.*?",
rule=to_me(), rule=to_me(),
priority=5, priority=5,
permission=GROUP, permission=GROUP,
block=True, block=True,
) )
manager_group_whitelist = on_command( manager_group_whitelist = on_command(
"添加群白名单", aliases={"删除群白名单"}, priority=1, permission=SUPERUSER, block=True "添加群白名单", aliases={"删除群白名单"}, priority=1, permission=SUPERUSER, block=True
) )
show_group_whitelist = on_command( show_group_whitelist = on_command(
"查看群白名单", priority=1, permission=SUPERUSER, block=True "查看群白名单", priority=1, permission=SUPERUSER, block=True
) )
group_auth = on_command( group_auth = on_command(
"添加群认证", aliases={"删除群认证"}, priority=1, permission=SUPERUSER, block=True "添加群认证", aliases={"删除群认证"}, priority=1, permission=SUPERUSER, block=True
) )
@del_group.handle() @del_group.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
group_id = get_message_text(event.json()) group_id = get_message_text(event.json())
if group_id: if group_id:
if is_number(group_id): if is_number(group_id):
try: try:
await bot.set_group_leave(group_id=int(group_id)) await bot.set_group_leave(group_id=int(group_id))
logger.info(f"退出群聊 {group_id} 成功") logger.info(f"退出群聊 {group_id} 成功")
await del_group.send(f"退出群聊 {group_id} 成功", at_sender=True) await del_group.send(f"退出群聊 {group_id} 成功", at_sender=True)
group_manager.delete_group(int(group_id)) group_manager.delete_group(int(group_id))
await GroupInfo.delete_group_info(int(group_id)) await GroupInfo.delete_group_info(int(group_id))
except Exception as e: except Exception as e:
logger.info(f"退出群聊 {group_id} 失败 e:{e}") logger.info(f"退出群聊 {group_id} 失败 e:{e}")
else: else:
await del_group.finish(f"请输入正确的群号", at_sender=True) await del_group.finish(f"请输入正确的群号", at_sender=True)
else: else:
await del_group.finish(f"请输入群号", at_sender=True) await del_group.finish(f"请输入群号", at_sender=True)
@add_group_level.handle() @add_group_level.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
group_id = 0 group_id = 0
level = 0 level = 0
if not msg: if not msg:
await add_group_level.finish("用法:修改群权限 [group] [level]") await add_group_level.finish("用法:修改群权限 [group] [level]")
msg = msg.split(" ") msg = msg.split(" ")
if len(msg) < 2: if len(msg) < 2:
await add_group_level.finish("参数不完全..[group] [level]") await add_group_level.finish("参数不完全..[group] [level]")
if is_number(msg[0]) and is_number(msg[1]): if is_number(msg[0]) and is_number(msg[1]):
group_id = msg[0] group_id = msg[0]
level = int(msg[1]) level = int(msg[1])
else: else:
await add_group_level.finish("参数错误...group和level必须是数字..") await add_group_level.finish("参数错误...group和level必须是数字..")
old_level = group_manager.get_group_level(group_id) old_level = group_manager.get_group_level(group_id)
group_manager.set_group_level(group_id, level) group_manager.set_group_level(group_id, level)
await add_group_level.send("修改成功...", at_sender=True) await add_group_level.send("修改成功...", at_sender=True)
if level > -1: if level > -1:
await bot.send_group_msg( await bot.send_group_msg(
group_id=int(group_id), message=f"管理员修改了此群权限:{old_level} -> {level}" group_id=int(group_id), message=f"管理员修改了此群权限:{old_level} -> {level}"
) )
logger.info(f"{event.user_id} 修改了 {group_id} 的权限:{level}") logger.info(f"{event.user_id} 修改了 {group_id} 的权限:{level}")
@my_group_level.handle() @my_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
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()
for module in data: for module in data:
if data[module]["level"] > level: if data[module]["level"] > level:
plugin_name = data[module]["cmd"][0] plugin_name = data[module]["cmd"][0]
if plugin_name == "pixiv": if plugin_name == "pixiv":
plugin_name = "搜图 p站排行" plugin_name = "搜图 p站排行"
tmp += f"{plugin_name}\n" tmp += f"{plugin_name}\n"
if tmp: if tmp:
tmp = "\n目前无法使用的功能:\n" + tmp tmp = "\n目前无法使用的功能:\n" + tmp
await my_group_level.finish(f"当前群权限:{level}{tmp}") await my_group_level.finish(f"当前群权限:{level}{tmp}")
@what_up_group_level.handle() @what_up_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
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, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).split() msg = get_message_text(event.json()).split()
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(self_id=int(bot.self_id))
] ]
group_list = [] group_list = []
for group in msg: for group in msg:
if is_number(group) and int(group) in all_group: if is_number(group) and int(group) in all_group:
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 state["_prefix"]["raw_command"] 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) + " " + state["_prefix"]["raw_command"]
) )
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 _(bot: Bot, event: MessageEvent, state: T_State):
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:
await show_group_whitelist.send("目前的群白名单:\n" + "\n".join(x)) await show_group_whitelist.send("目前的群白名单:\n" + "\n".join(x))
else: else:
await show_group_whitelist.send("没有任何群在群白名单...") await show_group_whitelist.send("没有任何群在群白名单...")
@group_auth.handle() @group_auth.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).split() msg = get_message_text(event.json()).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 state["_prefix"]["raw_command"][: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:
try: try:
group_info = await bot.get_group_info(group_id=group_id) group_info = await bot.get_group_info(group_id=group_id)
except ActionFailed: except ActionFailed:
group_info = { group_info = {
"group_id": group_id, "group_id": group_id,
"group_name": "_", "group_name": "_",
"max_member_count": -1, "max_member_count": -1,
"member_count": -1, "member_count": -1,
} }
await GroupInfo.add_group_info( await GroupInfo.add_group_info(
group_info["group_id"], group_info["group_id"],
group_info["group_name"], group_info["group_name"],
group_info["max_member_count"], group_info["max_member_count"],
group_info["member_count"], group_info["member_count"],
1, 1,
) )
else: else:
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} {state["_prefix"]["raw_command"][:2]}群认证..'
) )
+40 -40
View File
@@ -1,40 +1,40 @@
from nonebot import on_command from nonebot import on_command
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.rule import to_me from nonebot.rule import to_me
from utils.manager import ( from utils.manager import (
plugins2cd_manager, plugins2cd_manager,
plugins2settings_manager, plugins2settings_manager,
plugins2block_manager, plugins2block_manager,
group_manager, group_manager,
) )
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent
__zx_plugin_name__ = "重载插件配置 [Superuser]" __zx_plugin_name__ = "重载插件配置 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
重载插件配置 重载插件配置
指令: 指令:
重载插件配置 重载插件配置
""".strip() """.strip()
__plugin_des__ = "重载插件配置" __plugin_des__ = "重载插件配置"
__plugin_cmd__ = [ __plugin_cmd__ = [
"重载插件配置", "重载插件配置",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
reload_plugins_manager = on_command( reload_plugins_manager = on_command(
"重载插件限制", rule=to_me(), permission=SUPERUSER, priority=1, block=True "重载插件限制", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
@reload_plugins_manager.handle() @reload_plugins_manager.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
plugins2settings_manager.reload() plugins2settings_manager.reload()
plugins2cd_manager.reload() plugins2cd_manager.reload()
plugins2block_manager.reload() plugins2block_manager.reload()
group_manager.reload() group_manager.reload()
await reload_plugins_manager.send("重载完成...") await reload_plugins_manager.send("重载完成...")
+89 -89
View File
@@ -1,89 +1,89 @@
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.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, Message from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, Message
from utils.utils import get_message_at, get_message_text, 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
__zx_plugin_name__ = "用户权限管理 [Superuser]" __zx_plugin_name__ = "用户权限管理 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
增删改用户的权限 增删改用户的权限
指令: 指令:
添加权限 [at] [权限] 添加权限 [at] [权限]
添加权限 [qq] [group_id] [权限] 添加权限 [qq] [group_id] [权限]
删除权限 [at] 删除权限 [at]
""".strip() """.strip()
__plugin_des__ = "增删改用户的权限" __plugin_des__ = "增删改用户的权限"
__plugin_cmd__ = [ __plugin_cmd__ = [
"添加权限 [at] [权限]", "添加权限 [at] [权限]",
"添加权限 [qq] [group_id] [权限]", "添加权限 [qq] [group_id] [权限]",
"删除权限 [at]", "删除权限 [at]",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
super_cmd = on_command( super_cmd = on_command(
"添加管理", "添加管理",
aliases={"删除管理", "添加权限", "删除权限"}, aliases={"删除管理", "添加权限", "删除权限"},
priority=1, priority=1,
permission=SUPERUSER, permission=SUPERUSER,
block=True, block=True,
) )
@super_cmd.handle() @super_cmd.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
group_id = -1 group_id = -1
level = 0 level = 0
try: try:
args = get_message_text(event.json()).strip().split() args = get_message_text(event.json()).strip().split()
qq = get_message_at(event.json()) qq = get_message_at(event.json())
flag = -1 flag = -1
if not qq: if not qq:
if len(args) > 2: if len(args) > 2:
if is_number(args[0]) and is_number(args[1]) and is_number(args[2]): if is_number(args[0]) and is_number(args[1]) and is_number(args[2]):
qq = int(args[0]) qq = int(args[0])
group_id = int(args[1]) group_id = int(args[1])
level = int(args[2]) level = int(args[2])
flag = 1 flag = 1
else: else:
await super_cmd.finish("所有参数必须是数字!", at_sender=True) await super_cmd.finish("所有参数必须是数字!", at_sender=True)
else: else:
await super_cmd.finish( await super_cmd.finish(
"权限参数不完全\n\t格式:添加/删除权限 [at] [level]" "权限参数不完全\n\t格式:添加/删除权限 [at] [level]"
"\n\t格式:添加/删除权限 [qq] [group] [level]", "\n\t格式:添加/删除权限 [qq] [group] [level]",
at_sender=True, at_sender=True,
) )
else: else:
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 state["_prefix"]["raw_command"][:2] == "添加":
if is_number(args[0]): if is_number(args[0]):
level = int(args[0]) level = int(args[0])
else: else:
await super_cmd.finish("权限等级必须是数字!", at_sender=True) await super_cmd.finish("权限等级必须是数字!", at_sender=True)
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:
result = "管理已存在, 更新权限: " + str(level) result = "管理已存在, 更新权限: " + str(level)
else: else:
if await LevelUser.delete_level(qq, event.group_id): if await LevelUser.delete_level(qq, event.group_id):
result = "删除管理成功!" result = "删除管理成功!"
else: else:
result = "该账号无管理权限!" result = "该账号无管理权限!"
if flag == 2: if flag == 2:
await super_cmd.send(result) await super_cmd.send(result)
elif flag == 1: elif flag == 1:
await bot.send_group_msg( await bot.send_group_msg(
group_id=group_id, group_id=group_id,
message=Message(f"{at(qq)}管理员修改了你的权限" f"\n--------\n你当前的权限等级:{level}"), message=Message(f"{at(qq)}管理员修改了你的权限" f"\n--------\n你当前的权限等级:{level}"),
) )
await super_cmd.send("修改成功") await super_cmd.send("修改成功")
except Exception as e: except Exception as e:
await super_cmd.send("执行指令失败!") await super_cmd.send("执行指令失败!")
logger.error(f"执行指令失败 e:{e}") logger.error(f"执行指令失败 e:{e}")
+55 -55
View File
@@ -1,56 +1,56 @@
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.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent 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 get_message_text, is_number
from services.log import logger from services.log import logger
from utils.manager import group_manager from utils.manager import group_manager
__zx_plugin_name__ = "超级用户被动开关 [Superuser]" __zx_plugin_name__ = "超级用户被动开关 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
超级用户被动开关 超级用户被动开关
指令: 指令:
开启/关闭广播通知 开启/关闭广播通知
""".strip() """.strip()
__plugin_des__ = "超级用户被动开关" __plugin_des__ = "超级用户被动开关"
__plugin_cmd__ = [ __plugin_cmd__ = [
"开启/关闭广播通知", "开启/关闭广播通知",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
oc_gb = on_command( oc_gb = on_command(
"开启广播通知", "开启广播通知",
aliases={"关闭广播通知"}, aliases={"关闭广播通知"},
rule=to_me(), rule=to_me(),
permission=SUPERUSER, permission=SUPERUSER,
priority=1, priority=1,
block=True, block=True,
) )
@oc_gb.handle() @oc_gb.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
group = get_message_text(event.json()) group = get_message_text(event.json())
if group: if group:
if is_number(group): if is_number(group):
group = int(group) group = int(group)
for g in await bot.get_group_list(): for g in await bot.get_group_list():
if g["group_id"] == group: if g["group_id"] == group:
break break
else: else:
await oc_gb.finish("没有加入这个群...", at_sender=True) await oc_gb.finish("没有加入这个群...", at_sender=True)
if state["_prefix"]["raw_command"] == "开启广播通知": if state["_prefix"]["raw_command"] == "开启广播通知":
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:
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.close_group_task(group, "broadcast"), at_sender=True) await oc_gb.finish(await group_manager.close_group_task(group, "broadcast"), at_sender=True)
else: else:
await oc_gb.finish("请输入正确的群号", at_sender=True) await oc_gb.finish("请输入正确的群号", at_sender=True)
else: else:
await oc_gb.finish("请输入要关闭广播的群号", at_sender=True) await oc_gb.finish("请输入要关闭广播的群号", at_sender=True)
+71 -71
View File
@@ -1,71 +1,71 @@
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.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent 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
from models.group_info import GroupInfo from models.group_info import GroupInfo
from models.friend_user import FriendUser from models.friend_user import FriendUser
__zx_plugin_name__ = "更新群/好友信息 [Superuser]" __zx_plugin_name__ = "更新群/好友信息 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
更新群/好友信息 更新群/好友信息
指令: 指令:
更新群信息 更新群信息
更新好友信息 更新好友信息
""".strip() """.strip()
__plugin_des__ = "更新群/好友信息" __plugin_des__ = "更新群/好友信息"
__plugin_cmd__ = [ __plugin_cmd__ = [
"更新群信息", "更新群信息",
"更新好友信息", "更新好友信息",
] ]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
update_group_info = on_command( update_group_info = on_command(
"更新群信息", rule=to_me(), permission=SUPERUSER, priority=1, block=True "更新群信息", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
update_friend_info = on_command( update_friend_info = on_command(
"更新好友信息", rule=to_me(), permission=SUPERUSER, priority=1, block=True "更新好友信息", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
@update_group_info.handle() @update_group_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
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]
num = 0 num = 0
rst = "" rst = ""
for g in gl: for g in gl:
group_info = await bot.get_group_info(group_id=g) group_info = await bot.get_group_info(group_id=g)
if await GroupInfo.add_group_info( if await GroupInfo.add_group_info(
group_info["group_id"], group_info["group_id"],
group_info["group_name"], group_info["group_name"],
group_info["max_member_count"], group_info["max_member_count"],
group_info["member_count"], group_info["member_count"],
): ):
num += 1 num += 1
logger.info(f"自动更新群组 {g} 信息成功") logger.info(f"自动更新群组 {g} 信息成功")
else: else:
logger.info(f"自动更新群组 {g} 信息失败") logger.info(f"自动更新群组 {g} 信息失败")
rst += f"{g} 更新失败\n" rst += f"{g} 更新失败\n"
await update_group_info.send(f"成功更新了 {num} 个群的信息\n{rst[:-1]}") await update_group_info.send(f"成功更新了 {num} 个群的信息\n{rst[:-1]}")
@update_friend_info.handle() @update_friend_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
num = 0 num = 0
rst = "" rst = ""
fl = await get_bot().get_friend_list() fl = await get_bot().get_friend_list()
for f in fl: for f in fl:
if await FriendUser.add_friend_info(f["user_id"], f["nickname"]): if await FriendUser.add_friend_info(f["user_id"], f["nickname"]):
logger.info(f'自动更新好友 {f["user_id"]} 信息成功') logger.info(f'自动更新好友 {f["user_id"]} 信息成功')
num += 1 num += 1
else: else:
logger.warning(f'自动更新好友 {f["user_id"]} 信息失败') logger.warning(f'自动更新好友 {f["user_id"]} 信息失败')
rst += f'{f["user_id"]} 更新失败\n' rst += f'{f["user_id"]} 更新失败\n'
await update_friend_info.send(f"成功更新了 {num} 个好友的信息\n{rst[:-1]}") await update_friend_info.send(f"成功更新了 {num} 个好友的信息\n{rst[:-1]}")
+30 -30
View File
@@ -1,30 +1,30 @@
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.typing import T_State
from nonebot.adapters import Bot, Event 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 from pathlib import Path
__zx_plugin_name__ = '超级用户帮助 [Superuser]' __zx_plugin_name__ = '超级用户帮助 [Superuser]'
superuser_help_image = Path(IMAGE_PATH) / 'superuser_help.png' superuser_help_image = Path(IMAGE_PATH) / 'superuser_help.png'
if superuser_help_image.exists(): if superuser_help_image.exists():
superuser_help_image.unlink() superuser_help_image.unlink()
super_help = on_command( super_help = on_command(
"超级用户帮助", rule=to_me(), priority=1, permission=SUPERUSER, block=True "超级用户帮助", rule=to_me(), priority=1, permission=SUPERUSER, block=True
) )
@super_help.handle() @super_help.handle()
async def _(bot: Bot, event: Event, state: T_State): async def _(bot: Bot, event: Event, state: T_State):
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)
await super_help.finish(x) await super_help.finish(x)
View File
Regular → Executable
+35 -35
View File
@@ -1,35 +1,35 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, Event from nonebot.adapters.cqhttp import Bot, Event
from nonebot.typing import T_State from nonebot.typing import T_State
from utils.message_builder import image from utils.message_builder import image
__zx_plugin_name__ = "更新信息" __zx_plugin_name__ = "更新信息"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
更新信息 更新信息
指令: 指令:
更新信息 更新信息
""".strip() """.strip()
__plugin_des__ = "当前版本的更新信息" __plugin_des__ = "当前版本的更新信息"
__plugin_cmd__ = ["更新信息"] __plugin_cmd__ = ["更新信息"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ["更新信息"], "cmd": ["更新信息"],
} }
update_info = on_command("更新信息", aliases={"更新日志"}, priority=5, block=True) update_info = on_command("更新信息", aliases={"更新日志"}, priority=5, block=True)
@update_info.handle() @update_info.handle()
async def _(bot: Bot, event: Event, state: T_State): async def _(bot: Bot, event: Event, state: T_State):
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"))
else: else:
await update_info.finish("目前没有更新信息哦") await update_info.finish("目前没有更新信息哦")
+5 -4
View File
@@ -112,10 +112,11 @@ class ConfigsManager:
""" """
key = key.upper() key = key.upper()
if module in self._data.keys(): if module in self._data.keys():
if self._data[module].get(key) is not None: for key in [key, f"{key} [LEVEL]"]:
if self._data[module][key]["value"] is None: if self._data[module].get(key) is not None:
return self._data[module][key]["default_value"] if self._data[module][key]["value"] is None:
return self._data[module][key]["value"] return self._data[module][key]["default_value"]
return self._data[module][key]["value"]
return None return None
def get(self, key: str): def get(self, key: str):
Regular → Executable
View File
Regular → Executable
+1 -1
View File
@@ -82,7 +82,7 @@ class BanUser(db.Model):
参数: 参数:
:param user_qq: 目标用户qq号 :param user_qq: 目标用户qq号
:param ban_level: 使用ban命令用户的权限 :param ban_level: 使用ban命令用户的权限
:param duration: ban时长 :param duration: ban时长,秒
""" """
query = cls.query.where((cls.user_qq == user_qq)) query = cls.query.where((cls.user_qq == user_qq))
query = query.with_for_update() query = query.with_for_update()
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
-2
View File
@@ -24,8 +24,6 @@ __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = 'HibiKier'
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["Ai", "ai", "AI", "aI"], "cmd": ["Ai", "ai", "AI", "aI"],
} }
__plugin_configs__ = { __plugin_configs__ = {
Regular → Executable
+65 -65
View File
@@ -1,13 +1,12 @@
import os import os
import random import random
import re import re
from utils.http_utils import AsyncHttpx
import aiohttp
from aiohttp.client import ClientSession
from configs.path_config import IMAGE_PATH, DATA_PATH from configs.path_config import IMAGE_PATH, DATA_PATH
from services.log import logger from services.log import logger
from utils.message_builder import image, face from utils.message_builder import image, face
from configs.config import Config, NICKNAME from configs.config import Config, NICKNAME
from .utils import ai_message_manager
try: try:
import ujson as json import ujson as json
@@ -26,7 +25,7 @@ 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:
""" """
获取 AI 返回值,顺序:图灵 -> 青云客 获取 AI 返回值,顺序: 特殊回复 -> 图灵 -> 青云客
:param text: 问题 :param text: 问题
:param img_url: 图片链接 :param img_url: 图片链接
:param user_id: 用户id :param user_id: 用户id
@@ -34,6 +33,11 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
:return: 回答 :return: 回答
""" """
global index global index
ai_message_manager.add_message(user_id, text)
special_rst = await ai_message_manager.get_result(user_id, nickname)
if special_rst:
ai_message_manager.add_result(user_id, special_rst)
return special_rst
if index == 5: if index == 5:
index = 0 index = 0
if len(text) < 6 and random.random() < 0.6: if len(text) < 6 and random.random() < 0.6:
@@ -41,10 +45,9 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
for key in keys: for key in keys:
if text.find(key) != -1: if text.find(key) != -1:
return random.choice(anime_data[key]).replace("你", nickname) return random.choice(anime_data[key]).replace("你", nickname)
async with aiohttp.ClientSession() as sess: rst = await tu_ling(text, img_url, user_id)
rst = await tu_ling(text, img_url, user_id, sess) if not rst:
if not rst: rst = await xie_ai(text)
rst = await xie_ai(text, sess)
if not rst: if not rst:
return no_result() return no_result()
if nickname: if nickname:
@@ -55,23 +58,25 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
if nickname.find("大人") == -1: if nickname.find("大人") == -1:
nickname += "大~人~" nickname += "大~人~"
rst = rst.replace("小主人", nickname).replace("小朋友", nickname) rst = rst.replace("小主人", nickname).replace("小朋友", nickname)
ai_message_manager.add_result(user_id, rst)
print(ai_message_manager)
return rst return rst
# 图灵接口 # 图灵接口
async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession) -> str: async def tu_ling(text: str, img_url: str, user_id: int) -> str:
""" """
获取图灵接口的回复 获取图灵接口的回复
:param text: 问题 :param text: 问题
:param img_url: 图片链接 :param img_url: 图片链接
:param user_id: 用户id :param user_id: 用户id
:param sess: AIOHTTP SESSION
:return: 图灵回复 :return: 图灵回复
""" """
global index global index
TL_KEY = Config.get_config("ai", "TL_KEY") TL_KEY = Config.get_config("ai", "TL_KEY")
req = None
if not TL_KEY: if not TL_KEY:
return '' return ""
try: try:
if text: if text:
req = { req = {
@@ -98,62 +103,59 @@ async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession) ->
index = 0 index = 0
return "" return ""
text = "" text = ""
async with sess.post(url, json=req) as response: response = await AsyncHttpx.post(url, json=req)
if response.status != 200: if response.status_code != 200:
return no_result() return no_result()
resp_payload = json.loads(await response.text()) resp_payload = json.loads(response.text)
if int(resp_payload["intent"]["code"]) in [4003]: if int(resp_payload["intent"]["code"]) in [4003]:
return "" return ""
if resp_payload["results"]: if resp_payload["results"]:
for result in resp_payload["results"]: for result in resp_payload["results"]:
if result["resultType"] == "text": if result["resultType"] == "text":
text = result["values"]["text"] text = result["values"]["text"]
if "请求次数超过" in text: if "请求次数超过" in text:
text = "" text = ""
return text return text
# 屑 AI # 屑 AI
async def xie_ai(text: str, sess: ClientSession) -> str: async def xie_ai(text: str) -> str:
""" """
获取青云客回复 获取青云客回复
:param text: 问题 :param text: 问题
:param sess: AIOHTTP SESSION
:return: 青云可回复 :return: 青云可回复
""" """
async with sess.get( res = await AsyncHttpx.get(f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}")
f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}" content = ""
) as res: data = json.loads(res.text)
content = "" if data["result"] == 0:
data = json.loads(await res.text()) content = data["content"]
if data["result"] == 0: if "菲菲" in content:
content = data["content"] content = content.replace("菲菲", NICKNAME)
if "菲菲" in content: if "艳儿" in content:
content = content.replace("菲菲", NICKNAME) content = content.replace("艳儿", NICKNAME)
if "艳儿" in content: if "公众号" in content:
content = content.replace("艳儿", NICKNAME) content = ""
if "公众号" in content: if "{br}" in content:
content = "" content = content.replace("{br}", "\n")
if "{br}" in content: if "提示" in content:
content = content.replace("{br}", "\n") content = content[: content.find("提示")]
if "提示" in content: if "淘宝" in content:
content = content[: content.find("提示")] return ""
if "淘宝" in content: while True:
return "" r = re.search("{face:(.*)}", content)
while True: if r:
r = re.search("{face:(.*)}", content) id_ = r.group(1)
if r: content = content.replace(
id_ = r.group(1) "{" + f"face:{id_}" + "}", str(face(int(id_)))
content = content.replace( )
"{" + f"face:{id_}" + "}", str(face(int(id_))) else:
) break
else: return (
break content
return ( if not content and not Config.get_config("ai", "ALAPI_AI_CHECK")
content else await check_text(content)
if not content and not Config.get_config("ai", "ALAPI_AI_CHECK") )
else await check_text(content, sess)
)
def hello() -> str: def hello() -> str:
@@ -196,21 +198,19 @@ def no_result() -> str:
) )
async def check_text(text: str, sess: ClientSession) -> str: async def check_text(text: str) -> str:
""" """
ALAPI文本检测,主要针对青云客API,检测为恶俗文本改为无回复的回答 ALAPI文本检测,主要针对青云客API,检测为恶俗文本改为无回复的回答
:param text: 回复 :param text: 回复
:param sess: AIOHTTP SESSION
""" """
if not Config.get_config("alapi", "ALAPI_TOKEN"): if not Config.get_config("alapi", "ALAPI_TOKEN"):
return text return text
params = {"token": Config.get_config("alapi", "ALAPI_TOKEN"), "text": text} params = {"token": Config.get_config("alapi", "ALAPI_TOKEN"), "text": text}
try: try:
async with sess.get(check_url, timeout=2, params=params) as response: data = (await AsyncHttpx.get(check_url, timeout=2, params=params)).json()
data = await response.json() if data["code"] == 200:
if data["code"] == 200: if data["data"]["conclusion_type"] == 2:
if data["data"]["conclusion_type"] == 2: return ""
return ""
except Exception as e: except Exception as e:
logger.error(f"检测违规文本错误...{type(e)}:{e}") logger.error(f"检测违规文本错误...{type(e)}:{e}")
return text return text
+137
View File
@@ -0,0 +1,137 @@
from utils.manager import StaticData
from configs.config import NICKNAME
from models.ban_user import BanUser
from typing import Optional
import random
import time
class AiMessageManager(StaticData):
def __init__(self):
super().__init__(None)
self._same_message = [
"为什么要发一样的话?",
"请不要再重复对我说一句话了,不然我就要生气了!",
"别再发这句话了,我已经知道了...",
"你是只会说这一句话吗?",
"[*],你发我也发!",
"[uname],[*]",
f"救命!有笨蛋一直给{NICKNAME}发一样的话!",
"这句话你已经给我发了{}次了,再发就生气!",
]
self._repeat_message = [
f"请不要学{NICKNAME}说话",
f"为什么要一直学{NICKNAME}说话?",
"你再学!你再学我就生气了!",
f"呜呜,你是想欺负{NICKNAME}嘛..",
"[uname]不要再学我说话了!",
"再学我说话,我就把你拉进黑名单(生气",
"你再学![uname]是个笨蛋!",
"你已经学我说话{}次了!别再学了!",
]
def add_message(self, user_id: int, message: str):
"""
添加用户消息
:param user_id: 用户id
:param message: 消息内容
"""
if message:
if self._data.get(user_id) is None:
self._data[user_id] = {
"time": time.time(),
"message": [],
"result": [],
"repeat_count": 0,
}
if time.time() - self._data[user_id]["time"] > 60 * 10:
self._data[user_id]["message"].clear()
self._data[user_id]["time"] = time.time()
self._data[user_id]["message"].append(message.strip())
def add_result(self, user_id: int, message: str):
"""
添加回复用户的消息
:param user_id: 用户id
:param message: 回复消息内容
"""
if message:
if self._data.get(user_id) is None:
self._data[user_id] = {
"time": time.time(),
"message": [],
"result": [],
"repeat_count": 0,
}
if time.time() - self._data[user_id]["time"] > 60 * 10:
self._data[user_id]["result"].clear()
self._data[user_id]["repeat_count"] = 0
self._data[user_id]["time"] = time.time()
self._data[user_id]["result"].append(message.strip())
async def get_result(self, user_id: int, nickname: str) -> Optional[str]:
"""
特殊消息特殊回复
:param user_id: 用户id
:param nickname: 用户昵称
"""
if len(self._data[user_id]["message"]) < 2:
return None
msg = await self._get_user_repeat_message_result(user_id)
if not msg:
msg = await self._get_user_same_message_result(user_id)
if msg:
if "[uname]" in msg:
msg = msg.replace("[uname]", nickname)
if not msg.startswith("生气了!你好烦,闭嘴!") and "[*]" in msg:
msg = msg.replace("[*]", self._data[user_id]["message"][-1])
return msg
async def _get_user_same_message_result(self, user_id: int) -> Optional[str]:
"""
重复消息回复
:param user_id: 用户id
"""
msg = self._data[user_id]["message"][-1]
cnt = 0
_tmp = self._data[user_id]["message"][:-1]
_tmp.reverse()
for s in _tmp:
if s == msg:
cnt += 1
else:
break
if cnt > 1:
if random.random() < 0.5 and cnt > 3:
rand = random.randint(60, 300)
await BanUser.ban(user_id, 9, rand)
self._data[user_id]["message"].clear()
return f"生气了!你好烦,闭嘴!给我老实安静{rand}秒"
return random.choice(self._same_message).format(cnt)
return None
async def _get_user_repeat_message_result(self, user_id: int) -> Optional[str]:
"""
复读真寻的消息回复
:param user_id: 用户id
"""
msg = self._data[user_id]["message"][-1]
if self._data[user_id]["result"]:
rst = self._data[user_id]["result"][-1]
else:
return None
if msg == rst:
self._data[user_id]["repeat_count"] += 1
cnt = self._data[user_id]["repeat_count"]
if cnt > 1:
if random.random() < 0.5 and cnt > 3:
rand = random.randint(60, 300)
await BanUser.ban(user_id, 9, rand)
self._data[user_id]["result"].clear()
self._data[user_id]["repeat_count"] = 0
return f"生气了!你好烦,闭嘴!给我老实安静{rand}秒"
return random.choice(self._repeat_message).format(cnt)
return None
ai_message_manager = AiMessageManager()
Regular → Executable
View File
Regular → Executable
+46 -46
View File
@@ -1,46 +1,46 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State 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__ = "网易云热评"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
到点了,还是防不了下塔 到点了,还是防不了下塔
指令: 指令:
网易云热评/到点了/12点了 网易云热评/到点了/12点了
""".strip() """.strip()
__plugin_des__ = "生了个人,我很抱歉" __plugin_des__ = "生了个人,我很抱歉"
__plugin_cmd__ = ["网易云热评", "到点了", "12点了"] __plugin_cmd__ = ["网易云热评", "到点了", "12点了"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ["网易云热评", "网易云评论", "到点了", "12点了"], "cmd": ["网易云热评", "网易云评论", "到点了", "12点了"],
} }
comments_163 = on_command( comments_163 = on_command(
"网易云热评", aliases={"网易云评论", "到点了", "12点了"}, priority=5, block=True "网易云热评", aliases={"网易云评论", "到点了", "12点了"}, priority=5, block=True
) )
comments_163_url = "https://v2.alapi.cn/api/comment" 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 _(bot: Bot, event: MessageEvent, state: T_State):
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)
data = data["data"] data = data["data"]
comment = data["comment_content"] comment = data["comment_content"]
song_name = data["title"] song_name = data["title"]
await comments_163.send(f"{comment}\n\t——《{song_name}》") await comments_163.send(f"{comment}\n\t——《{song_name}》")
logger.info( logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送网易云热评: {comment} \n\t\t————{song_name}" f" 发送网易云热评: {comment} \n\t\t————{song_name}"
) )
Regular → Executable
+48 -48
View File
@@ -1,48 +1,48 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.typing import T_State 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 utils.utils import get_message_text
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封面"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
b封面 [链接/av/bv/cv/直播id] b封面 [链接/av/bv/cv/直播id]
示例:b封面 av86863038 示例:b封面 av86863038
""".strip() """.strip()
__plugin_des__ = "快捷的b站视频封面获取方式" __plugin_des__ = "快捷的b站视频封面获取方式"
__plugin_cmd__ = ["b封面/B封面"] __plugin_cmd__ = ["b封面/B封面"]
__plugin_type__ = ("一些工具",) __plugin_type__ = ("一些工具",)
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ["b封面", "B封面"], "cmd": ["b封面", "B封面"],
} }
cover = on_command("b封面", aliases={"B封面"}, priority=5, block=True) cover = on_command("b封面", aliases={"B封面"}, priority=5, block=True)
cover_url = "https://v2.alapi.cn/api/bilibili/cover" cover_url = "https://v2.alapi.cn/api/bilibili/cover"
@cover.handle() @cover.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
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:
await cover.finish(data, at_sender=True) await cover.finish(data, at_sender=True)
data = data["data"] data = data["data"]
title = data["title"] title = data["title"]
img = data["cover"] img = data["cover"]
await cover.send(Message(f"title:{title}\n{image(img)}")) await cover.send(Message(f"title:{title}\n{image(img)}"))
logger.info( logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 获取b站封面: {title} url:{img}" f" 获取b站封面: {title} url:{img}"
) )
Regular → Executable
+49 -51
View File
@@ -1,51 +1,49 @@
from nonebot.adapters.cqhttp import MessageSegment from nonebot.adapters.cqhttp import MessageSegment
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
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
from configs.config import Config from configs.config import Config
import aiohttp 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) -> "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")
async with aiohttp.ClientSession() as session: try:
try: data = (await AsyncHttpx.get(url, params=params, timeout=5)).json()
async with session.get(url, timeout=2, params=params) as response: if data["code"] == 200:
data = await response.json() if not data["data"]:
if data["code"] == 200: return "没有搜索到...", 997
if not data["data"]: return data, 200
return "没有搜索到...", 997 else:
return data, 200 return f'发生了错误...code:{data["code"]}', 999
else: except TimeoutError:
return f'发生了错误...code:{data["code"]}', 999 return "超时了....", 998
except TimeoutError:
return "超时了....", 998
def gen_wbtop_pic(data: dict) -> MessageSegment:
"""
def gen_wbtop_pic(data: dict) -> MessageSegment: 生成微博热搜图片
""" :param data: 微博热搜数据
生成微博热搜图片 """
:param data: 微博热搜数据 bk = CreateImg(700, 32 * 50 + 280, 700, 32, color="#797979")
""" wbtop_bk = CreateImg(700, 280, background=f"{IMAGE_PATH}/other/webtop.png")
bk = CreateImg(700, 32 * 50 + 280, 700, 32, color="#797979") bk.paste(wbtop_bk)
wbtop_bk = CreateImg(700, 280, background=f"{IMAGE_PATH}/other/webtop.png") text_bk = CreateImg(700, 32 * 50, 700, 32, color="#797979")
bk.paste(wbtop_bk) for i, data in enumerate(data):
text_bk = CreateImg(700, 32 * 50, 700, 32, color="#797979") title = f"{i+1}. {data['hot_word']}"
for i, data in enumerate(data): hot = data["hot_word_num"]
title = f"{i+1}. {data['hot_word']}" img = CreateImg(700, 30, font_size=20)
hot = data["hot_word_num"] w, h = img.getsize(title)
img = CreateImg(700, 30, font_size=20) img.text((10, int((30 - h) / 2)), title)
w, h = img.getsize(title) img.text((580, int((30 - h) / 2)), hot)
img.text((10, int((30 - h) / 2)), title) text_bk.paste(img)
img.text((580, int((30 - h) / 2)), hot) bk.paste(text_bk, (0, 280))
text_bk.paste(img) return image(b64=bk.pic2bs4())
bk.paste(text_bk, (0, 280))
return image(b64=bk.pic2bs4())
+48
View File
@@ -0,0 +1,48 @@
from nonebot import on_command
from services.log import logger
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from utils.http_utils import AsyncHttpx
from configs.config import Config
from .data_source import get_data
__zx_plugin_name__ = "鸡汤"
__plugin_usage__ = """
usage:
不喝点什么感觉有点不舒服
指令:
鸡汤
""".strip()
__plugin_des__ = "喏,亲手为你煮的鸡汤"
__plugin_cmd__ = ["鸡汤"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["鸡汤", "毒鸡汤"],
}
url = "https://v2.alapi.cn/api/soul"
jitang = on_command("鸡汤", aliases={"毒鸡汤"}, priority=5, block=True)
@jitang.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
try:
data, code = await get_data(url)
if code != 200:
await jitang.finish(data, at_sender=True)
await jitang.send(data["data"]["content"])
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送鸡汤:" + data["data"]["content"]
)
except Exception as e:
await jitang.send("鸡汤煮坏掉了...")
logger.error(f"鸡汤煮坏掉了 {type(e)}:{e}")
Regular → Executable
+42 -42
View File
@@ -1,42 +1,42 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State 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:
平白无故念首诗 平白无故念首诗
示例:念诗/来首诗/念首诗 示例:念诗/来首诗/念首诗
""" """
__plugin_des__ = "为什么突然文艺起来了!" __plugin_des__ = "为什么突然文艺起来了!"
__plugin_cmd__ = ["念诗/来首诗/念首诗"] __plugin_cmd__ = ["念诗/来首诗/念首诗"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ["念诗", "来首诗", "念首诗"], "cmd": ["念诗", "来首诗", "念首诗"],
} }
poetry = on_command("念诗", aliases={"来首诗", "念首诗"}, priority=5, block=True) poetry = on_command("念诗", aliases={"来首诗", "念首诗"}, priority=5, block=True)
poetry_url = "https://v2.alapi.cn/api/shici" poetry_url = "https://v2.alapi.cn/api/shici"
@poetry.handle() @poetry.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
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)
data = data["data"] data = data["data"]
content = data["content"] content = data["content"]
title = data["origin"] title = data["origin"]
author = data["author"] author = data["author"]
await poetry.send(f"{content}\n\t——{author}《{title}》") await poetry.send(f"{content}\n\t——{author}《{title}》")
logger.info( logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送古诗: f'{content}\n\t--{author}《{title}》'" f" 发送古诗: f'{content}\n\t--{author}《{title}》'"
) )
Regular → Executable
+71 -76
View File
@@ -1,76 +1,71 @@
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State from nonebot.typing import T_State
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.browser import get_browser from utils.utils import get_message_text, is_number
from utils.utils import get_message_text, is_number 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 utils.http_utils import AsyncPlaywright
import asyncio import asyncio
__zx_plugin_name__ = '微博热搜' __zx_plugin_name__ = "微博热搜"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
在QQ上吃个瓜 在QQ上吃个瓜
指令: 指令:
微博热搜:发送实时热搜 微博热搜:发送实时热搜
微博热搜 [id]:截图该热搜页面 微博热搜 [id]:截图该热搜页面
示例:微博热搜 5 示例:微博热搜 5
""".strip() """.strip()
__plugin_des__ = '刚买完瓜,在吃瓜现场' __plugin_des__ = "刚买完瓜,在吃瓜现场"
__plugin_cmd__ = ['微博热搜', '微博热搜 [id]'] __plugin_cmd__ = ["微博热搜", "微博热搜 [id]"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ['微博热搜'], "cmd": ["微博热搜"],
} }
wbtop = on_command("wbtop", aliases={'微博热搜'}, priority=5, block=True) wbtop = on_command("wbtop", aliases={"微博热搜"}, priority=5, block=True)
wbtop_url = 'https://v2.alapi.cn/api/new/wbtop' wbtop_url = "https://v2.alapi.cn/api/new/wbtop"
wbtop_data = [] wbtop_data = []
@wbtop.handle() @wbtop.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
global wbtop_data global wbtop_data
msg = get_message_text(event.json()) msg = get_message_text(event.json())
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:
await wbtop.finish(data, at_sender=True) await wbtop.finish(data, at_sender=True)
wbtop_data = data['data'] wbtop_data = data["data"]
if not msg: if not msg:
img = await asyncio.get_event_loop().run_in_executor(None, gen_wbtop_pic, wbtop_data) img = await asyncio.get_event_loop().run_in_executor(
await wbtop.send(img) None, gen_wbtop_pic, wbtop_data
logger.info( )
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" await wbtop.send(img)
f" 查询微博热搜") logger.info(
if is_number(msg) and 0 < int(msg) <= 50: f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
url = wbtop_data[int(msg) - 1]['url'] f" 查询微博热搜"
browser = await get_browser() )
page = None if is_number(msg) and 0 < int(msg) <= 50:
try: url = wbtop_data[int(msg) - 1]["url"]
if not browser: try:
logger.warning('获取 browser 失败,请部署至 linux 环境....') await wbtop.send("开始截取数据...")
await wbtop.finish('获取 browser 对象失败...') img = await AsyncPlaywright.screenshot(
page = await browser.new_page() url,
await page.goto(url, wait_until='networkidle', timeout=10000) f"{IMAGE_PATH}/temp/wbtop_{event.user_id}.png",
await page.set_viewport_size({"width": 2560, "height": 1080}) "#pl_feedlist_index",
await asyncio.sleep(5) sleep=5
div = await page.query_selector("#pl_feedlist_index") )
await div.screenshot(path=f'{IMAGE_PATH}/temp/wbtop_{event.user_id}.png', timeout=100000) await wbtop.send(img)
await page.close() except Exception as e:
await wbtop.send(image(f'wbtop_{event.user_id}.png', 'temp')) logger.error(f"微博热搜截图出错... {type(e)}: {e}")
except Exception as e: await wbtop.send("发生了一些错误.....")
logger.error(f'微博热搜截图出错... {type(e)}: {e}')
if page:
await page.close()
await wbtop.send('发生了一些错误.....')
Regular → Executable
+236 -235
View File
@@ -1,235 +1,236 @@
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.cqhttp import Bot, MessageEvent, GroupMessageEvent, Message
from .data_source import ( from .data_source import (
add_live_sub, add_live_sub,
delete_sub, delete_sub,
add_up_sub, add_up_sub,
add_season_sub, add_season_sub,
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 get_message_text, 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
import nonebot import nonebot
__zx_plugin_name__ = "B站订阅" __zx_plugin_name__ = "B站订阅"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
B站直播,番剧,UP动态开播等提醒 B站直播,番剧,UP动态开播等提醒
主播订阅相当于 直播间订阅 + UP订阅 主播订阅相当于 直播间订阅 + UP订阅
指令:[示例Id乱打的,仅做示例] 指令:[示例Id乱打的,仅做示例]
添加订阅 ['主播'/'UP'/'番剧'] [id/链接/番名] 添加订阅 ['主播'/'UP'/'番剧'] [id/链接/番名]
删除订阅 [id] 删除订阅 [id]
查看订阅 查看订阅
示例:添加订阅主播 2345344 <-(直播房间id) 示例:添加订阅主播 2345344 <-(直播房间id)
示例:添加订阅UP 2355543 <-(个人主页id) 示例:添加订阅UP 2355543 <-(个人主页id)
示例:添加订阅番剧 史莱姆 <-(支持模糊搜索) 示例:添加订阅番剧 史莱姆 <-(支持模糊搜索)
示例:添加订阅番剧 125344 <-(番剧id) 示例:添加订阅番剧 125344 <-(番剧id)
示例:删除订阅 2324344 <-(任意id,通过查看订阅获取) 示例:删除订阅 2324344 <-(任意id,通过查看订阅获取)
""".strip() """.strip()
__plugin_des__ = "非常便利的B站订阅通知" __plugin_des__ = "非常便利的B站订阅通知"
__plugin_cmd__ = ["添加订阅 [主播/UP/番剧] [id/链接/番名]", "删除订阅 [id]", "查看订阅"] __plugin_cmd__ = ["添加订阅 [主播/UP/番剧] [id/链接/番名]", "删除订阅 [id]", "查看订阅"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ["B站订阅", "b站订阅", "添加订阅", "删除订阅", "查看订阅"], "cmd": ["B站订阅", "b站订阅", "添加订阅", "删除订阅", "查看订阅"],
} }
__plugin_configs__ = { __plugin_configs__ = {
"GROUP_BILIBILI_SUB_LEVEL": { "GROUP_BILIBILI_SUB_LEVEL": {
"value": 5, "value": 5,
"help": "群内bilibili订阅需要管理的权限", "help": "群内bilibili订阅需要管理的权限",
"default_value": 5, "default_value": 5,
} }
} }
add_sub = on_command("添加订阅", priority=5, block=True) add_sub = on_command("添加订阅", priority=5, block=True)
del_sub = on_command("删除订阅", priority=5, block=True) del_sub = on_command("删除订阅", priority=5, block=True)
show_sub_info = on_command("查看订阅", priority=5, block=True) show_sub_info = on_command("查看订阅", priority=5, block=True)
driver: Driver = nonebot.get_driver() driver: Driver = nonebot.get_driver()
sub_manager: Optional[SubManager] = None sub_manager: Optional[SubManager] = None
@driver.on_startup @driver.on_startup
async def _(): async def _():
global sub_manager global sub_manager
sub_manager = SubManager() sub_manager = SubManager()
@add_sub.args_parser @add_sub.args_parser
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
season_data = state["season_data"] season_data = state["season_data"]
msg = get_message_text(event.json()) msg = get_message_text(event.json())
if not is_number(msg) or int(msg) < 1 or int(msg) > len(season_data): if not is_number(msg) or int(msg) < 1 or int(msg) > len(season_data):
await add_sub.reject("Id必须为数字且在范围内!请重新输入...") await add_sub.reject("Id必须为数字且在范围内!请重新输入...")
state["id"] = season_data[int(msg) - 1]["media_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 _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).split() msg = get_message_text(event.json()).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]
id_ = "" id_ = ""
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
if not await LevelUser.check_level( if not await LevelUser.check_level(
event.user_id, event.user_id,
event.group_id, event.group_id,
Config.get_config("bilibili_sub", "GROUP_BILIBILI_SUB_LEVEL"), Config.get_config("bilibili_sub", "GROUP_BILIBILI_SUB_LEVEL"),
): ):
await add_sub.finish( await add_sub.finish(
f"您的权限不足,群内订阅的需要 {Config.get_config('bilibili_sub', 'GROUP_BILIBILI_SUB_LEVEL')} 级权限..", f"您的权限不足,群内订阅的需要 {Config.get_config('bilibili_sub', 'GROUP_BILIBILI_SUB_LEVEL')} 级权限..",
at_sender=True, at_sender=True,
) )
sub_user = f"{event.user_id}:{event.group_id}" sub_user = f"{event.user_id}:{event.group_id}"
else: else:
sub_user = f"{event.user_id}" sub_user = f"{event.user_id}"
state["sub_type"] = sub_type state["sub_type"] = sub_type
state["sub_user"] = sub_user state["sub_user"] = sub_user
if len(msg) > 1: if len(msg) > 1:
if "http" in msg[1]: if "http" in msg[1]:
msg[1] = msg[1].split("?")[0] msg[1] = msg[1].split("?")[0]
msg[1] = msg[1][:-1] if msg[1][-1] == "/" else msg[1] msg[1] = msg[1][:-1] if msg[1][-1] == "/" else msg[1]
msg[1] = msg[1].split("/")[-1] msg[1] = msg[1].split("/")[-1]
id_ = msg[1][2:] if msg[1].startswith("md") else msg[1] id_ = msg[1][2:] if msg[1].startswith("md") else msg[1]
if not is_number(id_): if not is_number(id_):
if sub_type in ["season", "动漫", "番剧"]: if sub_type in ["season", "动漫", "番剧"]:
rst = "*以为您找到以下番剧,请输入Id选择:*\n" rst = "*以为您找到以下番剧,请输入Id选择:*\n"
state["season_data"] = await get_media_id(id_) state["season_data"] = await get_media_id(id_)
if len(state["season_data"]) == 0: if len(state["season_data"]) == 0:
await add_sub.finish(f"未找到番剧:{msg}") await add_sub.finish(f"未找到番剧:{msg}")
for i, x in enumerate(state["season_data"]): for i, x in enumerate(state["season_data"]):
rst += f'{i + 1}.{state["season_data"][x]["title"]}\n----------\n' rst += f'{i + 1}.{state["season_data"][x]["title"]}\n----------\n'
await add_sub.send("\n".join(rst.split("\n")[:-1])) await add_sub.send("\n".join(rst.split("\n")[:-1]))
else: else:
await add_sub.finish("Id 必须为全数字!") await add_sub.finish("Id 必须为全数字!")
else: else:
state["id"] = int(id_) state["id"] = int(id_)
@add_sub.got("id") @add_sub.got("id")
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
sub_type = state["sub_type"] sub_type = state["sub_type"]
sub_user = state["sub_user"] sub_user = state["sub_user"]
id_ = state["id"] id_ = state["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", "用户"]:
await add_sub.send(await add_up_sub(id_, sub_user)) await add_sub.send(await add_up_sub(id_, sub_user))
elif sub_type in ["season", "动漫", "番剧"]: elif sub_type in ["season", "动漫", "番剧"]:
await add_sub.send(await add_season_sub(id_, sub_user)) await add_sub.send(await add_season_sub(id_, sub_user))
else: else:
await add_sub.finish("参数错误,第一参数必须为:主播/up/番剧!") await add_sub.finish("参数错误,第一参数必须为:主播/up/番剧!")
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 添加订阅:{sub_type} -> {sub_user} -> {id_}" f" 添加订阅:{sub_type} -> {sub_user} -> {id_}"
) )
@del_sub.handle() @del_sub.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()) msg = get_message_text(event.json())
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_ = (
f"{event.user_id}:{event.group_id}" f"{event.user_id}:{event.group_id}"
if isinstance(event, GroupMessageEvent) if isinstance(event, GroupMessageEvent)
else f"{event.user_id}" else f"{event.user_id}"
) )
if await BilibiliSub.delete_bilibili_sub(int(msg), id_): if await BilibiliSub.delete_bilibili_sub(int(msg), id_):
await del_sub.send(f"删除订阅id:{msg} 成功...") await del_sub.send(f"删除订阅id:{msg} 成功...")
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 删除订阅 {id_}" f" 删除订阅 {id_}"
) )
else: else:
await del_sub.send(f"删除订阅id:{msg} 失败...") await del_sub.send(f"删除订阅id:{msg} 失败...")
@show_sub_info.handle() @show_sub_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
id_ = ( id_ = (
f"{event.user_id}:{event.group_id}" f"{event.user_id}:{event.group_id}"
if isinstance(event, GroupMessageEvent) if isinstance(event, GroupMessageEvent)
else f"{event.user_id}" else 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 = ""
season_rst = "" season_rst = ""
for x in data: for x in data:
if x.sub_type == "live": if x.sub_type == "live":
live_rst += ( live_rst += (
f"\t直播间id:{x.sub_id}\n" f"\t名称:{x.uname}\n" f"------------------\n" f"\t直播间id:{x.sub_id}\n" f"\t名称:{x.uname}\n" f"------------------\n"
) )
if x.sub_type == "up": if x.sub_type == "up":
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番名:{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"
) )
live_rst = "当前订阅的直播:\n" + live_rst if live_rst else live_rst live_rst = "当前订阅的直播:\n" + live_rst if live_rst else live_rst
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 = "您目前没有任何订阅..."
await show_sub_info.send(live_rst + up_rst + season_rst) await show_sub_info.send(live_rst + up_rst + season_rst)
# 推送 # 推送
@scheduler.scheduled_job( @scheduler.scheduled_job(
"interval", "interval",
seconds=30, seconds=30,
) )
async def _(): async def _():
bot = get_bot() bot = get_bot()
sub = None sub = None
if bot: if bot:
try: try:
await sub_manager.reload_sub_data() await sub_manager.reload_sub_data()
sub = await sub_manager.random_sub_data() sub = await sub_manager.random_sub_data()
if sub: if sub:
rst = await get_sub_status(sub.sub_id, sub.sub_type) logger.info(f"Bilibili订阅开始检测:{sub.sub_id}")
await send_sub_msg(rst, sub, bot) rst = await get_sub_status(sub.sub_id, sub.sub_type)
if sub.sub_type == "live": await send_sub_msg(rst, sub, bot)
rst = await get_sub_status(sub.sub_id, "up") if sub.sub_type == "live":
await send_sub_msg(rst, sub, bot) rst = await get_sub_status(sub.sub_id, "up")
except Exception as e: await send_sub_msg(rst, sub, bot)
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id if sub else 0} {type(e)}:{e}") except Exception as e:
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id if sub else 0} {type(e)}:{e}")
async def send_sub_msg(rst: str, sub: BilibiliSub, bot: Bot):
""" async def send_sub_msg(rst: str, sub: BilibiliSub, bot: Bot):
推送信息 """
:param rst: 回复 推送信息
:param sub: BilibiliSub :param rst: 回复
:param bot: Bot :param sub: BilibiliSub
""" :param bot: Bot
if rst: """
for x in sub.sub_users.split(",")[:-1]: if rst:
try: for x in sub.sub_users.split(",")[:-1]:
if ":" in x: try:
await bot.send_group_msg( if ":" in x:
group_id=int(x.split(":")[1]), message=Message(rst) await bot.send_group_msg(
) group_id=int(x.split(":")[1]), message=Message(rst)
else: )
await bot.send_private_msg(user_id=int(x), message=Message(rst)) else:
except Exception as e: await bot.send_private_msg(user_id=int(x), message=Message(rst))
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id} {type(e)}:{e}") except Exception as e:
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id} {type(e)}:{e}")
+391 -394
View File
@@ -1,394 +1,391 @@
from bilibili_api.exceptions.ResponseCodeException import ResponseCodeException from bilibili_api.exceptions.ResponseCodeException import ResponseCodeException
from utils.manager import resources_manager from utils.manager import resources_manager
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from .model import BilibiliSub from .model import BilibiliSub
from bilibili_api.live import LiveRoom from bilibili_api.live import LiveRoom
from bilibili_api import bangumi from bilibili_api import bangumi
from utils.message_builder import image 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 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
from services.db_context import db from services.db_context import db
from services.log import logger from services.log import logger
import aiohttp from utils.http_utils import AsyncHttpx
import random 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 = Path(IMAGE_PATH) / "bilibili_sub" / "dynamic"
dynamic_path.mkdir(exist_ok=True, parents=True) dynamic_path.mkdir(exist_ok=True, parents=True)
resources_manager.add_temp_dir(dynamic_path) resources_manager.add_temp_dir(dynamic_path)
async def add_live_sub(live_id: int, sub_user: str) -> str: async def add_live_sub(live_id: int, sub_user: str) -> str:
""" """
添加直播订阅 添加直播订阅
:param live_id: 直播房间号 :param live_id: 直播房间号
:param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group) :param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group)
:return: :return:
""" """
try: try:
async with db.transaction(): async with db.transaction():
try: try:
live = LiveRoom(live_id) live = LiveRoom(live_id)
live_info = (await live.get_room_info())["room_info"] live_info = (await live.get_room_info())["room_info"]
except ResponseCodeException: except ResponseCodeException:
return f"未找到房间号Id:{live_id} 的信息,请检查Id是否正确" return f"未找到房间号Id:{live_id} 的信息,请检查Id是否正确"
uid = live_info["uid"] uid = live_info["uid"]
room_id = live_info["room_id"] room_id = live_info["room_id"]
short_id = live_info["short_id"] short_id = live_info["short_id"]
title = live_info["title"] title = live_info["title"]
live_status = live_info["live_status"] live_status = live_info["live_status"]
if await BilibiliSub.add_bilibili_sub( if await BilibiliSub.add_bilibili_sub(
room_id, room_id,
"live", "live",
sub_user, sub_user,
uid=uid, uid=uid,
live_short_id=short_id, live_short_id=short_id,
live_status=live_status, live_status=live_status,
): ):
await _get_up_status(live_id) await _get_up_status(live_id)
uname = (await BilibiliSub.get_sub(live_id)).uname uname = (await BilibiliSub.get_sub(live_id)).uname
return ( return (
"已成功订阅主播:\n" "已成功订阅主播:\n"
f"\ttitle:{title}\n" f"\ttitle:{title}\n"
f"\tname: {uname}\n" f"\tname: {uname}\n"
f"\tlive_id:{live_id}\n" f"\tlive_id:{live_id}\n"
f"\tuid:{uid}" f"\tuid:{uid}"
) )
else: else:
return "添加订阅失败..." return "添加订阅失败..."
except Exception as e: except Exception as e:
logger.error(f"订阅主播live_id:{live_id} 发生了错误 {type(e)}:{e}") logger.error(f"订阅主播live_id:{live_id} 发生了错误 {type(e)}:{e}")
return "添加订阅失败..." return "添加订阅失败..."
async def add_up_sub(uid: int, sub_user: str) -> str: async def add_up_sub(uid: int, sub_user: str) -> str:
""" """
添加订阅 UP 添加订阅 UP
:param uid: UP uid :param uid: UP uid
:param sub_user: 订阅用户 :param sub_user: 订阅用户
""" """
try: try:
async with db.transaction(): async with db.transaction():
try: try:
u = user.User(uid) u = user.User(uid)
user_info = await u.get_user_info() user_info = await u.get_user_info()
except ResponseCodeException: except ResponseCodeException:
return f"未找到UpId:{uid} 的信息,请检查Id是否正确" return f"未找到UpId:{uid} 的信息,请检查Id是否正确"
uname = user_info["name"] uname = user_info["name"]
dynamic_info = await u.get_dynamics(0) dynamic_info = await u.get_dynamics(0)
dynamic_upload_time = 0 dynamic_upload_time = 0
if dynamic_info.get("cards"): if dynamic_info.get("cards"):
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"] dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
video_info = await u.get_videos() video_info = await u.get_videos()
latest_video_created = 0 latest_video_created = 0
if video_info["list"].get("vlist"): if video_info["list"].get("vlist"):
latest_video_created = video_info["list"]["vlist"][0]["created"] latest_video_created = video_info["list"]["vlist"][0]["created"]
if await BilibiliSub.add_bilibili_sub( if await BilibiliSub.add_bilibili_sub(
uid, uid,
"up", "up",
sub_user, sub_user,
uid=uid, uid=uid,
uname=uname, uname=uname,
dynamic_upload_time=dynamic_upload_time, dynamic_upload_time=dynamic_upload_time,
latest_video_created=latest_video_created, latest_video_created=latest_video_created,
): ):
return "已成功订阅UP:\n" f"\tname: {uname}\n" f"\tuid:{uid}" return "已成功订阅UP:\n" f"\tname: {uname}\n" f"\tuid:{uid}"
else: else:
return "添加订阅失败..." return "添加订阅失败..."
except Exception as e: except Exception as e:
logger.error(f"订阅Up uid:{uid} 发生了错误 {type(e)}:{e}") logger.error(f"订阅Up uid:{uid} 发生了错误 {type(e)}:{e}")
return "添加订阅失败..." return "添加订阅失败..."
async def add_season_sub(media_id: int, sub_user: str) -> str: async def add_season_sub(media_id: int, sub_user: str) -> str:
""" """
添加订阅 UP 添加订阅 UP
:param media_id: 番剧 media_id :param media_id: 番剧 media_id
:param sub_user: 订阅用户 :param sub_user: 订阅用户
""" """
try: try:
async with db.transaction(): async with db.transaction():
try: try:
season_info = await bangumi.get_meta(media_id) season_info = await bangumi.get_meta(media_id)
except ResponseCodeException: except ResponseCodeException:
return f"未找到media_id:{media_id} 的信息,请检查Id是否正确" return f"未找到media_id:{media_id} 的信息,请检查Id是否正确"
season_id = season_info["media"]["season_id"] season_id = season_info["media"]["season_id"]
season_current_episode = season_info["media"]["new_ep"]["index"] season_current_episode = season_info["media"]["new_ep"]["index"]
season_name = season_info["media"]["title"] season_name = season_info["media"]["title"]
if await BilibiliSub.add_bilibili_sub( if await BilibiliSub.add_bilibili_sub(
media_id, media_id,
"season", "season",
sub_user, sub_user,
season_name=season_name, season_name=season_name,
season_id=season_id, season_id=season_id,
season_current_episode=season_current_episode, season_current_episode=season_current_episode,
): ):
return ( return (
"已成功订阅番剧:\n" "已成功订阅番剧:\n"
f"\ttitle: {season_name}\n" f"\ttitle: {season_name}\n"
f"\tcurrent_episode: {season_current_episode}" f"\tcurrent_episode: {season_current_episode}"
) )
else: else:
return "添加订阅失败..." return "添加订阅失败..."
except Exception as e: except Exception as e:
logger.error(f"订阅番剧 media_id:{media_id} 发生了错误 {type(e)}:{e}") logger.error(f"订阅番剧 media_id:{media_id} 发生了错误 {type(e)}:{e}")
return "添加订阅失败..." return "添加订阅失败..."
async def delete_sub(sub_id: str, sub_user: str) -> str: async def delete_sub(sub_id: str, sub_user: str) -> str:
""" """
删除订阅 删除订阅
:param sub_id: 订阅 id :param sub_id: 订阅 id
:param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group) :param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group)
""" """
if await BilibiliSub.delete_bilibili_sub(sub_id, sub_user): if await BilibiliSub.delete_bilibili_sub(int(sub_id), sub_user):
return f"已成功取消订阅:{sub_id}" return f"已成功取消订阅:{sub_id}"
else: else:
return f"取消订阅:{sub_id} 失败,请检查是否订阅过该Id...." return f"取消订阅:{sub_id} 失败,请检查是否订阅过该Id...."
async def get_media_id(keyword: str) -> dict: async def get_media_id(keyword: str) -> dict:
""" """
获取番剧的 media_id 获取番剧的 media_id
:param keyword: 番剧名称 :param keyword: 番剧名称
""" """
params = {"keyword": keyword} params = {"keyword": keyword}
async with aiohttp.ClientSession() as session: 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)
async with session.get( if response.status_code == 200:
bilibili_search_url, timeout=5, params=params data = response.json()
) as response: if data.get("data"):
if response.status == 200: for item in data["data"]["result"]:
data = await response.json() if item["result_type"] == "media_bangumi":
if data.get("data"): idx = 0
for item in data["data"]["result"]: for x in item["data"]:
if item["result_type"] == "media_bangumi": _season_data[idx] = {
idx = 0 "media_id": x["media_id"],
for x in item["data"]: "title": x["title"]
_season_data[idx] = { .replace('<em class="keyword">', "")
"media_id": x["media_id"], .replace("</em>", ""),
"title": x["title"] }
.replace('<em class="keyword">', "") idx += 1
.replace("</em>", ""), return _season_data
} except TimeoutError:
idx += 1 pass
return _season_data return {}
except TimeoutError:
pass
return {} async def get_sub_status(id_: int, sub_type: str) -> Optional[str]:
"""
获取订阅状态
async def get_sub_status(id_: int, sub_type: str) -> Optional[str]: :param id_: 订阅 id
""" :param sub_type: 订阅类型
获取订阅状态 :return:
:param id_: 订阅 id """
:param sub_type: 订阅类型 try:
:return: if sub_type == "live":
""" return await _get_live_status(id_)
try: elif sub_type == "up":
if sub_type == "live": return await _get_up_status(id_)
return await _get_live_status(id_) elif sub_type == "season":
elif sub_type == "up": return await _get_season_status(id_)
return await _get_up_status(id_) except ResponseCodeException:
elif sub_type == "season": return "获取信息失败...请检查订阅Id是否存在或稍后再试..."
return await _get_season_status(id_) # except Exception as e:
except ResponseCodeException: # logger.error(f"获取订阅状态发生预料之外的错误 id_:{id_} {type(e)}:{e}")
return "获取信息失败...请检查订阅Id是否存在或稍后再试..." # return "发生了预料之外的错误..请稍后再试或联系管理员....."
# except Exception as e:
# logger.error(f"获取订阅状态发生预料之外的错误 id_:{id_} {type(e)}:{e}")
# return "发生了预料之外的错误..请稍后再试或联系管理员....." async def _get_live_status(id_: int) -> Optional[str]:
"""
获取直播订阅状态
async def _get_live_status(id_: int) -> Optional[str]: :param id_: 直播间 id
""" """
获取直播订阅状态 live = LiveRoom(id_)
:param id_: 直播间 id live_info = (await live.get_room_info())["room_info"]
""" title = live_info["title"]
live = LiveRoom(id_) room_id = live_info["room_id"]
live_info = (await live.get_room_info())["room_info"] live_status = live_info["live_status"]
title = live_info["title"] cover = live_info["cover"]
room_id = live_info["room_id"] sub = await BilibiliSub.get_sub(id_)
live_status = live_info["live_status"] if sub.live_status != live_status:
cover = live_info["cover"] await BilibiliSub.update_sub_info(id_, live_status=live_status)
sub = await BilibiliSub.get_sub(id_) if sub.live_status == 0 and live_status == 1:
if sub.live_status != live_status: return (
await BilibiliSub.update_sub_info(id_, live_status=live_status) f"{image(cover)}\n"
if sub.live_status == 0 and live_status == 1: f"{sub.uname} 开播啦!\n"
return ( f"标题:{title}\n"
f"{image(cover)}\n" f"直链:https://live.bilibili.com/{room_id}"
f"{sub.uname} 开播啦!\n" )
f"标题:{title}\n" return None
f"直链:https://live.bilibili.com/{room_id}"
)
return None async def _get_up_status(id_: int) -> Optional[str]:
"""
获取用户投稿状态
async def _get_up_status(id_: int) -> Optional[str]: :param id_: 用户 id
""" :return:
获取用户投稿状态 """
:param id_: 用户 id _user = await BilibiliSub.get_sub(id_)
:return: u = user.User(_user.uid)
""" user_info = await u.get_user_info()
_user = await BilibiliSub.get_sub(id_) uname = user_info["name"]
u = user.User(_user.uid) video_info = await u.get_videos()
user_info = await u.get_user_info() latest_video_created = 0
uname = user_info["name"] video = None
video_info = await u.get_videos() if _user.uname != uname:
latest_video_created = 0 await BilibiliSub.update_sub_info(id_, uname=uname)
video = None dynamic_img, dynamic_upload_time = await get_user_dynamic(u, _user)
if _user.uname != uname: if video_info["list"].get("vlist"):
await BilibiliSub.update_sub_info(id_, uname=uname) video = video_info["list"]["vlist"][0]
dynamic_img, dynamic_upload_time = await get_user_dynamic(u, _user) latest_video_created = video["created"]
if video_info["list"].get("vlist"): rst = ""
video = video_info["list"]["vlist"][0] if dynamic_img:
latest_video_created = video["created"] await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time)
rst = "" rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n"
if dynamic_img: if _user.latest_video_created != latest_video_created and video:
await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time) rst = rst + "-------------\n" if rst else rst
rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n" await BilibiliSub.update_sub_info(
if _user.latest_video_created != latest_video_created and video: id_, latest_video_created=latest_video_created
rst = rst + "-------------\n" if rst else rst )
await BilibiliSub.update_sub_info( rst += (
id_, latest_video_created=latest_video_created f'{image(video["pic"])}\n'
) f"{uname} 投稿了新视频啦\n"
rst += ( f'标题:{video["title"]}\n'
f'{image(video["pic"])}\n' f'Bvid:{video["bvid"]}\n'
f"{uname} 投稿了新视频啦\n" f'直链:https://www.bilibili.com/video/{video["bvid"]}'
f'标题:{video["title"]}\n' )
f'Bvid:{video["bvid"]}\n' rst = None if rst == "-------------\n" else rst
f'直链:https://www.bilibili.com/video/{video["bvid"]}' return rst
)
rst = None if rst == "-------------\n" else rst
return rst async def _get_season_status(id_) -> Optional[str]:
"""
获取 番剧 更新状态
async def _get_season_status(id_) -> Optional[str]: :param id_: 番剧 id
""" """
获取 番剧 更新状态 season_info = await bangumi.get_meta(id_)
:param id_: 番剧 id title = season_info["media"]["title"]
""" _idx = (await BilibiliSub.get_sub(id_)).season_current_episode
season_info = await bangumi.get_meta(id_) new_ep = season_info["media"]["new_ep"]["index"]
title = season_info["media"]["title"] if new_ep != _idx:
_idx = (await BilibiliSub.get_sub(id_)).season_current_episode await BilibiliSub.update_sub_info(
new_ep = season_info["media"]["new_ep"]["index"] id_, season_current_episode=new_ep, season_update_time=datetime.now()
if new_ep != _idx: )
await BilibiliSub.update_sub_info( return (
id_, season_current_episode=new_ep, season_update_time=datetime.now() f'{image(season_info["media"]["cover"])}\n'
) f"[{title}]更新啦\n"
return ( f"最新集数:{new_ep}"
f'{image(season_info["media"]["cover"])}\n' )
f"[{title}]更新啦\n" return None
f"最新集数:{new_ep}"
)
return None async def get_user_dynamic(
u: User, local_user: BilibiliSub
) -> "Optional[MessageSegment], int":
async def get_user_dynamic( """
u: User, local_user: BilibiliSub 获取用户动态
) -> "Optional[MessageSegment], int": :param u: 用户类
""" :param local_user: 数据库存储的用户数据
获取用户动态 :return: 最新动态截图与时间
:param u: 用户类 """
:param local_user: 数据库存储的用户数据 dynamic_info = await u.get_dynamics(0)
:return: 最新动态截图与时间 browser = await get_browser()
""" if dynamic_info.get("cards") and browser:
dynamic_info = await u.get_dynamics(0) dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
browser = await get_browser() if local_user.dynamic_upload_time != dynamic_upload_time:
if dynamic_info.get("cards") and browser: page = await browser.new_page()
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"] await page.goto(
if local_user.dynamic_upload_time != dynamic_upload_time: f"https://space.bilibili.com/{local_user.uid}/dynamic",
page = await browser.new_page() wait_until="networkidle",
await page.goto( timeout=10000,
f"https://space.bilibili.com/{local_user.uid}/dynamic", )
wait_until="networkidle", await page.set_viewport_size({"width": 2560, "height": 1080})
timeout=10000, # 删除置顶
) await page.evaluate(
await page.set_viewport_size({"width": 2560, "height": 1080}) """
# 删除置顶 xs = document.getElementsByClassName('first-card-with-title');
await page.evaluate( for (x of xs) {
""" x.remove();
xs = document.getElementsByClassName('first-card-with-title'); }
for (x of xs) { """
x.remove(); )
} card = await page.query_selector(".card")
""" # 截图并保存
) await card.screenshot(
card = await page.query_selector(".card") path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
# 截图并保存 timeout=100000,
await card.screenshot( )
path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg", await page.close()
timeout=100000, return (
) image(
await page.close() f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
return ( "bilibili_sub/dynamic",
image( ),
f"{local_user.sub_id}_{dynamic_upload_time}.jpg", dynamic_upload_time,
"bilibili_sub/dynamic", )
), return None, None
dynamic_upload_time,
)
return None, None class SubManager:
def __init__(self):
self.live_data = []
class SubManager: self.up_data = []
def __init__(self): self.season_data = []
self.live_data = [] self.current_index = -1
self.up_data = []
self.season_data = [] async def reload_sub_data(self):
self.current_index = -1 """
重载数据
async def reload_sub_data(self): """
""" if not self.live_data or not self.up_data or not self.season_data:
重载数据 (
""" _live_data,
if not self.live_data or not self.up_data or not self.season_data: _up_data,
( _season_data,
_live_data, ) = await BilibiliSub.get_all_sub_data()
_up_data, if not self.live_data:
_season_data, self.live_data = _live_data
) = await BilibiliSub.get_all_sub_data() if not self.up_data:
if not self.live_data: self.up_data = _up_data
self.live_data = _live_data if not self.season_data:
if not self.up_data: self.season_data = _season_data
self.up_data = _up_data
if not self.season_data: async def random_sub_data(self) -> Optional[BilibiliSub]:
self.season_data = _season_data """
随机获取一条数据
async def random_sub_data(self) -> Optional[BilibiliSub]: :return:
""" """
随机获取一条数据 sub = None
:return: if not self.live_data and not self.up_data and not self.season_data:
""" return sub
sub = None self.current_index += 1
if not self.live_data and not self.up_data and not self.season_data: if self.current_index == 0:
return sub if self.live_data:
self.current_index += 1 sub = random.choice(self.live_data)
if self.current_index == 0: self.live_data.remove(sub)
if self.live_data: elif self.current_index == 1:
sub = random.choice(self.live_data) if self.up_data:
self.live_data.remove(sub) sub = random.choice(self.up_data)
elif self.current_index == 1: self.up_data.remove(sub)
if self.up_data: elif self.current_index == 2:
sub = random.choice(self.up_data) if self.season_data:
self.up_data.remove(sub) sub = random.choice(self.season_data)
elif self.current_index == 2: self.season_data.remove(sub)
if self.season_data: else:
sub = random.choice(self.season_data) self.current_index = -1
self.season_data.remove(sub) if sub:
else: return sub
self.current_index = -1 await self.reload_sub_data()
if sub: return await self.random_sub_data()
return sub
await self.reload_sub_data()
return await self.random_sub_data()
Regular → Executable
+249 -249
View File
@@ -1,249 +1,249 @@
from services.log import logger from services.log import logger
from services.db_context import db from services.db_context import db
from datetime import datetime from datetime import datetime
from typing import Optional, List from typing import Optional, List
class BilibiliSub(db.Model): class BilibiliSub(db.Model):
__tablename__ = "bilibili_sub" __tablename__ = "bilibili_sub"
id = db.Column(db.Integer(), primary_key=True) id = db.Column(db.Integer(), primary_key=True)
sub_id = db.Column(db.Integer(), nullable=False) sub_id = db.Column(db.Integer(), nullable=False)
sub_type = db.Column(db.String(), nullable=False) sub_type = db.Column(db.String(), nullable=False)
# 订阅用户 # 订阅用户
sub_users = db.Column(db.String(), nullable=False) sub_users = db.Column(db.String(), nullable=False)
# 直播 # 直播
live_short_id = db.Column(db.Integer()) live_short_id = db.Column(db.Integer())
live_status = db.Column(db.Integer) live_status = db.Column(db.Integer)
# 主播/UP # 主播/UP
uid = db.Column(db.BigInteger()) uid = db.Column(db.BigInteger())
uname = db.Column(db.String()) uname = db.Column(db.String())
latest_video_created = db.Column(db.BigInteger()) # 视频上传时间 latest_video_created = db.Column(db.BigInteger()) # 视频上传时间
dynamic_upload_time = db.Column(db.BigInteger(), default=0) # 动态发布时间 dynamic_upload_time = db.Column(db.BigInteger(), default=0) # 动态发布时间
# 番剧 # 番剧
season_name = db.Column(db.String()) season_name = db.Column(db.String())
season_id = db.Column(db.Integer()) season_id = db.Column(db.Integer())
season_current_episode = db.Column(db.String()) season_current_episode = db.Column(db.String())
season_update_time = db.Column(db.DateTime()) season_update_time = db.Column(db.DateTime())
_idx1 = db.Index("bilibili_sub_idx1", "sub_id", "sub_type", unique=True) _idx1 = db.Index("bilibili_sub_idx1", "sub_id", "sub_type", unique=True)
@classmethod @classmethod
async def add_bilibili_sub( async def add_bilibili_sub(
cls, cls,
sub_id: int, sub_id: int,
sub_type: str, sub_type: str,
sub_user: str, sub_user: str,
*, *,
live_short_id: Optional[int] = None, live_short_id: Optional[int] = None,
live_status: Optional[int] = None, live_status: Optional[int] = None,
dynamic_upload_time: Optional[int] = None, dynamic_upload_time: Optional[int] = None,
uid: Optional[int] = None, uid: Optional[int] = None,
uname: Optional[str] = None, uname: Optional[str] = None,
latest_video_created: Optional[int] = None, latest_video_created: Optional[int] = None,
season_name: Optional[str] = None, season_name: Optional[str] = None,
season_id: Optional[int] = None, season_id: Optional[int] = None,
season_current_episode: Optional[str] = None, season_current_episode: Optional[str] = None,
season_update_time: Optional[datetime] = None, season_update_time: Optional[datetime] = None,
) -> bool: ) -> bool:
""" """
说明: 说明:
添加订阅 添加订阅
参数: 参数:
:param sub_id: 订阅名称,房间号,番剧号等 :param sub_id: 订阅名称,房间号,番剧号等
:param sub_type: 订阅类型 :param sub_type: 订阅类型
:param sub_user: 订阅此条目的用户 :param sub_user: 订阅此条目的用户
:param live_short_id: 直接短 id :param live_short_id: 直接短 id
:param live_status: 主播开播状态 :param live_status: 主播开播状态
:param dynamic_upload_time: 主播/UP最新动态时间 :param dynamic_upload_time: 主播/UP最新动态时间
:param uid: 主播/UP uid :param uid: 主播/UP uid
:param uname: 用户名称 :param uname: 用户名称
:param latest_video_created: 最新视频上传时间 :param latest_video_created: 最新视频上传时间
:param season_name: 番剧名称 :param season_name: 番剧名称
:param season_id: 番剧 season_id :param season_id: 番剧 season_id
:param season_current_episode: 番剧最新集数 :param season_current_episode: 番剧最新集数
:param season_update_time: 番剧更新时间 :param season_update_time: 番剧更新时间
""" """
try: try:
async with db.transaction(): async with db.transaction():
query = ( query = (
await cls.query.where(cls.sub_id == sub_id) await cls.query.where(cls.sub_id == sub_id)
.with_for_update() .with_for_update()
.gino.first() .gino.first()
) )
sub_user = sub_user if sub_user[-1] == "," else f"{sub_user}," sub_user = sub_user if sub_user[-1] == "," else f"{sub_user},"
if query: if query:
if sub_user not in query.sub_users: if sub_user not in query.sub_users:
sub_users = query.sub_users + sub_user sub_users = query.sub_users + sub_user
await query.update(sub_users=sub_users).apply() await query.update(sub_users=sub_users).apply()
else: else:
sub = await cls.create( sub = await cls.create(
sub_id=sub_id, sub_type=sub_type, sub_users=sub_user sub_id=sub_id, sub_type=sub_type, sub_users=sub_user
) )
await sub.update( await sub.update(
live_short_id=live_short_id live_short_id=live_short_id
if live_short_id if live_short_id
else sub.live_short_id, else sub.live_short_id,
live_status=live_status if live_status else sub.live_status, live_status=live_status if live_status else sub.live_status,
dynamic_upload_time=dynamic_upload_time dynamic_upload_time=dynamic_upload_time
if dynamic_upload_time if dynamic_upload_time
else sub.dynamic_upload_time, else sub.dynamic_upload_time,
uid=uid if uid else sub.uid, uid=uid if uid else sub.uid,
uname=uname if uname else sub.uname, uname=uname if uname else sub.uname,
latest_video_created=latest_video_created latest_video_created=latest_video_created
if latest_video_created if latest_video_created
else sub.latest_video_created, else sub.latest_video_created,
season_update_time=season_update_time season_update_time=season_update_time
if season_update_time if season_update_time
else sub.season_update_time, else sub.season_update_time,
season_current_episode=season_current_episode season_current_episode=season_current_episode
if season_current_episode if season_current_episode
else sub.season_current_episode, else sub.season_current_episode,
season_id=season_id if season_id else sub.season_id, season_id=season_id if season_id else sub.season_id,
season_name=season_name if season_name else sub.season_name, season_name=season_name if season_name else sub.season_name,
).apply() ).apply()
return True return True
except Exception as e: except Exception as e:
logger.info(f"bilibili_sub 添加订阅错误 {type(e)}: {e}") logger.info(f"bilibili_sub 添加订阅错误 {type(e)}: {e}")
return False return False
@classmethod @classmethod
async def delete_bilibili_sub(cls, sub_id: int, sub_user: str) -> bool: async def delete_bilibili_sub(cls, sub_id: int, sub_user: str) -> bool:
""" """
说明: 说明:
删除订阅 删除订阅
参数: 参数:
:param sub_id: 订阅名称 :param sub_id: 订阅名称
:param sub_user: 删除此条目的用户 :param sub_user: 删除此条目的用户
""" """
try: try:
async with db.transaction(): async with db.transaction():
query = ( query = (
await cls.query.where( await cls.query.where(
(cls.sub_id == sub_id) & (cls.sub_users.contains(sub_user)) (cls.sub_id == sub_id) & (cls.sub_users.contains(sub_user))
) )
.with_for_update() .with_for_update()
.gino.first() .gino.first()
) )
if not query: if not query:
return False return False
await query.update( await query.update(
sub_users=query.sub_users.replace(f"{sub_user},", "") sub_users=query.sub_users.replace(f"{sub_user},", "")
).apply() ).apply()
if not query.sub_users.strip(): if not query.sub_users.strip():
await query.delete() await query.delete()
return True return True
except Exception as e: except Exception as e:
logger.info(f"bilibili_sub 删除订阅错误 {type(e)}: {e}") logger.info(f"bilibili_sub 删除订阅错误 {type(e)}: {e}")
return False return False
@classmethod @classmethod
async def get_sub(cls, sub_id: int) -> Optional["BilibiliSub"]: async def get_sub(cls, sub_id: int) -> Optional["BilibiliSub"]:
""" """
说明: 说明:
获取订阅对象 获取订阅对象
参数: 参数:
:param sub_id: 订阅 id :param sub_id: 订阅 id
""" """
return await cls.query.where(cls.sub_id == sub_id).gino.first() return await cls.query.where(cls.sub_id == sub_id).gino.first()
@classmethod @classmethod
async def get_sub_data(cls, id_: str) -> List["BilibiliSub"]: async def get_sub_data(cls, id_: str) -> List["BilibiliSub"]:
""" """
获取 id_ 订阅的所有内容 获取 id_ 订阅的所有内容
:param id_: id :param id_: id
""" """
query = cls.query.where(cls.sub_users.contains(id_)) query = cls.query.where(cls.sub_users.contains(id_))
return await query.gino.all() return await query.gino.all()
@classmethod @classmethod
async def update_sub_info( async def update_sub_info(
cls, cls,
sub_id: int, sub_id: int,
*, *,
live_short_id: Optional[int] = None, live_short_id: Optional[int] = None,
live_status: Optional[int] = None, live_status: Optional[int] = None,
dynamic_upload_time: Optional[int] = None, dynamic_upload_time: Optional[int] = None,
uid: Optional[int] = None, uid: Optional[int] = None,
uname: Optional[str] = None, uname: Optional[str] = None,
latest_video_created: Optional[int] = None, latest_video_created: Optional[int] = None,
season_name: Optional[str] = None, season_name: Optional[str] = None,
season_id: Optional[int] = None, season_id: Optional[int] = None,
season_current_episode: Optional[str] = None, season_current_episode: Optional[str] = None,
season_update_time: Optional[datetime] = None, season_update_time: Optional[datetime] = None,
) -> bool: ) -> bool:
""" """
说明: 说明:
更新订阅信息 更新订阅信息
参数: 参数:
:param sub_id: 订阅名称,房间号,番剧号等 :param sub_id: 订阅名称,房间号,番剧号等
:param live_short_id: 直接短 id :param live_short_id: 直接短 id
:param live_status: 主播开播状态 :param live_status: 主播开播状态
:param dynamic_upload_time: 主播/UP最新动态时间 :param dynamic_upload_time: 主播/UP最新动态时间
:param uid: 主播/UP uid :param uid: 主播/UP uid
:param uname: 用户名称 :param uname: 用户名称
:param latest_video_created: 最新视频上传时间 :param latest_video_created: 最新视频上传时间
:param season_name: 番剧名称 :param season_name: 番剧名称
:param season_id: 番剧 season_id :param season_id: 番剧 season_id
:param season_current_episode: 番剧最新集数 :param season_current_episode: 番剧最新集数
:param season_update_time: 番剧更新时间 :param season_update_time: 番剧更新时间
""" """
try: try:
async with db.transaction(): async with db.transaction():
sub = ( sub = (
await cls.query.where(cls.sub_id == sub_id) await cls.query.where(cls.sub_id == sub_id)
.with_for_update() .with_for_update()
.gino.first() .gino.first()
) )
if sub: if sub:
await sub.update( await sub.update(
live_short_id=live_short_id live_short_id=live_short_id
if live_short_id is not None if live_short_id is not None
else sub.live_short_id, else sub.live_short_id,
live_status=live_status live_status=live_status
if live_status is not None if live_status is not None
else sub.live_status, else sub.live_status,
dynamic_upload_time=dynamic_upload_time dynamic_upload_time=dynamic_upload_time
if dynamic_upload_time is not None if dynamic_upload_time is not None
else sub.dynamic_upload_time, else sub.dynamic_upload_time,
uid=uid if uid is not None else sub.uid, uid=uid if uid is not None else sub.uid,
uname=uname if uname is not None else sub.uname, uname=uname if uname is not None else sub.uname,
latest_video_created=latest_video_created latest_video_created=latest_video_created
if latest_video_created is not None if latest_video_created is not None
else sub.latest_video_created, else sub.latest_video_created,
season_update_time=season_update_time season_update_time=season_update_time
if season_update_time is not None if season_update_time is not None
else sub.season_update_time, else sub.season_update_time,
season_current_episode=season_current_episode season_current_episode=season_current_episode
if season_current_episode is not None if season_current_episode is not None
else sub.season_current_episode, else sub.season_current_episode,
season_id=season_id if season_id is not None else sub.season_id, season_id=season_id if season_id is not None else sub.season_id,
season_name=season_name season_name=season_name
if season_name is not None if season_name is not None
else sub.season_name, else sub.season_name,
).apply() ).apply()
return True return True
except Exception as e: except Exception as e:
logger.info(f"bilibili_sub 更新订阅错误 {type(e)}: {e}") logger.info(f"bilibili_sub 更新订阅错误 {type(e)}: {e}")
return False return False
@classmethod @classmethod
async def get_all_sub_data( async def get_all_sub_data(
cls, cls,
) -> "List[BilibiliSub], List[BilibiliSub], List[BilibiliSub]": ) -> "List[BilibiliSub], List[BilibiliSub], List[BilibiliSub]":
""" """
说明: 说明:
分类获取所有数据 分类获取所有数据
""" """
live_data = [] live_data = []
up_data = [] up_data = []
season_data = [] season_data = []
query = await cls.query.gino.all() query = await cls.query.gino.all()
for x in query: for x in query:
if x.sub_type == "live": if x.sub_type == "live":
live_data.append(x) live_data.append(x)
if x.sub_type == "up": if x.sub_type == "up":
up_data.append(x) up_data.append(x)
if x.sub_type == "season": if x.sub_type == "season":
season_data.append(x) season_data.append(x)
return live_data, up_data, season_data return live_data, up_data, season_data
Regular → Executable
+71 -72
View File
@@ -1,72 +1,71 @@
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from pathlib import Path from utils.http_utils import AsyncHttpx
from bilibili_api import user from pathlib import Path
from io import BytesIO from bilibili_api import user
import aiohttp from io import BytesIO
BORDER_PATH = Path(IMAGE_PATH) / 'border' BORDER_PATH = Path(IMAGE_PATH) / "border"
BORDER_PATH.mkdir(parents=True, exist_ok=True) BORDER_PATH.mkdir(parents=True, exist_ok=True)
async def get_pic(url: str) -> bytes: async def get_pic(url: str) -> bytes:
""" """
获取图像 获取图像
:param url: 图像链接 :param url: 图像链接
:return: 图像二进制 :return: 图像二进制
""" """
async with aiohttp.ClientSession() as session: return (await AsyncHttpx.get(url, timeout=10)).content
async with session.get(url, timeout=2) as response:
return await response.read()
async def create_live_des_image(uid: int, title: str, cover: str, tags: str, des: str):
"""
async def create_live_des_image(uid: int, title: str, cover: str, tags: str, des: str): 生成主播简介图片
""" :param uid: 主播 uid
生成主播简介图片 :param title: 直播间标题
:param uid: 主播 uid :param cover: 直播封面
:param title: 直播间标题 :param tags: 直播标签
:param cover: 直播封面 :param des: 直播简介
:param tags: 直播标签 :return:
:param des: 直播简介 """
:return: u = user.User(uid)
""" user_info = await u.get_user_info()
u = user.User(uid) name = user_info["name"]
user_info = await u.get_user_info() sex = user_info["sex"]
name = user_info['name'] face = user_info["face"]
sex = user_info['sex'] sign = user_info["sign"]
face = user_info['face'] ava = CreateImg(100, 100, background=BytesIO(await get_pic(face)))
sign = user_info['sign'] ava.circle()
ava = CreateImg(100, 100, background=BytesIO(await get_pic(face))) cover = CreateImg(470, 265, background=BytesIO(await get_pic(cover)))
ava.circle() print()
cover = CreateImg(470, 265, background=BytesIO(await get_pic(cover)))
print()
def _create_live_des_image(
title: str,
def _create_live_des_image(title: str, cover: CreateImg, tags: str, des: str, user_name: str, sex: str, sign: str, ava: CreateImg): cover: CreateImg,
""" tags: str,
生成主播简介图片 des: str,
:param title: 直播间标题 user_name: str,
:param cover: 直播封面 sex: str,
:param tags: 直播标签 sign: str,
:param des: 直播简介 ava: CreateImg,
:param user_name: 主播名称 ):
:param sex: 主播性别 """
:param sign: 主播签名 生成主播简介图片
:param ava: 主播头像 :param title: 直播间标题
:return: :param cover: 直播封面
""" :param tags: 直播标签
border = BORDER_PATH / '0.png' :param des: 直播简介
border_img = None :param user_name: 主播名称
if border.exists(): :param sex: 主播性别
border_img = CreateImg(1772, 2657, background=border) :param sign: 主播签名
bk = CreateImg(1772, 2657, font_size=30) :param ava: 主播头像
bk.paste(cover, (0, 100), center_type='by_width') :return:
"""
border = BORDER_PATH / "0.png"
border_img = None
if border.exists():
border_img = CreateImg(1772, 2657, background=border)
bk = CreateImg(1772, 2657, font_size=30)
bk.paste(cover, (0, 100), center_type="by_width")
Regular → Executable
+1 -4
View File
@@ -7,7 +7,6 @@ from nonebot.adapters.cqhttp import PrivateMessageEvent
from utils.utils import get_message_text from utils.utils import get_message_text
from nonebot.adapters.cqhttp.permission import PRIVATE from nonebot.adapters.cqhttp.permission import PRIVATE
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from aiohttp.client_exceptions import ServerDisconnectedError
__zx_plugin_name__ = "磁力搜索" __zx_plugin_name__ = "磁力搜索"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -89,11 +88,9 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
send_flag = True send_flag = True
except TimeoutError: except TimeoutError:
await bt.finish(f"搜索 {keyword} 超时...") await bt.finish(f"搜索 {keyword} 超时...")
except ServerDisconnectedError:
await bt.finish(f"搜索 {keyword} 连接失败")
except Exception as e: except Exception as e:
await bt.finish(f"bt 其他未知错误..") await bt.finish(f"bt 其他未知错误..")
logger.error(f"bt 错误 e:{e}") logger.error(f"bt 错误 {type(e)}:{e}")
if not send_flag: if not send_flag:
await bt.send(f"{keyword} 未搜索到...") await bt.send(f"{keyword} 未搜索到...")
logger.info(f"USER {event.user_id} BT搜索 {keyword} 第 {page} 页") logger.info(f"USER {event.user_id} BT搜索 {keyword} 第 {page} 页")
Regular → Executable
+35 -34
View File
@@ -1,8 +1,6 @@
from utils.user_agent import get_user_agent from utils.http_utils import AsyncHttpx
import aiohttp
from configs.config import Config from configs.config import Config
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from utils.utils import get_local_proxy
import platform import platform
if platform.system() == "Windows": if platform.system() == "Windows":
@@ -15,36 +13,39 @@ url = "http://www.eclzz.world"
async def get_bt_info(keyword: str, page: str): async def get_bt_info(keyword: str, page: str):
async with aiohttp.ClientSession(headers=get_user_agent()) as session: """
async with session.get( 获取资源信息
f"{url}/s/{keyword}_rel_{page}.html", proxy=get_local_proxy(), timeout=5 :param keyword: 关键词
) as response: :param page: 页数
text = await response.text() """
if text.find("大约0条结果") != -1: text = (await AsyncHttpx.get(f"{url}/s/{keyword}_rel_{page}.html", timeout=5)).text
return if text.find("大约0条结果") != -1:
soup = BeautifulSoup(text, "lxml") return
item_lst = soup.find_all("div", {"class": "search-item"}) soup = BeautifulSoup(text, "lxml")
bt_max_num = Config.get_config("bt", "BT_MAX_NUM") item_lst = soup.find_all("div", {"class": "search-item"})
bt_max_num = bt_max_num if bt_max_num < len(item_lst) else len(item_lst) bt_max_num = Config.get_config("bt", "BT_MAX_NUM")
for item in item_lst[:bt_max_num]: bt_max_num = bt_max_num if bt_max_num < len(item_lst) else len(item_lst)
divs = item.find_all("div") for item in item_lst[:bt_max_num]:
title = ( divs = item.find_all("div")
str(divs[0].find("a").text) title = (
.replace("<em>", "") str(divs[0].find("a").text)
.replace("</em>", "") .replace("<em>", "")
.strip() .replace("</em>", "")
) .strip()
spans = divs[2].find_all("span") )
itype = spans[0].text spans = divs[2].find_all("span")
create_time = spans[1].find("b").text itype = spans[0].text
file_size = spans[2].find("b").text create_time = spans[1].find("b").text
link = await get_download_link(divs[0].find("a")["href"], session) file_size = spans[2].find("b").text
yield title, itype, create_time, file_size, link link = await get_download_link(divs[0].find("a")["href"])
yield title, itype, create_time, file_size, link
async def get_download_link(_url: str, session) -> str: async def get_download_link(_url: str) -> str:
async with session.get( """
f"{url}{_url}", proxy=get_local_proxy(), timeout=30 获取资源下载地址
) as response: :param _url: 链接
soup = BeautifulSoup(await response.text(), "lxml") """
return soup.find("a", {"id": "down-url"})["href"] text = (await AsyncHttpx.get(f"{url}{_url}")).text
soup = BeautifulSoup(text, "lxml")
return soup.find("a", {"id": "down-url"})["href"]
Regular → Executable
+57 -57
View File
@@ -1,57 +1,57 @@
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.cqhttp import Bot, Event, GroupMessageEvent
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
__zx_plugin_name__ = "点歌" __zx_plugin_name__ = "点歌"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
在线点歌 在线点歌
指令: 指令:
点歌 [歌名] 点歌 [歌名]
""".strip() """.strip()
__plugin_des__ = "为你点播了一首曾经的歌" __plugin_des__ = "为你点播了一首曾经的歌"
__plugin_cmd__ = ["点歌 [歌名]"] __plugin_cmd__ = ["点歌 [歌名]"]
__plugin_type__ = ("一些工具",) __plugin_type__ = ("一些工具",)
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ["点歌"], "cmd": ["点歌"],
} }
songpicker = on_command("点歌", priority=5, block=True) music = on_command("点歌", priority=5, block=True)
@songpicker.handle() @music.handle()
async def handle_first_receive(bot: Bot, event: Event, state: T_State): async def handle_first_receive(bot: Bot, event: Event, state: T_State):
args = str(event.get_message()).strip() args = str(event.get_message()).strip()
if args: if args:
state["song_name"] = args state["song_name"] = args
@songpicker.got("song_name", prompt="歌名是?") @music.got("song_name", prompt="歌名是?")
async def _(bot: Bot, event: Event, state: T_State): async def _(bot: Bot, event: Event, state: T_State):
song = state["song_name"] song = state["song_name"]
song_id = await get_song_id(song) song_id = await get_song_id(song)
if not song_id: if not song_id:
await songpicker.finish("没有找到这首歌!", at_sender=True) await music.finish("没有找到这首歌!", at_sender=True)
for _ in range(3): for _ in range(3):
song_content = [{"type": "music", "data": {"type": 163, "id": song_id}}] song_content = [{"type": "music", "data": {"type": 163, "id": song_id}}]
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 点歌 :{song}" f" 点歌 :{song}"
) )
await songpicker.finish(song_content) await music.finish(song_content)
else: else:
await songpicker.finish("网易云繁忙...") await music.finish("网易云繁忙...")
Regular → Executable
+38 -47
View File
@@ -1,47 +1,38 @@
import aiohttp from utils.http_utils import AsyncHttpx
import json import json
headers = {"referer": "http://music.163.com"} headers = {"referer": "http://music.163.com"}
cookies = {"appver": "2.0.2"} cookies = {"appver": "2.0.2"}
async def search_song(song_name: str): async def search_song(song_name: str):
async with aiohttp.ClientSession( """
headers=headers, cookies=cookies 搜索歌曲
) as session: :param song_name: 歌名
async with session.post( """
f"http://music.163.com/api/search/get/", r = await AsyncHttpx.post(
data={"s": song_name, "limit": 1, "type": 1, "offset": 0}, f"http://music.163.com/api/search/get/",
) as r: data={"s": song_name, "limit": 1, "type": 1, "offset": 0},
if r.status != 200: )
return None if r.status_code != 200:
r = await r.text() return None
return json.loads(r) return json.loads(r.text)
async def get_song_id(songName: str) -> int: async def get_song_id(song_name: str) -> int:
""" """ """
根据用户输入的songName 获取候选songId列表 [默认songId数量:5] r = await search_song(song_name)
""" return r["result"]["songs"][0]["id"]
r = await search_song(songName)
return r["result"]["songs"][0]["id"]
async def get_song_info(songId: int):
"""
async def get_song_info(songId: int): 获取歌曲信息
""" """
获取歌曲信息 r = await AsyncHttpx.post(
""" f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",
async with aiohttp.ClientSession( )
headers=headers, cookies=cookies if r.status_code != 200:
) as session: return None
async with session.post( return json.loads(r.text)
f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",
) as r:
if r.status != 200:
return None
r = await r.text()
return json.loads(r)
Regular → Executable
View File
Regular → Executable
+11 -22
View File
@@ -1,11 +1,7 @@
import psutil import psutil
import aiohttp
import time import time
from datetime import datetime from datetime import datetime
from utils.user_agent import get_user_agent from utils.http_utils import AsyncHttpx
from asyncio.exceptions import TimeoutError
from aiohttp.client_exceptions import ClientConnectorError
from utils.utils import get_local_proxy
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from pathlib import Path from pathlib import Path
@@ -34,23 +30,16 @@ class Check:
self.disk = psutil.disk_usage("/").percent self.disk = psutil.disk_usage("/").percent
async def check_network(self): async def check_network(self):
async with aiohttp.ClientSession(headers=get_user_agent()) as session: try:
try: await AsyncHttpx.get("https://www.baidu.com/", timeout=5)
async with session.get( except Exception as e:
"https://www.baidu.com/", proxy=get_local_proxy(), timeout=3 logger.warning(f"访问BaiDu失败... {type(e)}: {e}")
) as response: self.baidu = 404
pass try:
except (TimeoutError, ClientConnectorError) as e: await AsyncHttpx.get("https://www.google.com/", timeout=5)
logger.warning(f"访问BaiDu失败... e: {e}") except Exception as e:
self.baidu = 404 logger.warning(f"访问Google失败... {type(e)}: {e}")
try: self.google = 404
async with session.get(
"https://www.google.com/", proxy=get_local_proxy(), timeout=3
) as response:
pass
except (TimeoutError, ClientConnectorError) as e:
logger.warning(f"访问Google失败... e: {e}")
self.google = 404
def check_user(self): def check_user(self):
rst = "" rst = ""
+126 -126
View File
@@ -1,126 +1,126 @@
from nonebot.adapters.cqhttp import Bot, MessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.typing import T_State 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
from services.log import logger from services.log import logger
from utils.utils import scheduler, get_bot 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
import platform import platform
import os import os
__zx_plugin_name__ = "自动更新 [Superuser]" __zx_plugin_name__ = "自动更新 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
检查更新真寻最新版本,包括了自动更新 检查更新真寻最新版本,包括了自动更新
指令: 指令:
检查更新真寻 检查更新真寻
重启 重启
""".strip() """.strip()
__plugin_des__ = "就算是真寻也会成长的" __plugin_des__ = "就算是真寻也会成长的"
__plugin_cmd__ = ["检查更新真寻", "重启"] __plugin_cmd__ = ["检查更新真寻", "重启"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_configs__ = { __plugin_configs__ = {
"AUTO_UPDATE_ZHENXUN": { "AUTO_UPDATE_ZHENXUN": {
"value": False, "value": False,
"help": "真寻是否自动检查更新", "help": "真寻是否自动检查更新",
"default": False, "default": False,
} }
} }
update_zhenxun = on_command("检查更新真寻", permission=SUPERUSER, priority=1, block=True) update_zhenxun = on_command("检查更新真寻", permission=SUPERUSER, priority=1, block=True)
restart = on_command( restart = on_command(
"重启", "重启",
aliases={"restart"}, aliases={"restart"},
permission=SUPERUSER, permission=SUPERUSER,
rule=to_me(), rule=to_me(),
priority=1, priority=1,
block=True, block=True,
) )
@update_zhenxun.handle() @update_zhenxun.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
try: try:
code, error = await check_update(bot) code, error = await check_update(bot)
if error: if error:
logger.error(f"更新真寻未知错误 {error}") logger.error(f"更新真寻未知错误 {error}")
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=f"更新真寻未知错误 {error}" user_id=int(list(bot.config.superusers)[0]), message=f"更新真寻未知错误 {error}"
) )
except Exception as e: except Exception as e:
logger.error(f"更新真寻未知错误 {type(e)}:{e}") logger.error(f"更新真寻未知错误 {type(e)}:{e}")
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"更新真寻未知错误 {type(e)}:{e}", message=f"更新真寻未知错误 {type(e)}:{e}",
) )
else: else:
if code == 200: if code == 200:
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=f"更新完毕,请重启真寻...." user_id=int(list(bot.config.superusers)[0]), message=f"更新完毕,请重启真寻...."
) )
@restart.handle() @restart.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
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 _(bot: Bot, event: MessageEvent, state: T_State):
flag = state["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")
os.system("./restart.sh") os.system("./restart.sh")
else: else:
await restart.send("已取消操作...") await restart.send("已取消操作...")
@scheduler.scheduled_job( @scheduler.scheduled_job(
"cron", "cron",
hour=12, hour=12,
minute=0, minute=0,
) )
async def _(): async def _():
if Config.get_config("check_zhenxun_update", "AUTO_UPDATE_ZHENXUN"): if Config.get_config("check_zhenxun_update", "AUTO_UPDATE_ZHENXUN"):
_version = "v0.0.0" _version = "v0.0.0"
_version_file = Path() / "__version__" _version_file = Path() / "__version__"
if _version_file.exists(): if _version_file.exists():
_version = ( _version = (
open(_version_file, "r", encoding="utf8") open(_version_file, "r", encoding="utf8")
.readline() .readline()
.split(":")[-1] .split(":")[-1]
.strip() .strip()
) )
data = await get_latest_version_data() data = await get_latest_version_data()
if data: if data:
latest_version = data["name"] latest_version = data["name"]
if _version != latest_version: if _version != latest_version:
bot = get_bot() bot = get_bot()
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}\n"
f"尝试自动更新...", f"尝试自动更新...",
) )
try: try:
code = await check_update(bot) code = await check_update(bot)
except Exception as e: except Exception as e:
logger.error(f"更新真寻未知错误 {type(e)}:{e}") logger.error(f"更新真寻未知错误 {type(e)}:{e}")
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"更新真寻未知错误 {type(e)}:{e}\n", message=f"更新真寻未知错误 {type(e)}:{e}\n",
) )
else: else:
if code == 200: if code == 200:
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"更新完毕,请重启真寻....", message=f"更新完毕,请重启真寻....",
) )
+212 -231
View File
@@ -1,231 +1,212 @@
from aiohttp.client_exceptions import ClientConnectorError from nonebot.adapters.cqhttp import Bot, Message
from nonebot.adapters.cqhttp import Bot, Message from utils.image_utils import CreateImg
from utils.user_agent import get_user_agent from configs.path_config import IMAGE_PATH
from utils.utils import get_local_proxy from utils.message_builder import image
from utils.image_utils import CreateImg from utils.http_utils import AsyncHttpx
from configs.path_config import IMAGE_PATH from typing import List
from utils.message_builder import image from services.log import logger
from typing import List from pathlib import Path
from services.log import logger import ujson as json
from pathlib import Path import nonebot
import ujson as json import asyncio
import nonebot import platform
import asyncio import tarfile
import aiofiles import shutil
import aiohttp import os
import platform
import tarfile if str(platform.system()).lower() == "windows":
import shutil policy = asyncio.WindowsSelectorEventLoopPolicy()
import os asyncio.set_event_loop_policy(policy)
if str(platform.system()).lower() == "windows":
policy = asyncio.WindowsSelectorEventLoopPolicy() driver = nonebot.get_driver()
asyncio.set_event_loop_policy(policy)
release_url = "https://api.github.com/repos/HibiKier/zhenxun_bot/releases/latest"
driver = nonebot.get_driver() _version_file = Path() / "__version__"
zhenxun_latest_tar_gz = Path() / "zhenxun_latest_file.tar.gz"
release_url = "https://api.github.com/repos/HibiKier/zhenxun_bot/releases/latest" temp_dir = Path() / "temp"
backup_dir = Path() / "backup"
_version_file = Path() / "__version__"
zhenxun_latest_tar_gz = Path() / "zhenxun_latest_file.tar.gz"
temp_dir = Path() / "temp" @driver.on_bot_connect
backup_dir = Path() / "backup" async def remind(bot: Bot):
if str(platform.system()).lower() != "windows":
restart = Path() / "restart.sh"
@driver.on_bot_connect if not restart.exists():
async def remind(bot: Bot): with open(restart, "w", encoding="utf8") as f:
if str(platform.system()).lower() != "windows": f.write(
restart = Path() / "restart.sh" f"pid=$(netstat -tunlp | grep "
if not restart.exists(): + str(bot.config.port)
with open(restart, "w", encoding="utf8") as f: + " | awk '{print $7}')\n"
f.write( "pid=${pid%/*}\n"
f"pid=$(netstat -tunlp | grep " "kill -9 $pid\n"
+ str(bot.config.port) "sleep 3\n"
+ " | awk '{print $7}')\n" "python3 bot.py"
"pid=${pid%/*}\n" )
"kill -9 $pid\n" os.system("chmod +x ./restart.sh")
"sleep 3\n" logger.info("已自动生成 restart.sh(重启) 文件,请检查脚本是否与本地指令符合...")
"python3 bot.py" is_restart_file = Path() / "is_restart"
) if is_restart_file.exists():
os.system("chmod +x ./restart.sh") await bot.send_private_msg(
logger.info("已自动生成 restart.sh(重启) 文件,请检查脚本是否与本地指令符合...") user_id=int(list(bot.config.superusers)[0]),
is_restart_file = Path() / "is_restart" message=f"真寻重启完毕...",
if is_restart_file.exists(): )
await bot.send_private_msg( is_restart_file.unlink()
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻重启完毕...",
) async def check_update(bot: Bot) -> 'int, str':
is_restart_file.unlink() logger.info("开始检查更新真寻酱....")
_version = "v0.0.0"
if _version_file.exists():
async def check_update(bot: Bot) -> 'int, str': _version = (
logger.info("开始检查更新真寻酱....") open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip()
_version = "v0.0.0" )
if _version_file.exists(): data = await get_latest_version_data()
_version = ( if data:
open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip() latest_version = data["name"]
) if _version != latest_version:
data = await get_latest_version_data() tar_gz_url = data["tarball_url"]
if data: logger.info(f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}")
latest_version = data["name"] await bot.send_private_msg(
if _version != latest_version: user_id=int(list(bot.config.superusers)[0]),
tar_gz_url = data["tarball_url"] message=f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}\n" f"开始更新.....",
logger.info(f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}") )
await bot.send_private_msg( logger.info(f"开始下载真寻最新版文件....")
user_id=int(list(bot.config.superusers)[0]), if await AsyncHttpx.download_file(tar_gz_url, zhenxun_latest_tar_gz):
message=f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}\n" f"开始更新.....", logger.info("下载真寻最新版文件完成....")
) error = await asyncio.get_event_loop().run_in_executor(
logger.info(f"开始下载真寻最新版文件....") None, _file_handle, latest_version
if await download_latest_file(tar_gz_url): )
logger.info("下载真寻最新版文件完成....") if error:
error = await asyncio.get_event_loop().run_in_executor( return 998, error
None, _file_handle, latest_version logger.info("真寻更新完毕,清理文件完成....")
) logger.info("开始获取真寻更新日志.....")
if error: update_info = data["body"]
return 998, error width = 0
logger.info("真寻更新完毕,清理文件完成....") height = len(update_info.split('\n')) * 24
logger.info("开始获取真寻更新日志.....") A = CreateImg(width, height, font_size=20)
update_info = data["body"] for m in update_info.split('\n'):
width = 0 w, h = A.getsize(m)
height = len(update_info.split('\n')) * 24 if w > width:
A = CreateImg(width, height, font_size=20) width = w
for m in update_info.split('\n'): A = CreateImg(width + 50, height, font_size=20)
w, h = A.getsize(m) A.text((10, 10), update_info)
if w > width: A.save(f'{IMAGE_PATH}/update_info.png')
width = w await bot.send_private_msg(
A = CreateImg(width + 50, height, font_size=20) user_id=int(list(bot.config.superusers)[0]),
A.text((10, 10), update_info) message=Message(f"真寻更新完成,版本:{_version} -> {latest_version}\n"
A.save(f'{IMAGE_PATH}/update_info.png') f"更新日期:{data['created_at']}\n"
await bot.send_private_msg( f"更新日志:\n"
user_id=int(list(bot.config.superusers)[0]), f"{image('update_info.png')}"),
message=Message(f"真寻更新完成,版本:{_version} -> {latest_version}\n" )
f"更新日期:{data['created_at']}\n" return 200, ''
f"更新日志:\n" else:
f"{image('update_info.png')}"), logger.warning(f"下载真寻最新版本失败...版本号:{latest_version}")
) await bot.send_private_msg(
return 200, '' user_id=int(list(bot.config.superusers)[0]),
else: message=f"下载真寻最新版本失败...版本号:{latest_version}.",
logger.warning(f"下载真寻最新版本失败...版本号:{latest_version}") )
await bot.send_private_msg( else:
user_id=int(list(bot.config.superusers)[0]), logger.info(f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...")
message=f"下载真寻最新版本失败...版本号:{latest_version}.", await bot.send_private_msg(
) user_id=int(list(bot.config.superusers)[0]),
else: message=f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...",
logger.info(f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...") )
await bot.send_private_msg( else:
user_id=int(list(bot.config.superusers)[0]), logger.warning("自动获取真寻版本失败....")
message=f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...", await bot.send_private_msg(
) user_id=int(list(bot.config.superusers)[0]), message=f"自动获取真寻版本失败...."
else: )
logger.warning("自动获取真寻版本失败....") return 999, ''
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=f"自动获取真寻版本失败...."
) def _file_handle(latest_version: str) -> str:
return 999, '' if not temp_dir.exists():
temp_dir.mkdir(exist_ok=True, parents=True)
if backup_dir.exists():
def _file_handle(latest_version: str) -> str: shutil.rmtree(backup_dir)
if not temp_dir.exists(): tf = None
temp_dir.mkdir(exist_ok=True, parents=True) error = ''
if backup_dir.exists(): try:
shutil.rmtree(backup_dir) backup_dir.mkdir(exist_ok=True, parents=True)
tf = None logger.info("开始解压真寻文件压缩包....")
error = '' tf = tarfile.open(zhenxun_latest_tar_gz)
try: tf.extractall(temp_dir)
backup_dir.mkdir(exist_ok=True, parents=True) logger.info("解压真寻文件压缩包完成....")
logger.info("开始解压真寻文件压缩包....") zhenxun_latest_file = Path(temp_dir) / os.listdir(temp_dir)[0]
tf = tarfile.open(zhenxun_latest_tar_gz) update_info_file = Path(zhenxun_latest_file) / "update_info.json"
tf.extractall(temp_dir) update_info = json.load(open(update_info_file, "r", encoding="utf8"))
logger.info("解压真寻文件压缩包完成....") update_file = update_info["update_file"]
zhenxun_latest_file = Path(temp_dir) / os.listdir(temp_dir)[0] add_file = update_info["add_file"]
update_info_file = Path(zhenxun_latest_file) / "update_info.json" delete_file = update_info["delete_file"]
update_info = json.load(open(update_info_file, "r", encoding="utf8")) config_file = Path() / "configs" / "config.py"
update_file = update_info["update_file"] config_path_file = Path() / "configs" / "config_path.py"
add_file = update_info["add_file"] for file in delete_file + update_file:
delete_file = update_info["delete_file"] file = Path() / file
config_file = Path() / "configs" / "config.py" backup_file = Path(backup_dir) / file
config_path_file = Path() / "configs" / "config_path.py" if file.exists():
for file in delete_file + update_file: backup_file.parent.mkdir(parents=True, exist_ok=True)
file = Path() / file if backup_file.exists():
backup_file = Path(backup_dir) / file backup_file.unlink()
if file.exists(): if file not in [config_file, config_path_file]:
backup_file.parent.mkdir(parents=True, exist_ok=True) os.rename(file.absolute(), backup_file.absolute())
if backup_file.exists(): else:
backup_file.unlink() with open(file, "r", encoding="utf8") as rf:
if file not in [config_file, config_path_file]: data = rf.read()
os.rename(file.absolute(), backup_file.absolute()) with open(backup_file, "w", encoding="utf8") as wf:
else: wf.write(data)
with open(file, "r", encoding="utf8") as rf: logger.info(f"已备份文件:{file}")
data = rf.read() for file in add_file + update_file:
with open(backup_file, "w", encoding="utf8") as wf: new_file = Path(zhenxun_latest_file) / file
wf.write(data) old_file = Path() / file
logger.info(f"已备份文件:{file}") if old_file not in [config_file, config_path_file]:
for file in add_file + update_file: if not old_file.exists() and new_file.exists():
new_file = Path(zhenxun_latest_file) / file os.rename(new_file.absolute(), old_file.absolute())
old_file = Path() / file logger.info(f"已更新文件:{file}")
if old_file not in [config_file, config_path_file]: else:
if not old_file.exists() and new_file.exists(): tmp = ""
os.rename(new_file.absolute(), old_file.absolute()) new_lines = open(new_file, "r", encoding="utf8").readlines()
logger.info(f"已更新文件:{file}") old_lines = open(old_file, "r", encoding="utf8").readlines()
else: for nl in new_lines:
tmp = "" tmp += check_old_lines(old_lines, nl)
new_lines = open(new_file, "r", encoding="utf8").readlines() with open(file, "w", encoding="utf8") as f:
old_lines = open(old_file, "r", encoding="utf8").readlines() f.write(tmp)
for nl in new_lines: except Exception as e:
tmp += check_old_lines(old_lines, nl) error = f'{type(e)}:{e}'
with open(file, "w", encoding="utf8") as f: if tf:
f.write(tmp) tf.close()
except Exception as e: if temp_dir.exists():
error = f'{type(e)}:{e}' shutil.rmtree(temp_dir)
if tf: if zhenxun_latest_tar_gz.exists():
tf.close() zhenxun_latest_tar_gz.unlink()
if temp_dir.exists(): local_update_info_file = Path() / "update_info.json"
shutil.rmtree(temp_dir) if local_update_info_file.exists():
if zhenxun_latest_tar_gz.exists(): local_update_info_file.unlink()
zhenxun_latest_tar_gz.unlink() with open(_version_file, "w", encoding="utf8") as f:
local_update_info_file = Path() / "update_info.json" f.write(f"__version__: {latest_version}")
if local_update_info_file.exists(): return error
local_update_info_file.unlink()
with open(_version_file, "w", encoding="utf8") as f:
f.write(f"__version__: {latest_version}") # 获取最新版本号
return error async def get_latest_version_data() -> dict:
for _ in range(3):
try:
# 获取最新版本号 res = await AsyncHttpx.get(release_url)
async def get_latest_version_data() -> dict: if res.status_code == 200:
async with aiohttp.ClientSession(headers=get_user_agent()) as session: return res.json()
for _ in range(3): except TimeoutError:
try: pass
async with session.get(release_url, proxy=get_local_proxy()) as res: except Exception as e:
if res.status == 200: logger.error(f"检查更新真寻获取版本失败 {type(e)}:{e}")
return await res.json() return {}
except (TimeoutError, ClientConnectorError):
pass
return {} # 逐行检测
def check_old_lines(lines: List[str], line: str) -> str:
if "=" not in line:
# 下载文件 return line
async def download_latest_file(url_: str) -> bool: for l in lines:
async with aiohttp.ClientSession(headers=get_user_agent()) as session: if "=" in l and l.split("=")[0].strip() == line.split("=")[0].strip():
for _ in range(3): return l
try: return line
async with session.get(url_, proxy=get_local_proxy()) as res:
if res.status == 200:
async with aiofiles.open(zhenxun_latest_tar_gz, "wb") as f:
await f.write(await res.read())
return True
except (TimeoutError, ClientConnectorError):
pass
return False
# 逐行检测
def check_old_lines(lines: List[str], line: str) -> str:
if "=" not in line:
return line
for l in lines:
if "=" in l and l.split("=")[0].strip() == line.split("=")[0].strip():
if l.split("=")[1].strip() == 'None':
return l
return line
Regular → Executable
+8 -38
View File
@@ -1,13 +1,8 @@
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 from nonebot.adapters.cqhttp import Bot, MessageEvent
from services.log import logger
from asyncio.exceptions import TimeoutError
from utils.message_builder import image from utils.message_builder import image
from configs.path_config import IMAGE_PATH from services.log import logger
from utils.utils import get_local_proxy
import aiohttp
import aiofiles
__zx_plugin_name__ = "coser" __zx_plugin_name__ = "coser"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -32,38 +27,13 @@ coser = on_command(
) )
url = "http://ovooa.com/API/cosplay/api.php" url = "http://iw233.cn/API/cos.php"
@coser.handle() @coser.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
async with aiohttp.ClientSession() as session: try:
try: await coser.send(image(url))
for _ in range(3): except Exception as e:
try: await coser.send("你cos给我看!")
async with session.get(url, proxy=get_local_proxy(), timeout=2, verify_ssl=False) as response: logger.error(f"coser 发送了未知错误 {type(e)}:{e}")
_url = (await response.json())['text']
async with session.get(
_url, timeout=5, proxy=get_local_proxy(), verify_ssl=False
) as res:
if res.status == 200:
async with aiofiles.open(
f"{IMAGE_PATH}/temp/{event.user_id}_coser.jpg", "wb"
) as f:
await f.write(await res.read())
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送COSER"
)
await coser.send(
image(f"{event.user_id}_coser.jpg", "temp")
)
break
except (TimeoutError, KeyError):
pass
else:
await coser.send("你cos给我看!")
except Exception as e:
await coser.send("发生了预料之外的错误..请稍后再试或联系管理员修复...")
logger.error(f"coser 发送了未知错误 {type(e)}:{e}")
-69
View File
@@ -1,69 +0,0 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
from utils.utils import get_message_text, is_number
from .data_source import get_csgola_data, get_5e_data
from services.log import logger
__zx_plugin_name__ = "cs国服/平台信息查找"
__plugin_usage__ = """
usage:
快速查询csgo战绩和数据
指令:
cs国服查询 [steam主页个人id]
5e查询 [5e战绩个人名称]
示例:cs国服查询 23848238483
示例:5e查询 poster
"""
__plugin_des__ = "什么?你也是rush B玩家?"
__plugin_cmd__ = ["cs国服查询 [steam主页个人id]", "5e查询 [5e战绩个人名称]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["csgo战绩查询", "cs国服查询", "5e查询"],
}
csgola = on_command("cs国服查询", priority=5, block=True)
csgo5e = on_command("5e查询", priority=5, block=True)
@csgola.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if "http" in msg:
msg = msg[:-1] if msg[-1] == "/" else msg
msg = msg.split("/")[-1]
if not is_number(msg):
await csgola.finish("Id必须为数字!", at_sender=True)
await csgola.send("开始查找...")
img, code = await get_csgola_data(int(msg))
if code == 200:
await csgola.send(img, at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询csgo国服战绩:{msg}"
)
else:
await csgola.send(img, at_sender=True)
@csgo5e.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
await csgola.send("开始查找...")
img, code = await get_5e_data(msg)
if code == 200:
await csgo5e.send(img, at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询csgo国服战绩:{msg}"
)
else:
await csgo5e.send(img, at_sender=True)
-130
View File
@@ -1,130 +0,0 @@
from configs.path_config import IMAGE_PATH
from utils.image_utils import CreateImg
from utils.message_builder import image
from services.log import logger
from utils.browser import get_browser
from playwright._impl._api_types import TimeoutError
csgola_url = "https://www.csgola.com/player/"
_5e_url = "https://arena.5eplay.com/data/player/"
async def get_csgola_data(uid: int) -> "str, int":
page = None
try:
browser = await get_browser()
if not browser:
return "", 997
page = await browser.new_page()
for _ in range(3):
try:
await page.goto(f"{csgola_url}{uid}", wait_until="networkidle", timeout=10000)
break
except TimeoutError:
pass
else:
return '连接超时...', 995
await page.set_viewport_size({"width": 2560, "height": 1080})
data = await page.query_selector_all(".panel-body")
if not data:
return "未查询到该Id....", 999
await data[0].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_1.png", timeout=100000)
await data[3].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_2.png", timeout=100000)
await data[5].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_3.png", timeout=100000)
await data[7].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_5.png", timeout=100000)
ava = await page.query_selector("div.container:nth-child(4) > div:nth-child(1)")
await ava.screenshot(path=f"{IMAGE_PATH}/temp/{uid}_0.png", timeout=100000)
weapon_data = await page.query_selector(".gun-stats-sec")
await weapon_data.screenshot(
path=f"{IMAGE_PATH}/temp/{uid}_4.png", timeout=100000
)
ava = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_0.png")
statistical_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_1.png")
combined_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_2.png")
detailed_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_3.png")
weapon_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_4.png")
map_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_5.png")
if statistical_data.h > 300:
statistical_data.crop((0, 0, statistical_data.w, 300))
if combined_data.h > 260:
combined_data.crop((0, 0, combined_data.w, 260))
if detailed_data.h > 400:
detailed_data.crop((0, 0, detailed_data.w, 400))
weapon_data.crop((0, 100, weapon_data.w, weapon_data.h))
map_data.crop((0, 310, map_data.w, map_data.h))
height = (
ava.h
+ statistical_data.h
+ combined_data.h
+ detailed_data.h
+ weapon_data.h
+ map_data.h
)
bk = CreateImg(1168, height)
current_h = 0
for img in [
ava,
statistical_data,
combined_data,
detailed_data,
weapon_data,
map_data,
]:
bk.paste(img, (0, current_h))
current_h += img.h
bk.save(f"{IMAGE_PATH}/temp/csgo_{uid}.png")
except Exception as e:
logger.error(f"生成csgola图片错误 {type(e)}:{e}")
if page:
await page.close()
return "发生了错误....", 998
if page:
await page.close()
return image(f"csgo_{uid}.png", "temp"), 200
async def get_5e_data(uname: str) -> "str, int":
page = None
try:
browser = await get_browser()
if not browser:
return "", 997
page = await browser.new_page()
await page.goto(f"{_5e_url}{uname}", wait_until="networkidle", timeout=10000)
if "HTTP ERROR 404" in await page.content():
return "未查询到该玩家...", 999
await page.set_viewport_size({"width": 2560, "height": 1080})
body = await page.query_selector("body")
await body.screenshot(
path=f"{IMAGE_PATH}/temp/csgo_{uname}_0.png", timeout=100000
)
await page.click("a.match-tab-item:nth-child(2)")
body = await page.query_selector("body")
await body.screenshot(
path=f"{IMAGE_PATH}/temp/csgo_{uname}_1.png", timeout=100000
)
await page.click("a.match-tab-item:nth-child(1)")
body = await page.query_selector("body")
await body.screenshot(
path=f"{IMAGE_PATH}/temp/csgo_{uname}_2.png", timeout=100000
)
bk = CreateImg(1344 * 3, 2307)
current_w = 0
for i in range(3):
body = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/csgo_{uname}_{i}.png")
body.crop((600, 90, body.w - 600, body.h - 410))
bk.paste(body, (current_w, 0))
current_w += 1344
bk.save(f"{IMAGE_PATH}/temp/csgo_{uname}.png")
except Exception as e:
logger.error(f"生成5e图片错误 {type(e)}:{e}")
if page:
await page.close()
return "发生了错误...", 998
if page:
await page.close()
return image(f"csgo_{uname}.png", "temp"), 200
Regular → Executable
View File
Regular → Executable
View File
+26 -33
View File
@@ -1,11 +1,11 @@
import aiohttp
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from .config import DRAW_PATH from .config import DRAW_PATH
from pathlib import Path from pathlib import Path
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from services.log import logger from services.log import logger
from utils.http_utils import AsyncHttpx
import re
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -66,16 +66,14 @@ class PrtsAnnouncement:
self.game_name = '明日方舟' self.game_name = '明日方舟'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: text = (await AsyncHttpx.get(prts_url)).text
async with session.get(prts_url, timeout=7) as res: soup = BeautifulSoup(text, 'lxml')
soup = BeautifulSoup(await 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
itype = li.find('span', {'class': 'articleItemCate'}).text if itype == '活动':
if itype == '活动': a = li.find('a')['href']
a = li.find('a')['href'] return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}')).text
async with session.get(f'https://ak.hypergryph.com{a}', headers=headers, timeout=7) as res:
return await res.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)
@@ -147,9 +145,7 @@ class GenshinAnnouncement:
self.game_name = '原神' self.game_name = '原神'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: return (await AsyncHttpx.get(genshin_url)).text
async with session.get(genshin_url, timeout=7) as res:
return await res.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)
@@ -218,21 +214,20 @@ class PrettyAnnouncement:
self.game_name = '赛马娘' self.game_name = '赛马娘'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: text = (await AsyncHttpx.get(pretty_url)).text
async with session.get(pretty_url, timeout=7) as res: soup = BeautifulSoup(text, 'lxml')
soup = BeautifulSoup(await 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:
title = a['title'] title = a['title']
except (KeyError, TypeError): except (KeyError, TypeError):
continue continue
if title.find('新角色追加') != -1: if title.find('新角色追加') != -1:
url = a['href'] url = a['href']
break break
async with session.get(f'https://wiki.biligame.com/{url}', timeout=7) as res: return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}')).text, title[:-2]
return await res.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) pretty_up_char.parent.mkdir(exist_ok=True, parents=True)
@@ -343,9 +338,7 @@ class GuardianAnnouncement:
self.game_name = '坎公骑冠剑' self.game_name = '坎公骑冠剑'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: return (await AsyncHttpx.get(guardian_url)).text
async with session.get(guardian_url, timeout=7) as res:
return await res.text()
async def update_up_char(self): async def update_up_char(self):
data = { data = {
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
View File
+39 -11
View File
@@ -2,6 +2,7 @@ from typing import Any
from .config import DATA_PATH from .config import DATA_PATH
from utils.utils import is_number from utils.utils import is_number
from pathlib import Path from pathlib import Path
from services.log import logger
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -27,8 +28,11 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = True limited = True
if key.find('阿米娅') != -1: if key.find('阿米娅') != -1:
continue continue
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']), try:
limited=limited, recruit_only=recruit_only, event_only=event_only)) tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
limited=limited, recruit_only=recruit_only, event_only=event_only))
except Exception as e:
logger.warning(f"明日方舟导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin': if game == 'genshin':
for key in data.keys(): for key in data.keys():
if key.find('旅行者') != -1: if key.find('旅行者') != -1:
@@ -36,17 +40,26 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = False limited = False
if data[key]['常驻/限定'] == '限定UP': if data[key]['常驻/限定'] == '限定UP':
limited = True limited = True
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited)) try:
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
except Exception as e:
logger.warning(f"原神导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin_arms': if game == 'genshin_arms':
for key in data.keys(): 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
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited)) try:
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
except Exception as e:
logger.warning(f"原神导入武器 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty': if game == 'pretty':
for key in data.keys(): for key in data.keys():
tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False)) try:
tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False))
except Exception as e:
logger.warning(f"赛马娘导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty_card': if game == 'pretty_card':
for key in data.keys(): for key in data.keys():
limited = False limited = False
@@ -54,7 +67,10 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = True limited = True
if not data[key]['获取方式']: if not data[key]['获取方式']:
limited = False limited = False
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited)) try:
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited))
except Exception as e:
logger.warning(f"赛马娘导入卡片 {key} 数据错误:{type(e)}:{e}")
if game in ['guardian', 'guardian_arms']: if game in ['guardian', 'guardian_arms']:
for key in data.keys(): for key in data.keys():
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False)) tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False))
@@ -63,15 +79,21 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = False limited = False
if key.find('(') != -1: if key.find('(') != -1:
limited = True limited = True
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited)) try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
except Exception as e:
logger.warning(f"公主连接导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'azur': if game == 'azur':
for key in data.keys(): 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
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), try:
limited=limited, itype=data[key]['类型'])) tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
limited=limited, itype=data[key]['类型']))
except Exception as e:
logger.warning(f"碧蓝航线导入角色 {key} 数据错误:{type(e)}:{e}")
if game in ['fgo', 'fgo_card']: if game in ['fgo', 'fgo_card']:
for key in data.keys(): for key in data.keys():
limited = False limited = False
@@ -80,14 +102,20 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = True limited = True
except KeyError: except KeyError:
pass pass
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited)) try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
except Exception as e:
logger.warning(f"FGO导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'onmyoji': if game == 'onmyoji':
for key in data.keys(): for key in data.keys():
limited = False limited = False
if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护', if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护',
'灶门祢豆子', '灶门炭治郎']: '灶门祢豆子', '灶门炭治郎']:
limited = True limited = True
tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited)) try:
tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited))
except Exception as e:
logger.warning(f"阴阳师导入角色 {key} 数据错误:{type(e)}:{e}")
# print(tmp_lst) # 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 = Path(f'{DATA_PATH}/draw_card/draw_card_up/{game.split("_")[0]}_up_char.json')
-1
View File
@@ -6,7 +6,6 @@ from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max
from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_FLAG from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_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
import nonebot
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
Regular → Executable
-3
View File
@@ -1,7 +1,5 @@
import ujson as json import ujson as json
import os
from nonebot.adapters.cqhttp import MessageSegment from nonebot.adapters.cqhttp import MessageSegment
import nonebot
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
@@ -10,7 +8,6 @@ from .config import PCR_TWO_P, PCR_THREE_P, PCR_ONE_P, DRAW_PATH, PCR_FLAG, PCR_
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
driver: nonebot.Driver = nonebot.get_driver()
ALL_CHAR = [] ALL_CHAR = []

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