mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
优化manager代码
This commit is contained in:
parent
49e38862af
commit
cd66b7f5b8
@ -296,6 +296,10 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
|
|||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
|
### 2022/11/21
|
||||||
|
|
||||||
|
* 优化manager, hook代码
|
||||||
|
|
||||||
### 2022/11/19
|
### 2022/11/19
|
||||||
|
|
||||||
* 修改优化帮助图片生成逻辑
|
* 修改优化帮助图片生成逻辑
|
||||||
|
|||||||
@ -23,7 +23,7 @@ except ModuleNotFoundError:
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
async def group_current_status(group_id: int) -> str:
|
def group_current_status(group_id: int) -> str:
|
||||||
"""
|
"""
|
||||||
获取当前所有通知的开关
|
获取当前所有通知的开关
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
@ -31,17 +31,17 @@ async def group_current_status(group_id: int) -> str:
|
|||||||
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 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:
|
||||||
"""
|
"""
|
||||||
替换群欢迎消息
|
替换群欢迎消息
|
||||||
@ -104,20 +104,21 @@ async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
|
|||||||
if cmd == "全部被动":
|
if cmd == "全部被动":
|
||||||
for task in task_data:
|
for task in task_data:
|
||||||
if status == "开启":
|
if status == "开启":
|
||||||
if not await group_manager.check_group_task_status(group_id, task):
|
if not group_manager.check_group_task_status(group_id, task):
|
||||||
await group_manager.open_group_task(group_id, task)
|
group_manager.open_group_task(group_id, task)
|
||||||
else:
|
else:
|
||||||
if await group_manager.check_group_task_status(group_id, task):
|
if group_manager.check_group_task_status(group_id, task):
|
||||||
await group_manager.close_group_task(group_id, task)
|
group_manager.close_group_task(group_id, task)
|
||||||
if group_help_file.exists():
|
if group_help_file.exists():
|
||||||
group_help_file.unlink()
|
group_help_file.unlink()
|
||||||
return f"已 {status} 全部被动技能!"
|
return f"已 {status} 全部被动技能!"
|
||||||
if cmd == "全部功能":
|
if cmd == "全部功能":
|
||||||
for f in plugins2settings_manager.get_data():
|
for f in plugins2settings_manager.get_data():
|
||||||
if status == "开启":
|
if status == "开启":
|
||||||
group_manager.unblock_plugin(f, group_id)
|
group_manager.unblock_plugin(f, group_id, False)
|
||||||
else:
|
else:
|
||||||
group_manager.block_plugin(f, group_id)
|
group_manager.block_plugin(f, group_id, False)
|
||||||
|
group_manager.save()
|
||||||
if group_help_file.exists():
|
if group_help_file.exists():
|
||||||
group_help_file.unlink()
|
group_help_file.unlink()
|
||||||
return f"已 {status} 全部功能!"
|
return f"已 {status} 全部功能!"
|
||||||
@ -129,18 +130,18 @@ async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
|
|||||||
module = f"{module}:super"
|
module = f"{module}:super"
|
||||||
if status == "开启":
|
if status == "开启":
|
||||||
if type_ == "task":
|
if type_ == "task":
|
||||||
if await group_manager.check_group_task_status(group_id, module):
|
if group_manager.check_group_task_status(group_id, module):
|
||||||
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
|
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
|
||||||
await group_manager.open_group_task(group_id, module)
|
group_manager.open_group_task(group_id, module)
|
||||||
else:
|
else:
|
||||||
if group_manager.get_plugin_status(module, group_id):
|
if group_manager.get_plugin_status(module, group_id):
|
||||||
return f"功能 {cmd} 正处于开启状态!不要重复开启."
|
return f"功能 {cmd} 正处于开启状态!不要重复开启."
|
||||||
group_manager.unblock_plugin(module, group_id)
|
group_manager.unblock_plugin(module, group_id)
|
||||||
else:
|
else:
|
||||||
if type_ == "task":
|
if type_ == "task":
|
||||||
if not await group_manager.check_group_task_status(group_id, module):
|
if not group_manager.check_group_task_status(group_id, module):
|
||||||
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
|
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
|
||||||
await group_manager.close_group_task(group_id, module)
|
group_manager.close_group_task(group_id, module)
|
||||||
else:
|
else:
|
||||||
if not group_manager.get_plugin_status(module, group_id):
|
if not group_manager.get_plugin_status(module, group_id):
|
||||||
return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
|
return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
|
||||||
@ -197,17 +198,17 @@ def _get_plugin_status() -> MessageSegment:
|
|||||||
flag = plugins_manager.get_plugin_block_type(module)
|
flag = plugins_manager.get_plugin_block_type(module)
|
||||||
flag = flag.upper() + " CLOSE" if flag else "OPEN"
|
flag = flag.upper() + " CLOSE" if flag else "OPEN"
|
||||||
try:
|
try:
|
||||||
plugin_name = plugins_manager.get(module)["plugin_name"]
|
plugin_name = plugins_manager.get(module).plugin_name
|
||||||
if (
|
if (
|
||||||
"[Hidden]" in plugin_name
|
"[Hidden]" in plugin_name
|
||||||
or "[Admin]" in plugin_name
|
or "[Admin]" in plugin_name
|
||||||
or "[Superuser]" in plugin_name
|
or "[Superuser]" in plugin_name
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
rst += f"{plugin_name}"
|
rst += f"{plugin_name}"
|
||||||
except KeyError:
|
except KeyError:
|
||||||
rst += f"{module}"
|
rst += f"{module}"
|
||||||
if plugins_manager.get(module)["error"]:
|
if plugins_manager.get(module).error:
|
||||||
rst += "[ERROR]"
|
rst += "[ERROR]"
|
||||||
rst += "\n"
|
rst += "\n"
|
||||||
flag_str += f"{flag}\n"
|
flag_str += f"{flag}\n"
|
||||||
@ -238,12 +239,12 @@ async def update_member_info(group_id: int, remind_superuser: bool = False) -> b
|
|||||||
async with db.transaction():
|
async with db.transaction():
|
||||||
# 更新权限
|
# 更新权限
|
||||||
if (
|
if (
|
||||||
user_info["role"]
|
user_info["role"]
|
||||||
in [
|
in [
|
||||||
"owner",
|
"owner",
|
||||||
"admin",
|
"admin",
|
||||||
]
|
]
|
||||||
and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
|
and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
|
||||||
):
|
):
|
||||||
await LevelUser.set_level(
|
await LevelUser.set_level(
|
||||||
user_info["user_id"],
|
user_info["user_id"],
|
||||||
@ -272,10 +273,10 @@ async def update_member_info(group_id: int, remind_superuser: bool = False) -> b
|
|||||||
"%Y-%m-%d %H:%M:%S",
|
"%Y-%m-%d %H:%M:%S",
|
||||||
)
|
)
|
||||||
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"],
|
||||||
nickname,
|
nickname,
|
||||||
join_time,
|
join_time,
|
||||||
):
|
):
|
||||||
_exist_member_list.append(int(user_info["user_id"]))
|
_exist_member_list.append(int(user_info["user_id"]))
|
||||||
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
||||||
@ -317,7 +318,4 @@ def set_group_bot_status(group_id: int, status: bool) -> str:
|
|||||||
return "呜..醒来了..."
|
return "呜..醒来了..."
|
||||||
else:
|
else:
|
||||||
group_manager.shutdown_group_bot_status(group_id)
|
group_manager.shutdown_group_bot_status(group_id)
|
||||||
# for x in group_manager.get_task_data():
|
|
||||||
# group_manager.close_group_task(group_id, x)
|
|
||||||
return "那我先睡觉了..."
|
return "那我先睡觉了..."
|
||||||
|
|
||||||
|
|||||||
@ -2,18 +2,23 @@ from nonebot.adapters.onebot.v11 import Event
|
|||||||
from utils.manager import group_manager, plugins2settings_manager
|
from utils.manager import group_manager, plugins2settings_manager
|
||||||
from utils.utils import get_message_text
|
from utils.utils import get_message_text
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
|
import time
|
||||||
|
|
||||||
cmd = []
|
cmd = []
|
||||||
|
|
||||||
|
v = time.time()
|
||||||
|
|
||||||
|
|
||||||
def switch_rule(event: Event) -> bool:
|
def switch_rule(event: Event) -> bool:
|
||||||
"""
|
"""
|
||||||
检测文本是否是关闭功能命令
|
说明:
|
||||||
:param event: pass
|
检测文本是否是关闭功能命令
|
||||||
|
参数:
|
||||||
|
:param event: pass
|
||||||
"""
|
"""
|
||||||
global cmd
|
global cmd
|
||||||
try:
|
try:
|
||||||
if not cmd:
|
if not cmd or time.time() - v > 60 * 60:
|
||||||
cmd = ["关闭全部被动", "开启全部被动", "开启全部功能", "关闭全部功能"]
|
cmd = ["关闭全部被动", "开启全部被动", "开启全部功能", "关闭全部功能"]
|
||||||
_data = group_manager.get_task_data()
|
_data = group_manager.get_task_data()
|
||||||
for key in _data:
|
for key in _data:
|
||||||
@ -22,10 +27,10 @@ def switch_rule(event: Event) -> bool:
|
|||||||
cmd.append(f"开启 {_data[key]}")
|
cmd.append(f"开启 {_data[key]}")
|
||||||
cmd.append(f"关闭 {_data[key]}")
|
cmd.append(f"关闭 {_data[key]}")
|
||||||
_data = plugins2settings_manager.get_data()
|
_data = plugins2settings_manager.get_data()
|
||||||
for key in _data:
|
for key in _data.keys():
|
||||||
try:
|
try:
|
||||||
if isinstance(_data[key]["cmd"], list):
|
if isinstance(_data[key].cmd, list):
|
||||||
for x in _data[key]["cmd"]:
|
for x in _data[key].cmd:
|
||||||
cmd.append(f"开启{x}")
|
cmd.append(f"开启{x}")
|
||||||
cmd.append(f"关闭{x}")
|
cmd.append(f"关闭{x}")
|
||||||
cmd.append(f"开启 {x}")
|
cmd.append(f"开启 {x}")
|
||||||
|
|||||||
@ -110,7 +110,7 @@ async def _():
|
|||||||
|
|
||||||
@group_task_status.handle()
|
@group_task_status.handle()
|
||||||
async def _(event: GroupMessageEvent):
|
async def _(event: GroupMessageEvent):
|
||||||
await group_task_status.send(await group_current_status(event.group_id))
|
await group_task_status.send(group_current_status(event.group_id))
|
||||||
|
|
||||||
|
|
||||||
@group_status.handle()
|
@group_status.handle()
|
||||||
|
|||||||
@ -16,9 +16,9 @@ admin_help_image = 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():
|
||||||
if not group_manager.get_task_data():
|
if not group_manager.get_task_data():
|
||||||
await group_manager.init_group_task()
|
group_manager.load_task()
|
||||||
logger.info(f'已成功加载 {len(group_manager.get_task_data())} 个被动技能.')
|
logger.info(f'已成功加载 {len(group_manager.get_task_data())} 个被动技能.')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -44,7 +44,7 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
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 group_manager.check_group_task_status(g["group_id"], "broadcast")
|
||||||
]
|
]
|
||||||
g_cnt = len(gl)
|
g_cnt = len(gl)
|
||||||
cnt = 0
|
cnt = 0
|
||||||
|
|||||||
@ -40,16 +40,14 @@ async def _create_help_img(
|
|||||||
:param help_image: 图片路径
|
:param help_image: 图片路径
|
||||||
:param simple_help_image: 简易帮助图片路径
|
:param simple_help_image: 简易帮助图片路径
|
||||||
"""
|
"""
|
||||||
_matchers = get_matchers(True)
|
|
||||||
width = 0
|
width = 0
|
||||||
matchers_data = {}
|
matchers_data = {}
|
||||||
_des_tmp = {}
|
_des_tmp = {}
|
||||||
_plugin_name_tmp = []
|
|
||||||
_tmp = []
|
_tmp = []
|
||||||
tmp_img = BuildImage(0, 0, plain_text="1", font_size=24)
|
tmp_img = BuildImage(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 get_matchers(True):
|
||||||
plugin_name = None
|
plugin_name = None
|
||||||
_plugin = matcher.plugin
|
_plugin = matcher.plugin
|
||||||
if not _plugin:
|
if not _plugin:
|
||||||
@ -67,7 +65,6 @@ async def _create_help_img(
|
|||||||
"[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 == "帮助"
|
or plugin_name == "帮助"
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
@ -75,11 +72,9 @@ async def _create_help_img(
|
|||||||
text_type = 0
|
text_type = 0
|
||||||
if plugins2settings_manager.get(
|
if plugins2settings_manager.get(
|
||||||
matcher.plugin_name
|
matcher.plugin_name
|
||||||
) and plugins2settings_manager[matcher.plugin_name].get("plugin_type"):
|
) and plugins2settings_manager.get(matcher.plugin_name).plugin_type:
|
||||||
plugin_type = tuple(
|
plugin_type = tuple(
|
||||||
plugins2settings_manager.get_plugin_data(matcher.plugin_name)[
|
plugins2settings_manager.get_plugin_data(matcher.plugin_name).plugin_type
|
||||||
"plugin_type"
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@ -128,10 +123,7 @@ async def _create_help_img(
|
|||||||
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:
|
logger.warning(f"获取功能 {matcher.plugin_name}: {plugin_name} 设置失败...e:{e}")
|
||||||
logger.warning(f"获取功能 {matcher.plugin_name}: {plugin_name} 设置失败...e:{e}")
|
|
||||||
if plugin_name not in _plugin_name_tmp:
|
|
||||||
_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())
|
||||||
@ -284,45 +276,13 @@ async def _create_help_img(
|
|||||||
B.save(simple_help_image)
|
B.save(simple_help_image)
|
||||||
|
|
||||||
|
|
||||||
def get_max_width_or_paste(
|
|
||||||
simple_help_img_list: List[BuildImage], B: BuildImage = None, is_paste: bool = False
|
|
||||||
) -> Tuple[int, BuildImage]:
|
|
||||||
"""
|
|
||||||
获取最大宽度,或直接贴图
|
|
||||||
:param simple_help_img_list: 简单帮助图片列表
|
|
||||||
:param B: 背景图
|
|
||||||
:param is_paste: 是否直接贴图
|
|
||||||
"""
|
|
||||||
current_width = 50
|
|
||||||
current_height = 180
|
|
||||||
max_width = simple_help_img_list[0].w
|
|
||||||
for i in range(len(simple_help_img_list)):
|
|
||||||
try:
|
|
||||||
if is_paste and B:
|
|
||||||
B.paste(simple_help_img_list[i], (current_width, current_height), True)
|
|
||||||
current_height += simple_help_img_list[i].h + 40
|
|
||||||
if current_height + simple_help_img_list[i + 1].h > B.h - 10:
|
|
||||||
current_height = 180
|
|
||||||
current_width += max_width + 30
|
|
||||||
max_width = 0
|
|
||||||
elif simple_help_img_list[i].w > max_width:
|
|
||||||
max_width = simple_help_img_list[i].w
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
if current_width > simple_help_img_list[0].w + 50:
|
|
||||||
current_width += simple_help_img_list[-1].w
|
|
||||||
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) or admin_manager.get_plugin_module(msg)
|
||||||
if not module:
|
|
||||||
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)
|
||||||
|
|||||||
@ -1,5 +1,37 @@
|
|||||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent
|
from typing import Optional
|
||||||
from utils.manager import plugins2block_manager, StaticData
|
|
||||||
|
import nonebot
|
||||||
|
from nonebot.adapters.onebot.v11 import (
|
||||||
|
GroupMessageEvent,
|
||||||
|
PrivateMessageEvent,
|
||||||
|
Bot,
|
||||||
|
Event,
|
||||||
|
MessageEvent,
|
||||||
|
Message,
|
||||||
|
PokeNotifyEvent,
|
||||||
|
)
|
||||||
|
from nonebot.exception import ActionFailed, IgnoredException
|
||||||
|
from nonebot.internal.matcher import Matcher
|
||||||
|
|
||||||
|
from models.bag_user import BagUser
|
||||||
|
from models.ban_user import BanUser
|
||||||
|
from models.friend_user import FriendUser
|
||||||
|
from models.group_member_info import GroupInfoUser
|
||||||
|
from models.level_user import LevelUser
|
||||||
|
from models.user_shop_gold_log import UserShopGoldLog
|
||||||
|
from utils.manager import (
|
||||||
|
plugins2block_manager,
|
||||||
|
StaticData,
|
||||||
|
plugins2settings_manager,
|
||||||
|
group_manager,
|
||||||
|
admin_manager,
|
||||||
|
plugins_manager,
|
||||||
|
plugins2cd_manager,
|
||||||
|
plugins2count_manager,
|
||||||
|
)
|
||||||
|
from utils.message_builder import at
|
||||||
|
from utils.utils import FreqLimiter
|
||||||
|
from configs.config import Config
|
||||||
import time
|
import time
|
||||||
|
|
||||||
ignore_rst_module = ["ai", "poke", "dialogue"]
|
ignore_rst_module = ["ai", "poke", "dialogue"]
|
||||||
@ -8,7 +40,6 @@ other_limit_plugins = ["poke"]
|
|||||||
|
|
||||||
|
|
||||||
class StatusMessageManager(StaticData):
|
class StatusMessageManager(StaticData):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(None)
|
super().__init__(None)
|
||||||
|
|
||||||
@ -39,8 +70,8 @@ def set_block_limit_false(event, 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")
|
||||||
@ -50,3 +81,436 @@ def set_block_limit_false(event, module):
|
|||||||
block_type_ = event.group_id
|
block_type_ = event.group_id
|
||||||
plugins2block_manager.set_false(block_type_, module)
|
plugins2block_manager.set_false(block_type_, module)
|
||||||
|
|
||||||
|
|
||||||
|
async def send_msg(msg: str, bot: Bot, event: MessageEvent):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
发送信息
|
||||||
|
参数:
|
||||||
|
:param msg: pass
|
||||||
|
:param bot: pass
|
||||||
|
:param event: pass
|
||||||
|
"""
|
||||||
|
if "[uname]" in msg:
|
||||||
|
uname = event.sender.card or event.sender.nickname
|
||||||
|
msg = msg.replace("[uname]", uname)
|
||||||
|
if "[nickname]" in msg:
|
||||||
|
if isinstance(event, GroupMessageEvent):
|
||||||
|
nickname = await GroupInfoUser.get_group_member_nickname(
|
||||||
|
event.user_id, event.group_id
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
nickname = await FriendUser.get_friend_nickname(event.user_id)
|
||||||
|
msg = msg.replace("[nickname]", nickname)
|
||||||
|
if "[at]" in msg and isinstance(event, GroupMessageEvent):
|
||||||
|
msg = msg.replace("[at]", str(at(event.user_id)))
|
||||||
|
try:
|
||||||
|
if isinstance(event, GroupMessageEvent):
|
||||||
|
status_message_manager.add(event.group_id)
|
||||||
|
await bot.send_group_msg(group_id=event.group_id, message=Message(msg))
|
||||||
|
else:
|
||||||
|
status_message_manager.add(event.user_id)
|
||||||
|
await bot.send_private_msg(user_id=event.user_id, message=Message(msg))
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ReturnException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AuthChecker:
|
||||||
|
"""
|
||||||
|
权限检查
|
||||||
|
"""
|
||||||
|
|
||||||
|
checker: Optional["AuthChecker"] = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._flmt = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
||||||
|
self._flmt_g = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
||||||
|
self._flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
||||||
|
self._flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
if not cls.checker:
|
||||||
|
cls.checker = super().__new__(cls)
|
||||||
|
return cls.checker
|
||||||
|
|
||||||
|
async def auth(self, matcher: Matcher, bot: Bot, event: Event):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
权限检查
|
||||||
|
参数:
|
||||||
|
:param matcher: matcher
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
plugin_name = matcher.plugin_name
|
||||||
|
cost_gold = await self.auth_cost(plugin_name, bot, event)
|
||||||
|
await self.auth_basic(plugin_name, bot, event)
|
||||||
|
self.auth_group(plugin_name, bot, event)
|
||||||
|
await self.auth_admin(plugin_name, matcher, bot, event)
|
||||||
|
await self.auth_plugin(plugin_name, matcher, bot, event)
|
||||||
|
await self.auth_limit(plugin_name, bot, event)
|
||||||
|
if cost_gold and str(event.user_id) not in bot.config.superusers:
|
||||||
|
await BagUser.spend_gold(event.user_id, event.group_id, cost_gold)
|
||||||
|
except ReturnException:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def auth_limit(self, plugin_name: str, bot: Bot, event: Event):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
插件限制
|
||||||
|
参数:
|
||||||
|
:param plugin_name: 模块名
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
if plugins2cd_manager.check_plugin_cd_status(plugin_name):
|
||||||
|
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(plugin_name)
|
||||||
|
check_type = plugin_cd_data.check_type
|
||||||
|
limit_type = plugin_cd_data.limit_type
|
||||||
|
msg = plugin_cd_data.rst
|
||||||
|
if (
|
||||||
|
(isinstance(event, PrivateMessageEvent) and check_type == "private")
|
||||||
|
or (isinstance(event, GroupMessageEvent) and check_type == "group")
|
||||||
|
or plugins2cd_manager.get_plugin_data(plugin_name).check_type == "all"
|
||||||
|
):
|
||||||
|
cd_type_ = event.user_id
|
||||||
|
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||||
|
cd_type_ = event.group_id
|
||||||
|
if not plugins2cd_manager.check(plugin_name, cd_type_):
|
||||||
|
if msg:
|
||||||
|
await send_msg(msg, bot, event)
|
||||||
|
raise IgnoredException(f"{plugin_name} 正在cd中...")
|
||||||
|
else:
|
||||||
|
plugins2cd_manager.start_cd(plugin_name, cd_type_)
|
||||||
|
# Block
|
||||||
|
if plugins2block_manager.check_plugin_block_status(plugin_name):
|
||||||
|
plugin_block_data = plugins2block_manager.get_plugin_block_data(plugin_name)
|
||||||
|
check_type = plugin_block_data.check_type
|
||||||
|
limit_type = plugin_block_data.limit_type
|
||||||
|
msg = plugin_block_data.rst
|
||||||
|
if (
|
||||||
|
(isinstance(event, PrivateMessageEvent) and check_type == "private")
|
||||||
|
or (isinstance(event, GroupMessageEvent) and check_type == "group")
|
||||||
|
or check_type == "all"
|
||||||
|
):
|
||||||
|
block_type_ = event.user_id
|
||||||
|
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||||
|
block_type_ = event.group_id
|
||||||
|
if plugins2block_manager.check(block_type_, plugin_name):
|
||||||
|
if msg:
|
||||||
|
await send_msg(msg, bot, event)
|
||||||
|
raise IgnoredException(f"{event.user_id}正在调用{plugin_name}....")
|
||||||
|
else:
|
||||||
|
plugins2block_manager.set_true(block_type_, plugin_name)
|
||||||
|
# Count
|
||||||
|
if (
|
||||||
|
plugins2count_manager.check_plugin_count_status(plugin_name)
|
||||||
|
and event.user_id not in bot.config.superusers
|
||||||
|
):
|
||||||
|
plugin_count_data = plugins2count_manager.get_plugin_count_data(plugin_name)
|
||||||
|
limit_type = plugin_count_data.limit_type
|
||||||
|
msg = plugin_count_data.rst
|
||||||
|
count_type_ = event.user_id
|
||||||
|
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||||
|
count_type_ = event.group_id
|
||||||
|
if not plugins2count_manager.check(plugin_name, count_type_):
|
||||||
|
if msg:
|
||||||
|
await send_msg(msg, bot, event)
|
||||||
|
raise IgnoredException(f"{plugin_name} count次数限制...")
|
||||||
|
else:
|
||||||
|
plugins2count_manager.increase(plugin_name, count_type_)
|
||||||
|
|
||||||
|
async def auth_plugin(self, plugin_name: str, matcher: Matcher, bot: Bot, event: Event):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
插件状态
|
||||||
|
参数:
|
||||||
|
:param plugin_name: 模块名
|
||||||
|
:param matcher: matcher
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
if plugin_name in plugins2settings_manager.keys() and matcher.priority not in [
|
||||||
|
1,
|
||||||
|
999,
|
||||||
|
]:
|
||||||
|
# 戳一戳单独判断
|
||||||
|
if (
|
||||||
|
isinstance(event, GroupMessageEvent)
|
||||||
|
or isinstance(event, PokeNotifyEvent)
|
||||||
|
or matcher.plugin_name in other_limit_plugins
|
||||||
|
):
|
||||||
|
if status_message_manager.get(event.group_id) is None:
|
||||||
|
status_message_manager.delete(event.group_id)
|
||||||
|
if plugins2settings_manager[
|
||||||
|
plugin_name
|
||||||
|
].level > group_manager.get_group_level(event.group_id):
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
self._flmt_g.check(event.user_id)
|
||||||
|
and plugin_name not in ignore_rst_module
|
||||||
|
):
|
||||||
|
self._flmt_g.start_cd(event.user_id)
|
||||||
|
await bot.send_group_msg(
|
||||||
|
group_id=event.group_id, message="群权限不足..."
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.group_id)
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
raise IgnoredException("群权限不足")
|
||||||
|
# 插件状态
|
||||||
|
if not group_manager.get_plugin_status(plugin_name, event.group_id):
|
||||||
|
try:
|
||||||
|
if plugin_name not in ignore_rst_module and self._flmt_s.check(
|
||||||
|
event.group_id
|
||||||
|
):
|
||||||
|
self._flmt_s.start_cd(event.group_id)
|
||||||
|
await bot.send_group_msg(
|
||||||
|
group_id=event.group_id, message="该群未开启此功能.."
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.group_id)
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
raise IgnoredException("未开启此功能...")
|
||||||
|
# 管理员禁用
|
||||||
|
if not group_manager.get_plugin_status(
|
||||||
|
f"{plugin_name}:super", event.group_id
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
self._flmt_s.check(event.group_id)
|
||||||
|
and plugin_name not in ignore_rst_module
|
||||||
|
):
|
||||||
|
self._flmt_s.start_cd(event.group_id)
|
||||||
|
await bot.send_group_msg(
|
||||||
|
group_id=event.group_id, message="管理员禁用了此群该功能..."
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.group_id)
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
raise IgnoredException("管理员禁用了此群该功能...")
|
||||||
|
# 群聊禁用
|
||||||
|
if not plugins_manager.get_plugin_status(
|
||||||
|
plugin_name, block_type="group"
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
self._flmt_c.check(event.group_id)
|
||||||
|
and plugin_name not in ignore_rst_module
|
||||||
|
):
|
||||||
|
self._flmt_c.start_cd(event.group_id)
|
||||||
|
await bot.send_group_msg(
|
||||||
|
group_id=event.group_id, message="该功能在群聊中已被禁用..."
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.group_id)
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
raise IgnoredException("该插件在群聊中已被禁用...")
|
||||||
|
else:
|
||||||
|
# 私聊禁用
|
||||||
|
if not plugins_manager.get_plugin_status(
|
||||||
|
plugin_name, block_type="private"
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if self._flmt_c.check(event.user_id):
|
||||||
|
self._flmt_c.start_cd(event.user_id)
|
||||||
|
await bot.send_private_msg(
|
||||||
|
user_id=event.user_id, message="该功能在私聊中已被禁用..."
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.user_id)
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
raise IgnoredException("该插件在私聊中已被禁用...")
|
||||||
|
# 维护
|
||||||
|
if not plugins_manager.get_plugin_status(plugin_name, block_type="all"):
|
||||||
|
if isinstance(
|
||||||
|
event, GroupMessageEvent
|
||||||
|
) and group_manager.check_group_is_white(event.group_id):
|
||||||
|
raise ReturnException()
|
||||||
|
try:
|
||||||
|
if isinstance(event, GroupMessageEvent):
|
||||||
|
if (
|
||||||
|
self._flmt_c.check(event.group_id)
|
||||||
|
and plugin_name not in ignore_rst_module
|
||||||
|
):
|
||||||
|
self._flmt_c.start_cd(event.group_id)
|
||||||
|
await bot.send_group_msg(
|
||||||
|
group_id=event.group_id, message="此功能正在维护..."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await bot.send_private_msg(
|
||||||
|
user_id=event.user_id, message="此功能正在维护..."
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
if event.is_tome():
|
||||||
|
id_ = (
|
||||||
|
event.group_id
|
||||||
|
if isinstance(event, GroupMessageEvent)
|
||||||
|
else event.user_id
|
||||||
|
)
|
||||||
|
status_message_manager.add(id_)
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
raise IgnoredException("此功能正在维护...")
|
||||||
|
|
||||||
|
async def auth_admin(self, plugin_name: str, matcher: Matcher, bot: Bot, event: Event):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
管理员命令 个人权限
|
||||||
|
参数:
|
||||||
|
:param plugin_name: 模块名
|
||||||
|
:param matcher: matcher
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
if plugin_name in admin_manager.keys() and matcher.priority not in [1, 999]:
|
||||||
|
if isinstance(event, GroupMessageEvent):
|
||||||
|
# 个人权限
|
||||||
|
if (
|
||||||
|
not await LevelUser.check_level(
|
||||||
|
event.user_id,
|
||||||
|
event.group_id,
|
||||||
|
admin_manager.get_plugin_level(plugin_name),
|
||||||
|
)
|
||||||
|
and admin_manager.get_plugin_level(plugin_name) > 0
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if self._flmt.check(event.user_id):
|
||||||
|
self._flmt.start_cd(event.user_id)
|
||||||
|
await bot.send_group_msg(
|
||||||
|
group_id=event.group_id,
|
||||||
|
message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:"
|
||||||
|
f"{admin_manager.get_plugin_level(plugin_name)}",
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.group_id)
|
||||||
|
raise IgnoredException("权限不足")
|
||||||
|
else:
|
||||||
|
if not await LevelUser.check_level(
|
||||||
|
event.user_id, 0, admin_manager.get_plugin_level(plugin_name)
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
await bot.send_private_msg(
|
||||||
|
user_id=event.user_id,
|
||||||
|
message=f"你的权限不足喔,该功能需要的权限等级:{admin_manager.get_plugin_level(plugin_name)}",
|
||||||
|
)
|
||||||
|
except ActionFailed:
|
||||||
|
pass
|
||||||
|
set_block_limit_false(event, plugin_name)
|
||||||
|
if event.is_tome():
|
||||||
|
status_message_manager.add(event.user_id)
|
||||||
|
raise IgnoredException("权限不足")
|
||||||
|
|
||||||
|
def auth_group(self, plugin_name: str, bot: Bot, event: Event):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
群黑名单检测 群总开关检测
|
||||||
|
参数:
|
||||||
|
:param plugin_name: 模块名
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
if isinstance(event, GroupMessageEvent) or plugin_name in other_limit_plugins:
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
group_manager.get_group_level(event.group_id) < 0
|
||||||
|
and str(event.user_id) not in bot.config.superusers
|
||||||
|
):
|
||||||
|
raise IgnoredException("群黑名单")
|
||||||
|
if not group_manager.check_group_bot_status(event.group_id):
|
||||||
|
try:
|
||||||
|
if str(event.get_message()) != "醒来":
|
||||||
|
raise IgnoredException("功能总开关关闭状态")
|
||||||
|
except ValueError:
|
||||||
|
raise IgnoredException("功能总开关关闭状态")
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def auth_basic(self, plugin_name: str, bot: Bot, event: Event):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
检测是否满足超级用户权限,是否被ban等
|
||||||
|
参数:
|
||||||
|
:param plugin_name: 模块名
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
ban = await BanUser.is_ban(event.user_id)
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
not isinstance(event, MessageEvent)
|
||||||
|
and plugin_name not in other_limit_plugins
|
||||||
|
)
|
||||||
|
or await BanUser.is_ban(event.user_id)
|
||||||
|
and str(event.user_id) not in bot.config.superusers
|
||||||
|
) or (
|
||||||
|
str(event.user_id) in bot.config.superusers
|
||||||
|
and plugins2settings_manager.get_plugin_data(plugin_name)
|
||||||
|
and not plugins2settings_manager.get_plugin_data(
|
||||||
|
plugin_name
|
||||||
|
).limit_superuser
|
||||||
|
):
|
||||||
|
raise ReturnException()
|
||||||
|
_plugin = nonebot.plugin.get_plugin(plugin_name)
|
||||||
|
_module = _plugin.module
|
||||||
|
_plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
||||||
|
if (
|
||||||
|
"[superuser]" in _plugin_name.lower()
|
||||||
|
and str(event.user_id) in bot.config.superusers
|
||||||
|
):
|
||||||
|
raise ReturnException()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def auth_cost(self, plugin_name: str, bot: Bot, event: Event) -> int:
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
检测是否满足金币条件
|
||||||
|
参数:
|
||||||
|
:param plugin_name: 模块名
|
||||||
|
:param bot: bot
|
||||||
|
:param event: event
|
||||||
|
"""
|
||||||
|
cost_gold = 0
|
||||||
|
if isinstance(event, GroupMessageEvent) and (
|
||||||
|
psm := plugins2settings_manager.get_plugin_data(plugin_name)
|
||||||
|
):
|
||||||
|
if psm.cost_gold > 0:
|
||||||
|
if (
|
||||||
|
await BagUser.get_gold(event.user_id, event.group_id)
|
||||||
|
< psm.cost_gold
|
||||||
|
):
|
||||||
|
await send_msg(f"金币不足..该功能需要{psm.cost_gold}金币..", bot, event)
|
||||||
|
raise IgnoredException(f"{plugin_name} 金币限制...")
|
||||||
|
# 当插件不阻塞超级用户时,超级用户提前扣除金币
|
||||||
|
if (
|
||||||
|
str(event.user_id) in bot.config.superusers
|
||||||
|
and not psm.limit_superuser
|
||||||
|
):
|
||||||
|
await BagUser.spend_gold(
|
||||||
|
event.user_id, event.group_id, psm.cost_gold
|
||||||
|
)
|
||||||
|
await UserShopGoldLog.add_shop_log(
|
||||||
|
event.user_id, event.group_id, 2, plugin_name, psm.cost_gold, 1
|
||||||
|
)
|
||||||
|
cost_gold = psm.cost_gold
|
||||||
|
return cost_gold
|
||||||
|
|||||||
@ -1,395 +1,36 @@
|
|||||||
from nonebot.matcher import Matcher
|
|
||||||
from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException
|
|
||||||
from models.friend_user import FriendUser
|
|
||||||
from models.group_member_info import GroupInfoUser
|
|
||||||
from models.bag_user import BagUser
|
|
||||||
from models.user_shop_gold_log import UserShopGoldLog
|
|
||||||
from utils.manager import (
|
|
||||||
plugins2settings_manager,
|
|
||||||
admin_manager,
|
|
||||||
group_manager,
|
|
||||||
plugins_manager,
|
|
||||||
plugins2cd_manager,
|
|
||||||
plugins2block_manager,
|
|
||||||
plugins2count_manager,
|
|
||||||
)
|
|
||||||
from ._utils import (
|
|
||||||
set_block_limit_false,
|
|
||||||
status_message_manager,
|
|
||||||
ignore_rst_module,
|
|
||||||
other_limit_plugins,
|
|
||||||
)
|
|
||||||
from nonebot.typing import T_State
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
ActionFailed,
|
|
||||||
MessageEvent,
|
MessageEvent,
|
||||||
GroupMessageEvent,
|
|
||||||
PokeNotifyEvent,
|
|
||||||
PrivateMessageEvent,
|
|
||||||
Message,
|
|
||||||
Event,
|
Event,
|
||||||
)
|
)
|
||||||
from configs.config import Config
|
from nonebot.matcher import Matcher
|
||||||
from models.ban_user import BanUser
|
from nonebot.message import run_preprocessor, run_postprocessor
|
||||||
from utils.utils import FreqLimiter
|
from nonebot.typing import T_State
|
||||||
from utils.message_builder import at
|
|
||||||
from models.level_user import LevelUser
|
|
||||||
import nonebot
|
|
||||||
|
|
||||||
_flmt = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
from ._utils import (
|
||||||
_flmt_g = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
set_block_limit_false,
|
||||||
_flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
AuthChecker,
|
||||||
_flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
|
)
|
||||||
|
|
||||||
|
|
||||||
# 权限检测
|
# # 权限检测
|
||||||
@run_preprocessor
|
@run_preprocessor
|
||||||
async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
|
async def _(matcher: Matcher, bot: Bot, event: Event):
|
||||||
module = matcher.plugin_name
|
await AuthChecker().auth(matcher, bot, event)
|
||||||
plugins2info_dict = plugins2settings_manager.get_data()
|
|
||||||
# 功能的金币检测 #######################################
|
|
||||||
# 功能的金币检测 #######################################
|
|
||||||
# 功能的金币检测 #######################################
|
|
||||||
cost_gold = 0
|
|
||||||
if isinstance(
|
|
||||||
event, GroupMessageEvent
|
|
||||||
) and plugins2settings_manager.get_plugin_data(module).get("cost_gold"):
|
|
||||||
cost_gold = plugins2settings_manager.get_plugin_data(module).get("cost_gold")
|
|
||||||
if await BagUser.get_gold(event.user_id, event.group_id) < cost_gold:
|
|
||||||
await send_msg(f"金币不足..该功能需要{cost_gold}金币..", bot, event)
|
|
||||||
raise IgnoredException(f"{module} 金币限制...")
|
|
||||||
await UserShopGoldLog.add_shop_log(event.user_id, event.group_id, 2, matcher.plugin_name, cost_gold, 1)
|
|
||||||
# 当插件不阻塞超级用户时,超级用户提前扣除金币
|
|
||||||
if (
|
|
||||||
str(event.user_id) in bot.config.superusers
|
|
||||||
and not plugins2info_dict[module]["limit_superuser"]
|
|
||||||
):
|
|
||||||
await BagUser.spend_gold(event.user_id, event.group_id, cost_gold)
|
|
||||||
try:
|
|
||||||
if (
|
|
||||||
(not isinstance(event, MessageEvent) and module not in other_limit_plugins)
|
|
||||||
or await BanUser.is_ban(event.user_id)
|
|
||||||
and str(event.user_id) not in bot.config.superusers
|
|
||||||
) or (
|
|
||||||
str(event.user_id) in bot.config.superusers
|
|
||||||
and plugins2info_dict.get(module)
|
|
||||||
and not plugins2info_dict[module]["limit_superuser"]
|
|
||||||
):
|
|
||||||
return
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
# 超级用户命令
|
|
||||||
try:
|
|
||||||
_plugin = nonebot.plugin.get_plugin(module)
|
|
||||||
_module = _plugin.module
|
|
||||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
|
||||||
if (
|
|
||||||
"[superuser]" in plugin_name.lower()
|
|
||||||
and str(event.user_id) in bot.config.superusers
|
|
||||||
):
|
|
||||||
return
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
# 群黑名单检测 群总开关检测
|
|
||||||
if (
|
|
||||||
isinstance(event, GroupMessageEvent)
|
|
||||||
or matcher.plugin_name in other_limit_plugins
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
if (
|
|
||||||
group_manager.get_group_level(event.group_id) < 0
|
|
||||||
and str(event.user_id) not in bot.config.superusers
|
|
||||||
):
|
|
||||||
raise IgnoredException("群黑名单")
|
|
||||||
if not group_manager.check_group_bot_status(event.group_id):
|
|
||||||
try:
|
|
||||||
if str(event.get_message()) != "醒来":
|
|
||||||
raise IgnoredException("功能总开关关闭状态")
|
|
||||||
except ValueError:
|
|
||||||
raise IgnoredException("功能总开关关闭状态")
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
if module in admin_manager.keys() and matcher.priority not in [1, 999]:
|
|
||||||
if isinstance(event, GroupMessageEvent):
|
|
||||||
# 个人权限
|
|
||||||
if (
|
|
||||||
not await LevelUser.check_level(
|
|
||||||
event.user_id,
|
|
||||||
event.group_id,
|
|
||||||
admin_manager.get_plugin_level(module),
|
|
||||||
)
|
|
||||||
and admin_manager.get_plugin_level(module) > 0
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
if _flmt.check(event.user_id):
|
|
||||||
_flmt.start_cd(event.user_id)
|
|
||||||
await bot.send_group_msg(
|
|
||||||
group_id=event.group_id,
|
|
||||||
message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:"
|
|
||||||
f"{admin_manager.get_plugin_level(module)}",
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.group_id)
|
|
||||||
raise IgnoredException("权限不足")
|
|
||||||
else:
|
|
||||||
if not await LevelUser.check_level(
|
|
||||||
event.user_id, 0, admin_manager.get_plugin_level(module)
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
await bot.send_private_msg(
|
|
||||||
user_id=event.user_id,
|
|
||||||
message=f"你的权限不足喔,该功能需要的权限等级:{admin_manager.get_plugin_level(module)}",
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.user_id)
|
|
||||||
raise IgnoredException("权限不足")
|
|
||||||
if module in plugins2info_dict.keys() and matcher.priority not in [1, 999]:
|
|
||||||
# 戳一戳单独判断
|
|
||||||
if (
|
|
||||||
isinstance(event, GroupMessageEvent)
|
|
||||||
or isinstance(event, PokeNotifyEvent)
|
|
||||||
or matcher.plugin_name in other_limit_plugins
|
|
||||||
):
|
|
||||||
if status_message_manager.get(event.group_id) is None:
|
|
||||||
status_message_manager.delete(event.group_id)
|
|
||||||
if plugins2info_dict[module]["level"] > group_manager.get_group_level(
|
|
||||||
event.group_id
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
if _flmt_g.check(event.user_id) and module not in ignore_rst_module:
|
|
||||||
_flmt_g.start_cd(event.user_id)
|
|
||||||
await bot.send_group_msg(
|
|
||||||
group_id=event.group_id, message="群权限不足..."
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.group_id)
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
raise IgnoredException("群权限不足")
|
|
||||||
# 插件状态
|
|
||||||
if not group_manager.get_plugin_status(module, event.group_id):
|
|
||||||
try:
|
|
||||||
if module not in ignore_rst_module and _flmt_s.check(
|
|
||||||
event.group_id
|
|
||||||
):
|
|
||||||
_flmt_s.start_cd(event.group_id)
|
|
||||||
await bot.send_group_msg(
|
|
||||||
group_id=event.group_id, message="该群未开启此功能.."
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.group_id)
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
raise IgnoredException("未开启此功能...")
|
|
||||||
# 管理员禁用
|
|
||||||
if not group_manager.get_plugin_status(f"{module}:super", event.group_id):
|
|
||||||
try:
|
|
||||||
if (
|
|
||||||
_flmt_s.check(event.group_id)
|
|
||||||
and module not in ignore_rst_module
|
|
||||||
):
|
|
||||||
_flmt_s.start_cd(event.group_id)
|
|
||||||
await bot.send_group_msg(
|
|
||||||
group_id=event.group_id, message="管理员禁用了此群该功能..."
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.group_id)
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
raise IgnoredException("管理员禁用了此群该功能...")
|
|
||||||
# 群聊禁用
|
|
||||||
if not plugins_manager.get_plugin_status(module, block_type="group"):
|
|
||||||
try:
|
|
||||||
if (
|
|
||||||
_flmt_c.check(event.group_id)
|
|
||||||
and module not in ignore_rst_module
|
|
||||||
):
|
|
||||||
_flmt_c.start_cd(event.group_id)
|
|
||||||
await bot.send_group_msg(
|
|
||||||
group_id=event.group_id, message="该功能在群聊中已被禁用..."
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.group_id)
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
raise IgnoredException("该插件在群聊中已被禁用...")
|
|
||||||
else:
|
|
||||||
# 私聊禁用
|
|
||||||
if not plugins_manager.get_plugin_status(module, block_type="private"):
|
|
||||||
try:
|
|
||||||
if _flmt_c.check(event.user_id):
|
|
||||||
_flmt_c.start_cd(event.user_id)
|
|
||||||
await bot.send_private_msg(
|
|
||||||
user_id=event.user_id, message="该功能在私聊中已被禁用..."
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
if event.is_tome():
|
|
||||||
status_message_manager.add(event.user_id)
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
raise IgnoredException("该插件在私聊中已被禁用...")
|
|
||||||
# 维护
|
|
||||||
if not plugins_manager.get_plugin_status(module, block_type="all"):
|
|
||||||
if isinstance(
|
|
||||||
event, GroupMessageEvent
|
|
||||||
) and group_manager.check_group_is_white(event.group_id):
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
if isinstance(event, GroupMessageEvent):
|
|
||||||
if (
|
|
||||||
_flmt_c.check(event.group_id)
|
|
||||||
and module not in ignore_rst_module
|
|
||||||
):
|
|
||||||
_flmt_c.start_cd(event.group_id)
|
|
||||||
await bot.send_group_msg(
|
|
||||||
group_id=event.group_id, message="此功能正在维护..."
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await bot.send_private_msg(
|
|
||||||
user_id=event.user_id, message="此功能正在维护..."
|
|
||||||
)
|
|
||||||
except ActionFailed:
|
|
||||||
pass
|
|
||||||
if event.is_tome():
|
|
||||||
id_ = (
|
|
||||||
event.group_id
|
|
||||||
if isinstance(event, GroupMessageEvent)
|
|
||||||
else event.user_id
|
|
||||||
)
|
|
||||||
status_message_manager.add(id_)
|
|
||||||
set_block_limit_false(event, module)
|
|
||||||
raise IgnoredException("此功能正在维护...")
|
|
||||||
|
|
||||||
# 以下为限制检测 #######################################################
|
|
||||||
# 以下为限制检测 #######################################################
|
|
||||||
# 以下为限制检测 #######################################################
|
|
||||||
# 以下为限制检测 #######################################################
|
|
||||||
# 以下为限制检测 #######################################################
|
|
||||||
# 以下为限制检测 #######################################################
|
|
||||||
# Cd
|
|
||||||
if plugins2cd_manager.check_plugin_cd_status(module):
|
|
||||||
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
|
|
||||||
check_type = plugin_cd_data["check_type"]
|
|
||||||
limit_type = plugin_cd_data["limit_type"]
|
|
||||||
rst = plugin_cd_data["rst"]
|
|
||||||
if (
|
|
||||||
(isinstance(event, PrivateMessageEvent) and check_type == "private")
|
|
||||||
or (isinstance(event, GroupMessageEvent) and check_type == "group")
|
|
||||||
or plugins2cd_manager.get_plugin_data(module).get("check_type") == "all"
|
|
||||||
):
|
|
||||||
cd_type_ = event.user_id
|
|
||||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
|
||||||
cd_type_ = event.group_id
|
|
||||||
if not plugins2cd_manager.check(module, cd_type_):
|
|
||||||
if rst:
|
|
||||||
rst = await init_rst(rst, event)
|
|
||||||
await send_msg(rst, bot, event)
|
|
||||||
raise IgnoredException(f"{module} 正在cd中...")
|
|
||||||
else:
|
|
||||||
plugins2cd_manager.start_cd(module, cd_type_)
|
|
||||||
# Block
|
|
||||||
if plugins2block_manager.check_plugin_block_status(module):
|
|
||||||
plugin_block_data = plugins2block_manager.get_plugin_block_data(module)
|
|
||||||
check_type = plugin_block_data["check_type"]
|
|
||||||
limit_type = plugin_block_data["limit_type"]
|
|
||||||
rst = plugin_block_data["rst"]
|
|
||||||
if (
|
|
||||||
(isinstance(event, PrivateMessageEvent) and check_type == "private")
|
|
||||||
or (isinstance(event, GroupMessageEvent) and check_type == "group")
|
|
||||||
or check_type == "all"
|
|
||||||
):
|
|
||||||
block_type_ = event.user_id
|
|
||||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
|
||||||
block_type_ = event.group_id
|
|
||||||
if plugins2block_manager.check(block_type_, module):
|
|
||||||
if rst:
|
|
||||||
rst = await init_rst(rst, event)
|
|
||||||
await send_msg(rst, bot, event)
|
|
||||||
raise IgnoredException(f"{event.user_id}正在调用{module}....")
|
|
||||||
else:
|
|
||||||
plugins2block_manager.set_true(block_type_, module)
|
|
||||||
# Count
|
|
||||||
if (
|
|
||||||
plugins2count_manager.check_plugin_count_status(module)
|
|
||||||
and event.user_id not in bot.config.superusers
|
|
||||||
):
|
|
||||||
plugin_count_data = plugins2count_manager.get_plugin_count_data(module)
|
|
||||||
limit_type = plugin_count_data["limit_type"]
|
|
||||||
rst = plugin_count_data["rst"]
|
|
||||||
count_type_ = event.user_id
|
|
||||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
|
||||||
count_type_ = event.group_id
|
|
||||||
if not plugins2count_manager.check(module, count_type_):
|
|
||||||
if rst:
|
|
||||||
rst = await init_rst(rst, event)
|
|
||||||
await send_msg(rst, bot, event)
|
|
||||||
raise IgnoredException(f"{module} count次数限制...")
|
|
||||||
else:
|
|
||||||
plugins2count_manager.increase(module, count_type_)
|
|
||||||
# 功能花费的金币 #######################################
|
|
||||||
# 功能花费的金币 #######################################
|
|
||||||
if cost_gold:
|
|
||||||
await BagUser.spend_gold(event.user_id, event.group_id, cost_gold)
|
|
||||||
|
|
||||||
|
|
||||||
async def send_msg(rst: str, bot: Bot, event: MessageEvent):
|
|
||||||
"""
|
|
||||||
发送信息
|
|
||||||
:param rst: pass
|
|
||||||
:param bot: pass
|
|
||||||
:param event: pass
|
|
||||||
"""
|
|
||||||
rst = await init_rst(rst, event)
|
|
||||||
try:
|
|
||||||
if isinstance(event, GroupMessageEvent):
|
|
||||||
status_message_manager.add(event.group_id)
|
|
||||||
await bot.send_group_msg(group_id=event.group_id, message=Message(rst))
|
|
||||||
else:
|
|
||||||
status_message_manager.add(event.user_id)
|
|
||||||
await bot.send_private_msg(user_id=event.user_id, message=Message(rst))
|
|
||||||
except ActionFailed:
|
|
||||||
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.plugin_name != "poke":
|
if not isinstance(event, MessageEvent) and matcher.plugin_name != "poke":
|
||||||
return
|
return
|
||||||
module = matcher.plugin_name
|
module = matcher.plugin_name
|
||||||
set_block_limit_false(event, module)
|
set_block_limit_false(event, module)
|
||||||
|
|
||||||
|
|
||||||
async def init_rst(rst: str, event: MessageEvent):
|
|
||||||
if "[uname]" in rst:
|
|
||||||
uname = event.sender.card or event.sender.nickname
|
|
||||||
rst = rst.replace("[uname]", uname)
|
|
||||||
if "[nickname]" in rst:
|
|
||||||
if isinstance(event, GroupMessageEvent):
|
|
||||||
nickname = await GroupInfoUser.get_group_member_nickname(
|
|
||||||
event.user_id, event.group_id
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
nickname = await FriendUser.get_friend_nickname(event.user_id)
|
|
||||||
rst = rst.replace("[nickname]", nickname)
|
|
||||||
if "[at]" in rst and isinstance(event, GroupMessageEvent):
|
|
||||||
rst = rst.replace("[at]", str(at(event.user_id)))
|
|
||||||
return rst
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ async def _(bot: Bot, api: str, data: Dict[str, Any]):
|
|||||||
group_id = data["group_id"]
|
group_id = data["group_id"]
|
||||||
if group_manager.get_group_level(
|
if group_manager.get_group_level(
|
||||||
group_id
|
group_id
|
||||||
) < 0 or not await group_manager.check_group_task_status(group_id, task):
|
) < 0 or not group_manager.check_group_task_status(group_id, task):
|
||||||
raise MockApiException(f"被动技能 {task} 处于关闭状态...")
|
raise MockApiException(f"被动技能 {task} 处于关闭状态...")
|
||||||
else:
|
else:
|
||||||
msg = str(data["message"]).strip()
|
msg = str(data["message"]).strip()
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from configs.path_config import DATA_PATH
|
||||||
from .init_group_manager import init_group_manager, group_manager
|
from .init_group_manager import init_group_manager, group_manager
|
||||||
from .init_plugins_config import init_plugins_config
|
from .init_plugins_config import init_plugins_config
|
||||||
from .init_plugins_data import init_plugins_data, plugins_manager
|
from .init_plugins_data import init_plugins_data, plugins_manager
|
||||||
@ -12,7 +13,6 @@ from .init_plugins_limit import (
|
|||||||
from .init import init
|
from .init import init
|
||||||
from .check_plugin_status import check_plugin_status
|
from .check_plugin_status import check_plugin_status
|
||||||
from nonebot.adapters.onebot.v11 import Bot
|
from nonebot.adapters.onebot.v11 import Bot
|
||||||
from configs.path_config import DATA_PATH
|
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from nonebot import Driver
|
from nonebot import Driver
|
||||||
import nonebot
|
import nonebot
|
||||||
@ -31,23 +31,21 @@ async def _():
|
|||||||
"""
|
"""
|
||||||
初始化数据
|
初始化数据
|
||||||
"""
|
"""
|
||||||
_flag = False
|
|
||||||
config_file = DATA_PATH / "configs" / "plugins2config.yaml"
|
config_file = DATA_PATH / "configs" / "plugins2config.yaml"
|
||||||
if not config_file.exists():
|
_flag = not config_file.exists()
|
||||||
_flag = True
|
|
||||||
init()
|
init()
|
||||||
init_plugins_settings(DATA_PATH)
|
init_plugins_settings()
|
||||||
init_plugins_cd_limit(DATA_PATH)
|
init_plugins_cd_limit()
|
||||||
init_plugins_block_limit(DATA_PATH)
|
init_plugins_block_limit()
|
||||||
init_plugins_count_limit(DATA_PATH)
|
init_plugins_count_limit()
|
||||||
init_plugins_data(DATA_PATH)
|
init_plugins_data()
|
||||||
init_plugins_config(DATA_PATH)
|
init_plugins_config()
|
||||||
init_plugins_resources()
|
init_plugins_resources()
|
||||||
init_none_plugin_count_manager()
|
init_none_plugin_count_manager()
|
||||||
x = group_manager.get_super_old_data()
|
# x = group_manager.get_super_old_data()
|
||||||
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:
|
if _flag:
|
||||||
raise Exception("首次运行,已在configs目录下生成配置文件config.yaml,修改后重启即可...")
|
raise Exception("首次运行,已在configs目录下生成配置文件config.yaml,修改后重启即可...")
|
||||||
logger.info("初始化数据完成...")
|
logger.info("初始化数据完成...")
|
||||||
@ -55,5 +53,5 @@ async def _():
|
|||||||
|
|
||||||
@driver.on_bot_connect
|
@driver.on_bot_connect
|
||||||
async def _(bot: Bot):
|
async def _(bot: Bot):
|
||||||
await init_group_manager()
|
# await init_group_manager()
|
||||||
await check_plugin_status(bot)
|
await check_plugin_status(bot)
|
||||||
|
|||||||
@ -6,13 +6,13 @@ async def check_plugin_status(bot: Bot):
|
|||||||
"""
|
"""
|
||||||
遍历查看插件加载情况
|
遍历查看插件加载情况
|
||||||
"""
|
"""
|
||||||
rst = ""
|
msg = ""
|
||||||
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 not data.error:
|
||||||
rst += f'{plugin}:{data["plugin_name"]}\n'
|
msg += f'{plugin}:{data.plugin_name}\n'
|
||||||
if rst:
|
if msg and bot.config.superusers:
|
||||||
rst = "以下插件加载失败..\n" + rst
|
msg = "以下插件加载失败..\n" + msg
|
||||||
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=msg.strip()
|
||||||
)
|
)
|
||||||
|
|||||||
@ -19,36 +19,44 @@ def init_none_plugin_count_manager():
|
|||||||
"""
|
"""
|
||||||
清除已删除插件数据
|
清除已删除插件数据
|
||||||
"""
|
"""
|
||||||
modules = [x.plugin_name for x in get_matchers()]
|
modules = [x.plugin_name for x in get_matchers(True)]
|
||||||
plugins_manager_list = list(plugins_manager.keys())
|
plugins_manager_list = list(plugins_manager.keys())
|
||||||
for module in plugins_manager_list:
|
for module in plugins_manager_list:
|
||||||
if module not in modules or none_plugin_count_manager.check(module):
|
try:
|
||||||
try:
|
if module not in modules or none_plugin_count_manager.check(module):
|
||||||
plugin_name = plugins_manager.get(module)["plugin_name"]
|
|
||||||
except (AttributeError, KeyError):
|
|
||||||
plugin_name = ""
|
|
||||||
if none_plugin_count_manager.check(module):
|
|
||||||
try:
|
try:
|
||||||
plugins2settings_manager.delete(module)
|
plugin_name = plugins_manager.get(module).plugin_name
|
||||||
plugins2settings_manager.save()
|
except (AttributeError, KeyError):
|
||||||
plugins2count_manager.delete(module)
|
plugin_name = ""
|
||||||
plugins2count_manager.save()
|
if none_plugin_count_manager.check(module):
|
||||||
plugins2cd_manager.delete(module)
|
try:
|
||||||
plugins2cd_manager.save()
|
plugins2settings_manager.delete(module)
|
||||||
plugins2block_manager.delete(module)
|
plugins2count_manager.delete(module)
|
||||||
plugins2block_manager.save()
|
plugins2cd_manager.delete(module)
|
||||||
plugins_manager.delete(module)
|
plugins2block_manager.delete(module)
|
||||||
plugins_manager.save()
|
plugins_manager.delete(module)
|
||||||
# resources_manager.remove_resource(module)
|
plugins_manager.save()
|
||||||
none_plugin_count_manager.delete(module)
|
# resources_manager.remove_resource(module)
|
||||||
logger.info(f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据...")
|
none_plugin_count_manager.delete(module)
|
||||||
except Exception as e:
|
logger.info(f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据...")
|
||||||
logger.exception(
|
except Exception as e:
|
||||||
f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据失败...{type(e)}:{e}")
|
logger.exception(
|
||||||
|
f"{module}:{plugin_name} 插件疑似已删除,清除对应插件数据失败...{type(e)}:{e}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
none_plugin_count_manager.add_count(module)
|
||||||
|
logger.info(
|
||||||
|
f"{module}:{plugin_name} 插件疑似已删除,"
|
||||||
|
f"加载{none_plugin_count_manager._max_count}次失败后将清除对应插件数据,"
|
||||||
|
f"当前次数:{none_plugin_count_manager._data[module]}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
none_plugin_count_manager.add_count(module)
|
none_plugin_count_manager.reset(module)
|
||||||
logger.info(
|
except Exception as e:
|
||||||
f"{module}:{plugin_name} 插件疑似已删除,加载{none_plugin_count_manager._max_count}次失败后将清除对应插件数据,当前次数:{none_plugin_count_manager._data[module]}")
|
logger.error(f"清除插件数据错误 {type(e)}:{e}")
|
||||||
else:
|
plugins2settings_manager.save()
|
||||||
none_plugin_count_manager.reset(module)
|
plugins2count_manager.save()
|
||||||
|
plugins2cd_manager.save()
|
||||||
|
plugins2block_manager.save()
|
||||||
|
plugins_manager.save()
|
||||||
none_plugin_count_manager.save()
|
none_plugin_count_manager.save()
|
||||||
|
|||||||
@ -8,40 +8,32 @@ from services.log import logger
|
|||||||
from utils.text_utils import prompt2cn
|
from utils.text_utils import prompt2cn
|
||||||
from utils.utils import get_matchers
|
from utils.utils import get_matchers
|
||||||
from utils.utils import scheduler
|
from utils.utils import scheduler
|
||||||
|
from configs.path_config import DATA_PATH
|
||||||
from ruamel import yaml
|
from ruamel import yaml
|
||||||
|
|
||||||
|
|
||||||
_yaml = YAML(typ="safe")
|
_yaml = YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
def init_plugins_config(data_path):
|
def init_plugins_config():
|
||||||
"""
|
"""
|
||||||
初始化插件数据配置
|
初始化插件数据配置
|
||||||
"""
|
"""
|
||||||
plugins2config_file = data_path / "configs" / "plugins2config.yaml"
|
plugins2config_file = DATA_PATH / "configs" / "plugins2config.yaml"
|
||||||
plugins2config_file.parent.mkdir(parents=True, exist_ok=True)
|
plugins2config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
_data = {}
|
_data = {}
|
||||||
if plugins2config_file.exists():
|
if plugins2config_file.exists():
|
||||||
_data = _yaml.load(open(plugins2config_file, "r", encoding="utf8"))
|
_data = _yaml.load(open(plugins2config_file, "r", encoding="utf8"))
|
||||||
_matchers = get_matchers(True)
|
|
||||||
# 优先使用 metadata 数据
|
# 优先使用 metadata 数据
|
||||||
for matcher in _matchers:
|
for matcher in [matcher for matcher in get_matchers(True) if matcher.plugin and matcher.plugin.module]:
|
||||||
_plugin = matcher.plugin
|
_plugin = matcher.plugin
|
||||||
if not _plugin:
|
|
||||||
continue
|
|
||||||
metadata = _plugin.metadata
|
metadata = _plugin.metadata
|
||||||
try:
|
_module = _plugin.module
|
||||||
_module = _plugin.module
|
|
||||||
except AttributeError:
|
|
||||||
continue
|
|
||||||
plugin_version = None
|
plugin_version = None
|
||||||
if metadata:
|
if metadata:
|
||||||
plugin_version = metadata.extra.get("version")
|
plugin_version = metadata.extra.get("version")
|
||||||
if not plugin_version:
|
if not plugin_version and hasattr(_module, "__plugin_version__"):
|
||||||
try:
|
plugin_version = _module.__getattribute__("__plugin_version__")
|
||||||
plugin_version = _module.__getattribute__("__plugin_version__")
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
if metadata and metadata.config:
|
if metadata and metadata.config:
|
||||||
plugin_configs = {}
|
plugin_configs = {}
|
||||||
for key, value in metadata.config.__fields__.items():
|
for key, value in metadata.config.__fields__.items():
|
||||||
@ -61,7 +53,7 @@ def init_plugins_config(data_path):
|
|||||||
_data.get(matcher.plugin_name)
|
_data.get(matcher.plugin_name)
|
||||||
and _data[matcher.plugin_name].keys() != plugin_configs.keys()
|
and _data[matcher.plugin_name].keys() != plugin_configs.keys()
|
||||||
)
|
)
|
||||||
or plugin_version > plugins_manager.get(matcher.plugin_name)["version"]
|
or plugin_version > plugins_manager.get(matcher.plugin_name).version
|
||||||
or matcher.plugin_name not in _data.keys()
|
or matcher.plugin_name not in _data.keys()
|
||||||
):
|
):
|
||||||
for key in plugin_configs:
|
for key in plugin_configs:
|
||||||
@ -94,16 +86,16 @@ def init_plugins_config(data_path):
|
|||||||
_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():
|
||||||
try:
|
# try:
|
||||||
admin_manager.set_admin_level(k, v)
|
admin_manager.set_admin_level(k, v)
|
||||||
except KeyError as e:
|
# except KeyError as e:
|
||||||
raise KeyError(f"{e} ****** 请检查是否有插件加载失败 ******")
|
# raise KeyError(f"{e} ****** 请检查是否有插件加载失败 ******")
|
||||||
# 存完插件基本设置
|
# 存完插件基本设置
|
||||||
with open(plugins2config_file, "w", encoding="utf8") as wf:
|
with open(plugins2config_file, "w", encoding="utf8") as wf:
|
||||||
round_trip_dump(
|
round_trip_dump(
|
||||||
@ -181,7 +173,7 @@ def _replace_config():
|
|||||||
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 = (
|
||||||
|
|||||||
@ -3,6 +3,7 @@ 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
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
|
from configs.path_config import DATA_PATH
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ujson as json
|
import ujson as json
|
||||||
@ -13,17 +14,13 @@ except ModuleNotFoundError:
|
|||||||
_yaml = YAML(typ="safe")
|
_yaml = YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
def init_plugins_data(data_path):
|
def init_plugins_data():
|
||||||
"""
|
"""
|
||||||
初始化插件数据信息
|
初始化插件数据信息
|
||||||
"""
|
"""
|
||||||
plugin2data_file = data_path / "manager" / "plugin_manager.json"
|
plugin2data_file = DATA_PATH / "manager" / "plugin_manager.json"
|
||||||
plugin2data_file.parent.mkdir(parents=True, exist_ok=True)
|
plugin2data_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
_data = {}
|
for matcher in get_matchers(True):
|
||||||
if plugin2data_file.exists():
|
|
||||||
_data = json.load(open(plugin2data_file, "r", encoding="utf8"))
|
|
||||||
_matchers = get_matchers(True)
|
|
||||||
for matcher in _matchers:
|
|
||||||
_plugin = matcher.plugin
|
_plugin = matcher.plugin
|
||||||
if not _plugin:
|
if not _plugin:
|
||||||
continue
|
continue
|
||||||
@ -31,27 +28,19 @@ def init_plugins_data(data_path):
|
|||||||
try:
|
try:
|
||||||
_module = _plugin.module
|
_module = _plugin.module
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if matcher.plugin_name not in _data.keys():
|
if matcher.plugin_name not in plugins_manager.keys():
|
||||||
plugins_manager.add_plugin_data(
|
plugins_manager.add_plugin_data(
|
||||||
matcher.plugin_name, matcher.plugin_name, error=True
|
matcher.plugin_name, matcher.plugin_name, error=True
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
plugins_manager.set_module_data(matcher.plugin_name, "error", True)
|
plugins_manager[matcher.plugin_name].error = True
|
||||||
plugin_data = plugins_manager.get(matcher.plugin_name)
|
|
||||||
if plugin_data:
|
|
||||||
plugins_manager.set_module_data(
|
|
||||||
matcher.plugin_name, "version", plugin_data.get("version")
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
plugin_version = None
|
plugin_version = None
|
||||||
if metadata:
|
if metadata:
|
||||||
plugin_version = metadata.extra.get("version")
|
plugin_version = metadata.extra.get("version")
|
||||||
if not plugin_version:
|
if not plugin_version and hasattr(_module, "__plugin_version__"):
|
||||||
try:
|
plugin_version = _module.__getattribute__("__plugin_version__")
|
||||||
plugin_version = _module.__getattribute__("__plugin_version__")
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
if metadata:
|
if metadata:
|
||||||
plugin_name = metadata.name
|
plugin_name = metadata.name
|
||||||
else:
|
else:
|
||||||
@ -62,12 +51,10 @@ def init_plugins_data(data_path):
|
|||||||
plugin_author = None
|
plugin_author = None
|
||||||
if metadata:
|
if metadata:
|
||||||
plugin_author = metadata.extra.get('author')
|
plugin_author = metadata.extra.get('author')
|
||||||
try:
|
if not plugin_author and hasattr(_module, "__plugin_author__"):
|
||||||
plugin_author = _module.__getattribute__("__plugin_author__")
|
plugin_author = _module.__getattribute__("__plugin_author__")
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
if matcher.plugin_name in plugins_manager.keys():
|
if matcher.plugin_name in plugins_manager.keys():
|
||||||
plugins_manager.set_module_data(matcher.plugin_name, "error", False)
|
plugins_manager[matcher.plugin_name].error = False
|
||||||
if matcher.plugin_name not in plugins_manager.keys():
|
if matcher.plugin_name not in plugins_manager.keys():
|
||||||
plugins_manager.add_plugin_data(
|
plugins_manager.add_plugin_data(
|
||||||
matcher.plugin_name,
|
matcher.plugin_name,
|
||||||
@ -76,24 +63,21 @@ def init_plugins_data(data_path):
|
|||||||
version=plugin_version,
|
version=plugin_version,
|
||||||
)
|
)
|
||||||
# metadata不检测version
|
# metadata不检测version
|
||||||
elif isinstance(plugin_version, str) or plugins_manager[matcher.plugin_name]["version"] is None or (
|
elif isinstance(plugin_version, str) or plugins_manager[matcher.plugin_name].version is None or (
|
||||||
plugin_version is not None
|
plugin_version is not None
|
||||||
and plugin_version > float(plugins_manager[matcher.plugin_name]["version"])
|
and plugin_version > float(plugins_manager[matcher.plugin_name].version)
|
||||||
):
|
):
|
||||||
plugins_manager.set_module_data(
|
plugins_manager[matcher.plugin_name].plugin_name = plugin_name
|
||||||
matcher.plugin_name, "plugin_name", plugin_name
|
plugins_manager[matcher.plugin_name].author = plugin_author
|
||||||
)
|
plugins_manager[matcher.plugin_name].version = plugin_version
|
||||||
plugins_manager.set_module_data(matcher.plugin_name, "author", plugin_author)
|
# if matcher.plugin_name in _data.keys():
|
||||||
plugins_manager.set_module_data(
|
# plugins_manager[matcher.plugin_name].error = _data[matcher.plugin_name]["error"]
|
||||||
matcher.plugin_name, "version", plugin_version
|
# plugins_manager.set_module_data(
|
||||||
)
|
# matcher.plugin_name, "error", _data[matcher.plugin_name]["error"]
|
||||||
if matcher.plugin_name in _data.keys():
|
# )
|
||||||
plugins_manager.set_module_data(
|
# plugins_manager.set_module_data(
|
||||||
matcher.plugin_name, "error", _data[matcher.plugin_name]["error"]
|
# matcher.plugin_name, "plugin_name", _data[matcher.plugin_name]["plugin_name"]
|
||||||
)
|
# )
|
||||||
plugins_manager.set_module_data(
|
|
||||||
matcher.plugin_name, "plugin_name", _data[matcher.plugin_name]["plugin_name"]
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"插件数据 {matcher.plugin_name} 加载发生错误 {type(e)}:{e}")
|
logger.error(f"插件数据 {matcher.plugin_name} 加载发生错误 {type(e)}:{e}")
|
||||||
plugins_manager.save()
|
plugins_manager.save()
|
||||||
|
|||||||
@ -1,27 +1,21 @@
|
|||||||
from pathlib import Path
|
|
||||||
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 configs.path_config import DATA_PATH
|
||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
|
|
||||||
_yaml = YAML(typ="safe")
|
def init_plugins_cd_limit():
|
||||||
|
|
||||||
|
|
||||||
def init_plugins_cd_limit(data_path):
|
|
||||||
"""
|
"""
|
||||||
加载 cd 限制
|
加载 cd 限制
|
||||||
"""
|
"""
|
||||||
plugins2cd_file = data_path / "configs" / "plugins2cd.yaml"
|
plugins2cd_file = DATA_PATH / "configs" / "plugins2cd.yaml"
|
||||||
plugins2cd_file.parent.mkdir(exist_ok=True, parents=True)
|
plugins2cd_file.parent.mkdir(exist_ok=True, parents=True)
|
||||||
_data = {}
|
_data = {}
|
||||||
_matchers = get_matchers()
|
for matcher in get_matchers(True):
|
||||||
for matcher in _matchers:
|
|
||||||
if not plugins2cd_manager.get_plugin_cd_data(matcher.plugin_name):
|
if not plugins2cd_manager.get_plugin_cd_data(matcher.plugin_name):
|
||||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||||
try:
|
try:
|
||||||
@ -36,42 +30,19 @@ def init_plugins_cd_limit(data_path):
|
|||||||
plugins2cd_manager.add_cd_limit(
|
plugins2cd_manager.add_cd_limit(
|
||||||
"这是一个示例"
|
"这是一个示例"
|
||||||
)
|
)
|
||||||
_tmp_data = {"PluginCdLimit": plugins2cd_manager.get_data()}
|
plugins2cd_manager.save()
|
||||||
with open(plugins2cd_file, "w", encoding="utf8") as wf:
|
|
||||||
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
|
||||||
_data = round_trip_load(open(plugins2cd_file, encoding="utf8"))
|
|
||||||
_data["PluginCdLimit"].yaml_set_start_comment(
|
|
||||||
"""# 需要cd的功能
|
|
||||||
# 自定义的功能需要cd也可以在此配置
|
|
||||||
# key:模块名称
|
|
||||||
# cd:cd 时长(秒)
|
|
||||||
# status:此限制的开关状态
|
|
||||||
# check_type:'private'/'group'/'all',限制私聊/群聊/全部
|
|
||||||
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
|
||||||
# 示例:'user':用户N秒内触发1次,'group':群N秒内触发1次
|
|
||||||
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
|
|
||||||
# rst 为 "" 或 None 时则不回复
|
|
||||||
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
|
|
||||||
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
|
|
||||||
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
|
|
||||||
indent=2,
|
|
||||||
)
|
|
||||||
with open(plugins2cd_file, "w", encoding="utf8") as wf:
|
|
||||||
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():
|
||||||
"""
|
"""
|
||||||
加载阻塞限制
|
加载阻塞限制
|
||||||
"""
|
"""
|
||||||
plugins2block_file = data_path / "configs" / "plugins2block.yaml"
|
plugins2block_file = DATA_PATH / "configs" / "plugins2block.yaml"
|
||||||
plugins2block_file.parent.mkdir(exist_ok=True, parents=True)
|
plugins2block_file.parent.mkdir(exist_ok=True, parents=True)
|
||||||
_data = {}
|
for matcher in get_matchers(True):
|
||||||
_matchers = get_matchers()
|
|
||||||
for matcher in _matchers:
|
|
||||||
if not plugins2block_manager.get_plugin_block_data(matcher.plugin_name):
|
if not plugins2block_manager.get_plugin_block_data(matcher.plugin_name):
|
||||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
_plugin = matcher.plugin
|
||||||
try:
|
try:
|
||||||
_module = _plugin.module
|
_module = _plugin.module
|
||||||
plugin_block_limit = _module.__getattribute__("__plugin_block_limit__")
|
plugin_block_limit = _module.__getattribute__("__plugin_block_limit__")
|
||||||
@ -84,36 +55,15 @@ def init_plugins_block_limit(data_path):
|
|||||||
plugins2block_manager.add_block_limit(
|
plugins2block_manager.add_block_limit(
|
||||||
"这是一个示例"
|
"这是一个示例"
|
||||||
)
|
)
|
||||||
_tmp_data = {"PluginBlockLimit": plugins2block_manager.get_data()}
|
plugins2block_manager.save()
|
||||||
with open(plugins2block_file, "w", encoding="utf8") as wf:
|
|
||||||
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
|
||||||
_data = round_trip_load(open(plugins2block_file, encoding="utf8"))
|
|
||||||
_data["PluginBlockLimit"].yaml_set_start_comment(
|
|
||||||
"""# 用户调用阻塞
|
|
||||||
# 即 当用户调用此功能还未结束时
|
|
||||||
# 用发送消息阻止用户重复调用此命令直到该命令结束
|
|
||||||
# key:模块名称
|
|
||||||
# status:此限制的开关状态
|
|
||||||
# check_type:'private'/'group'/'all',限制私聊/群聊/全部
|
|
||||||
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
|
||||||
# 示例:'user':阻塞用户,'group':阻塞群聊
|
|
||||||
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
|
|
||||||
# rst 为 "" 或 None 时则不回复
|
|
||||||
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
|
|
||||||
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
|
|
||||||
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
|
|
||||||
indent=2,
|
|
||||||
)
|
|
||||||
with open(plugins2block_file, "w", encoding="utf8") as wf:
|
|
||||||
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():
|
||||||
"""
|
"""
|
||||||
加载次数限制
|
加载次数限制
|
||||||
"""
|
"""
|
||||||
plugins2count_file = data_path / "configs" / "plugins2count.yaml"
|
plugins2count_file = DATA_PATH / "configs" / "plugins2count.yaml"
|
||||||
plugins2count_file.parent.mkdir(exist_ok=True, parents=True)
|
plugins2count_file.parent.mkdir(exist_ok=True, parents=True)
|
||||||
_data = {}
|
_data = {}
|
||||||
_matchers = get_matchers()
|
_matchers = get_matchers()
|
||||||
@ -132,26 +82,5 @@ def init_plugins_count_limit(data_path):
|
|||||||
plugins2count_manager.add_count_limit(
|
plugins2count_manager.add_count_limit(
|
||||||
"这是一个示例"
|
"这是一个示例"
|
||||||
)
|
)
|
||||||
_tmp_data = {"PluginCountLimit": plugins2count_manager.get_data()}
|
plugins2count_manager.save()
|
||||||
with open(plugins2count_file, "w", encoding="utf8") as wf:
|
|
||||||
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
|
||||||
_data = round_trip_load(open(plugins2count_file, encoding="utf8"))
|
|
||||||
_data["PluginCountLimit"].yaml_set_start_comment(
|
|
||||||
"""# 命令每日次数限制
|
|
||||||
# 即 用户/群聊 每日可调用命令的次数 [数据内存存储,重启将会重置]
|
|
||||||
# 每日调用直到 00:00 刷新
|
|
||||||
# key:模块名称
|
|
||||||
# max_count: 每日调用上限
|
|
||||||
# status:此限制的开关状态
|
|
||||||
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
|
||||||
# 示例:'user':用户上限,'group':群聊上限
|
|
||||||
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
|
|
||||||
# rst 为 "" 或 None 时则不回复
|
|
||||||
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
|
|
||||||
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
|
|
||||||
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
|
|
||||||
indent=2,
|
|
||||||
)
|
|
||||||
with open(plugins2count_file, "w", encoding="utf8") as wf:
|
|
||||||
round_trip_dump(_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
|
||||||
plugins2count_manager.reload_count_limit()
|
plugins2count_manager.reload_count_limit()
|
||||||
|
|||||||
@ -1,24 +1,14 @@
|
|||||||
from pathlib import Path
|
|
||||||
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
|
|
||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
|
|
||||||
_yaml = YAML(typ="safe")
|
def init_plugins_settings():
|
||||||
|
|
||||||
|
|
||||||
def init_plugins_settings(data_path: str):
|
|
||||||
"""
|
"""
|
||||||
初始化插件设置,从插件中获取 __zx_plugin_name__,__plugin_cmd__,__plugin_settings__
|
初始化插件设置,从插件中获取 __zx_plugin_name__,__plugin_cmd__,__plugin_settings__
|
||||||
"""
|
"""
|
||||||
plugins2settings_file = data_path / "configs" / "plugins2settings.yaml"
|
|
||||||
plugins2settings_file.parent.mkdir(exist_ok=True, parents=True)
|
|
||||||
_matchers = get_matchers(True)
|
|
||||||
_tmp_module = {}
|
_tmp_module = {}
|
||||||
_tmp = []
|
|
||||||
for x in plugins2settings_manager.keys():
|
for x in plugins2settings_manager.keys():
|
||||||
try:
|
try:
|
||||||
_plugin = nonebot.plugin.get_plugin(x)
|
_plugin = nonebot.plugin.get_plugin(x)
|
||||||
@ -33,12 +23,10 @@ def init_plugins_settings(data_path: str):
|
|||||||
except (KeyError, AttributeError) as e:
|
except (KeyError, AttributeError) as e:
|
||||||
logger.warning(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}")
|
logger.warning(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}")
|
||||||
_tmp_module[x] = ""
|
_tmp_module[x] = ""
|
||||||
for matcher in _matchers:
|
for matcher in [x for x in get_matchers(True) if x.plugin]:
|
||||||
try:
|
try:
|
||||||
if matcher.plugin_name not in plugins2settings_manager.keys():
|
if matcher.plugin_name not in plugins2settings_manager.keys():
|
||||||
_plugin = matcher.plugin
|
_plugin = matcher.plugin
|
||||||
if not _plugin:
|
|
||||||
continue
|
|
||||||
metadata = _plugin.metadata
|
metadata = _plugin.metadata
|
||||||
try:
|
try:
|
||||||
_module = _plugin.module
|
_module = _plugin.module
|
||||||
@ -46,22 +34,17 @@ def init_plugins_settings(data_path: str):
|
|||||||
logger.warning(f"插件 {matcher.plugin_name} 加载失败...,插件控制未加载.")
|
logger.warning(f"插件 {matcher.plugin_name} 加载失败...,插件控制未加载.")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if metadata:
|
plugin_name = metadata.name if metadata else _module.__getattribute__("__zx_plugin_name__")
|
||||||
plugin_name = metadata.name
|
# 管理员命令
|
||||||
else:
|
|
||||||
plugin_name = _module.__getattribute__("__zx_plugin_name__")
|
|
||||||
if "[admin]" in plugin_name.lower():
|
if "[admin]" in plugin_name.lower():
|
||||||
try:
|
level = 5
|
||||||
|
cmd = None
|
||||||
|
if hasattr(_module, "__plugin_settings__"):
|
||||||
admin_settings = _module.__getattribute__(
|
admin_settings = _module.__getattribute__(
|
||||||
"__plugin_settings__"
|
"__plugin_settings__"
|
||||||
)
|
)
|
||||||
level = admin_settings["admin_level"]
|
level = admin_settings.get("admin_level", 5)
|
||||||
cmd = admin_settings.get("cmd")
|
cmd = admin_settings.get("cmd")
|
||||||
except (AttributeError, KeyError):
|
|
||||||
level = 5
|
|
||||||
cmd = None
|
|
||||||
if level is None:
|
|
||||||
level = 5
|
|
||||||
admin_manager.add_admin_plugin_settings(
|
admin_manager.add_admin_plugin_settings(
|
||||||
matcher.plugin_name, cmd, level
|
matcher.plugin_name, cmd, level
|
||||||
)
|
)
|
||||||
@ -73,19 +56,18 @@ def init_plugins_settings(data_path: str):
|
|||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if matcher.plugin_name not in _tmp:
|
logger.warning(
|
||||||
logger.warning(
|
f"获取插件 {matcher.plugin_name} __zx_plugin_name__ 失败...,插件控制未加载."
|
||||||
f"获取插件 {matcher.plugin_name} __zx_plugin_name__ 失败...,插件控制未加载."
|
)
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
_tmp_module[matcher.plugin_name] = plugin_name
|
_tmp_module[matcher.plugin_name] = plugin_name
|
||||||
try:
|
if hasattr(_module, "__plugin_settings__"):
|
||||||
plugin_settings = _module.__getattribute__(
|
plugin_settings = _module.__getattribute__(
|
||||||
"__plugin_settings__"
|
"__plugin_settings__"
|
||||||
)
|
)
|
||||||
except AttributeError:
|
else:
|
||||||
plugin_settings = {"cmd": [matcher.plugin_name, plugin_name]}
|
plugin_settings = {"cmd": [matcher.plugin_name, plugin_name]}
|
||||||
if not plugin_settings.get("cost_gold"):
|
if plugin_settings.get("cost_gold") is None:
|
||||||
plugin_settings["cost_gold"] = 0
|
plugin_settings["cost_gold"] = 0
|
||||||
if (
|
if (
|
||||||
plugin_settings.get("cmd") is not None
|
plugin_settings.get("cmd") is not None
|
||||||
@ -100,12 +82,12 @@ def init_plugins_settings(data_path: str):
|
|||||||
plugin_type = tuple(
|
plugin_type = tuple(
|
||||||
plugins2settings_manager.get_plugin_data(
|
plugins2settings_manager.get_plugin_data(
|
||||||
matcher.plugin_name
|
matcher.plugin_name
|
||||||
)["plugin_type"]
|
).plugin_type
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
try:
|
if hasattr(_module, "__plugin_type__"):
|
||||||
plugin_type = _module.__getattribute__("__plugin_type__")
|
plugin_type = _module.__getattribute__("__plugin_type__")
|
||||||
except AttributeError:
|
else:
|
||||||
plugin_type = ("normal",)
|
plugin_type = ("normal",)
|
||||||
if plugin_settings and matcher.plugin_name:
|
if plugin_settings and matcher.plugin_name:
|
||||||
plugins2settings_manager.add_plugin_settings(
|
plugins2settings_manager.add_plugin_settings(
|
||||||
@ -115,26 +97,5 @@ def init_plugins_settings(data_path: str):
|
|||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f'{matcher.plugin_name} 初始化 plugin_settings 发生错误 {type(e)}:{e}')
|
logger.error(f'{matcher.plugin_name} 初始化 plugin_settings 发生错误 {type(e)}:{e}')
|
||||||
_tmp.append(matcher.plugin_name)
|
plugins2settings_manager.save()
|
||||||
_tmp_data = {"PluginSettings": plugins2settings_manager.get_data()}
|
|
||||||
with open(plugins2settings_file, "w", encoding="utf8") as wf:
|
|
||||||
yaml.dump(_tmp_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
|
||||||
_data = round_trip_load(open(plugins2settings_file, encoding="utf8"))
|
|
||||||
_data["PluginSettings"].yaml_set_start_comment(
|
|
||||||
"""# 模块与对应命令和对应群权限
|
|
||||||
# 用于生成帮助图片 和 开关功能
|
|
||||||
# key:模块名称
|
|
||||||
# level:需要的群等级
|
|
||||||
# default_status:加入群时功能的默认开关状态
|
|
||||||
# limit_superuser: 功能状态是否限制超级用户
|
|
||||||
# cmd: 关闭[cmd] 都会触发命令 关闭对应功能,cmd列表第一个词为统计的功能名称
|
|
||||||
# plugin_type: 帮助类别 示例:('原神相关',) 或 ('原神相关', 1),1代表帮助命令列向排列,否则为横向排列""",
|
|
||||||
indent=2,
|
|
||||||
)
|
|
||||||
for plugin in _data["PluginSettings"].keys():
|
|
||||||
_data["PluginSettings"][plugin].yaml_set_start_comment(
|
|
||||||
f"{plugin}:{_tmp_module[plugin]}", indent=2
|
|
||||||
)
|
|
||||||
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())} 个非限制插件.")
|
logger.info(f"已成功加载 {len(plugins2settings_manager.get_data())} 个非限制插件.")
|
||||||
|
|||||||
@ -122,8 +122,8 @@ async def _(event: GroupMessageEvent):
|
|||||||
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"
|
||||||
|
|||||||
@ -67,7 +67,7 @@ async def _():
|
|||||||
gl = [g["group_id"] for g in gl]
|
gl = [g["group_id"] for g in gl]
|
||||||
msg_list, code = await get_epic_free(bot, "Group")
|
msg_list, code = await get_epic_free(bot, "Group")
|
||||||
for g in gl:
|
for g in gl:
|
||||||
if await group_manager.check_group_task_status(g, "epic_free_game"):
|
if group_manager.check_group_task_status(g, "epic_free_game"):
|
||||||
try:
|
try:
|
||||||
if msg_list and code == 200:
|
if msg_list and code == 200:
|
||||||
await bot.send_group_forward_msg(group_id=g, messages=msg_list)
|
await bot.send_group_forward_msg(group_id=g, messages=msg_list)
|
||||||
|
|||||||
@ -71,5 +71,5 @@ async def _():
|
|||||||
if alc_img:
|
if alc_img:
|
||||||
mes = "[[_task|genshin_alc]]" + alc_img + "\n ※ 黄历数据来源于 genshin.pub"
|
mes = "[[_task|genshin_alc]]" + alc_img + "\n ※ 黄历数据来源于 genshin.pub"
|
||||||
for gid in gl:
|
for gid in gl:
|
||||||
if await group_manager.check_group_task_status(gid, "genshin_alc"):
|
if group_manager.check_group_task_status(gid, "genshin_alc"):
|
||||||
await bot.send_group_msg(group_id=int(gid), message="" + mes)
|
await bot.send_group_msg(group_id=int(gid), message="" + mes)
|
||||||
|
|||||||
@ -172,7 +172,7 @@ async def generate_statistics_img(
|
|||||||
data: dict, arg: str, name: str, plugin: str, day_index: int
|
data: dict, arg: str, name: str, plugin: str, day_index: int
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
plugin = plugins2settings_manager.get_plugin_data(plugin)['cmd'][0]
|
plugin = plugins2settings_manager.get_plugin_data(plugin).cmd[0]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError):
|
||||||
pass
|
pass
|
||||||
bar_graph = None
|
bar_graph = None
|
||||||
|
|||||||
@ -107,8 +107,8 @@ async def _(
|
|||||||
group_id = "total"
|
group_id = "total"
|
||||||
user_id = str(event.user_id)
|
user_id = str(event.user_id)
|
||||||
plugin_name = plugins2settings_manager.get_plugin_data(module)
|
plugin_name = plugins2settings_manager.get_plugin_data(module)
|
||||||
if plugin_name and plugin_name.get('cmd'):
|
if plugin_name and plugin_name.cmd:
|
||||||
plugin_name = plugin_name.get('cmd')[0]
|
plugin_name = plugin_name.cmd[0]
|
||||||
check_exists_key(group_id, user_id, plugin_name)
|
check_exists_key(group_id, user_id, plugin_name)
|
||||||
for data in [_prefix_count_dict, _prefix_user_count_dict]:
|
for data in [_prefix_count_dict, _prefix_user_count_dict]:
|
||||||
data["total_statistics"]["total"][plugin_name] += 1
|
data["total_statistics"]["total"][plugin_name] += 1
|
||||||
|
|||||||
@ -23,11 +23,11 @@ gConfig.add_plugin_config("web-ui", "password", None, name="web-ui", help_="前
|
|||||||
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||||
flag = False
|
flag = False
|
||||||
for module in plugins2settings_manager.keys():
|
for module in plugins2settings_manager.keys():
|
||||||
if isinstance(plugins2settings_manager.get_plugin_data(module).get("cmd"), str):
|
if isinstance(plugins2settings_manager.get_plugin_data(module).cmd, str):
|
||||||
plugins2settings_manager.set_module_data(
|
plugins2settings_manager.set_module_data(
|
||||||
module,
|
module,
|
||||||
"cmd",
|
"cmd",
|
||||||
plugins2settings_manager.get_plugin_data(module).get("cmd").split(","),
|
plugins2settings_manager.get_plugin_data(module).cmd.split(","),
|
||||||
False
|
False
|
||||||
)
|
)
|
||||||
flag = True
|
flag = True
|
||||||
|
|||||||
@ -61,8 +61,8 @@ def _(type_: Optional[str], user: User = Depends(token_to_user)) -> Result:
|
|||||||
)
|
)
|
||||||
data["plugin_manager"] = PluginManager(**x)
|
data["plugin_manager"] = PluginManager(**x)
|
||||||
if x := plugins2settings_manager.get(model):
|
if x := plugins2settings_manager.get(model):
|
||||||
if x.get("cmd") and isinstance(x.get("cmd"), list):
|
if x.cmd and isinstance(x.cmd, list):
|
||||||
x["cmd"] = ",".join(x["cmd"])
|
x.cmd = ",".join(x.cmd)
|
||||||
data["plugin_settings"] = PluginSettings(**x)
|
data["plugin_settings"] = PluginSettings(**x)
|
||||||
if x := plugins2cd_manager.get(model):
|
if x := plugins2cd_manager.get(model):
|
||||||
data["cd_limit"] = CdLimit(**x)
|
data["cd_limit"] = CdLimit(**x)
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
"poetry.lock",
|
"poetry.lock",
|
||||||
"pyproject.toml"
|
"pyproject.toml"
|
||||||
],
|
],
|
||||||
"add_file": [
|
"add_file": [],
|
||||||
"resources/image/shop_icon"
|
|
||||||
],
|
|
||||||
"delete_file": []
|
"delete_file": []
|
||||||
}
|
}
|
||||||
@ -14,6 +14,9 @@ from .requests_manager import RequestManager
|
|||||||
from configs.path_config import DATA_PATH
|
from configs.path_config import DATA_PATH
|
||||||
|
|
||||||
|
|
||||||
|
# 管理员命令管理器
|
||||||
|
admin_manager = AdminManager()
|
||||||
|
|
||||||
# 群功能开关 | 群被动技能 | 群权限 管理
|
# 群功能开关 | 群被动技能 | 群权限 管理
|
||||||
group_manager: Optional[GroupManager] = GroupManager(
|
group_manager: Optional[GroupManager] = GroupManager(
|
||||||
DATA_PATH / "manager" / "group_manager.json"
|
DATA_PATH / "manager" / "group_manager.json"
|
||||||
@ -62,5 +65,3 @@ requests_manager: Optional[RequestManager] = RequestManager(
|
|||||||
DATA_PATH / "manager" / "requests_manager.json"
|
DATA_PATH / "manager" / "requests_manager.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 管理员命令管理器
|
|
||||||
admin_manager = AdminManager()
|
|
||||||
|
|||||||
64
utils/manager/admin_manager.py
Executable file → Normal file
64
utils/manager/admin_manager.py
Executable file → Normal file
@ -1,5 +1,6 @@
|
|||||||
from .data_class import StaticData
|
from .models import AdminSetting
|
||||||
from typing import List, Optional
|
from utils.manager.data_class import StaticData
|
||||||
|
from typing import List, Optional, Dict
|
||||||
|
|
||||||
|
|
||||||
class AdminManager(StaticData):
|
class AdminManager(StaticData):
|
||||||
@ -9,60 +10,71 @@ class AdminManager(StaticData):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(None)
|
super().__init__(None)
|
||||||
|
self._data: Dict[str, AdminSetting] = {}
|
||||||
|
|
||||||
def add_admin_plugin_settings(self, plugin: str, cmd: List[str], level: int):
|
def add_admin_plugin_settings(self, plugin: str, cmd: List[str], level: int):
|
||||||
"""
|
"""
|
||||||
添加一个管理员命令
|
说明:
|
||||||
:param plugin: 模块
|
添加一个管理员命令
|
||||||
:param cmd: 别名
|
参数:
|
||||||
:param level: 等级
|
:param plugin: 模块
|
||||||
|
:param cmd: 别名
|
||||||
|
:param level: 等级
|
||||||
"""
|
"""
|
||||||
self._data[plugin] = {
|
self._data[plugin] = AdminSetting(level=level, cmd=cmd)
|
||||||
"level": level,
|
|
||||||
"cmd": cmd,
|
|
||||||
}
|
|
||||||
|
|
||||||
def set_admin_level(self, plugin: str, level: int):
|
def set_admin_level(self, plugin: str, level: int):
|
||||||
"""
|
"""
|
||||||
设置管理员命令等级
|
说明:
|
||||||
:param plugin: 模块名
|
设置管理员命令等级
|
||||||
:param level: 权限等级
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
|
:param level: 权限等级
|
||||||
"""
|
"""
|
||||||
self._data[plugin]["level"] = level
|
if plugin in self._data.keys():
|
||||||
|
self._data[plugin].level = level
|
||||||
|
|
||||||
def remove_admin_plugin_settings(self, plugin: str):
|
def remove_admin_plugin_settings(self, plugin: str):
|
||||||
"""
|
"""
|
||||||
删除一个管理员命令
|
说明:
|
||||||
:param plugin: 模块名
|
删除一个管理员命令
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if plugin in self._data.keys():
|
if plugin in self._data.keys():
|
||||||
del self._data[plugin]
|
del self._data[plugin]
|
||||||
|
|
||||||
def check(self, plugin: str, level: int) -> bool:
|
def check(self, plugin: str, level: int) -> bool:
|
||||||
"""
|
"""
|
||||||
检查是否满足权限
|
说明:
|
||||||
:param plugin: 模块名
|
检查是否满足权限
|
||||||
:param level: 权限等级
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
|
:param level: 权限等级
|
||||||
"""
|
"""
|
||||||
if plugin in self._data.keys():
|
if plugin in self._data.keys():
|
||||||
return level >= self._data[plugin]["level"]
|
return level >= self._data[plugin].level
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_plugin_level(self, plugin: str) -> int:
|
def get_plugin_level(self, plugin: str) -> int:
|
||||||
"""
|
"""
|
||||||
获取插件等级
|
说明:
|
||||||
:param plugin: 模块名
|
获取插件等级
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if plugin in self._data.keys():
|
if plugin in self._data.keys():
|
||||||
return self._data[plugin]["level"]
|
return self._data[plugin].level
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def get_plugin_module(self, cmd: str) -> Optional[str]:
|
def get_plugin_module(self, cmd: str) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
根据 cmd 获取功能 modules
|
说明:
|
||||||
:param cmd: 命令
|
根据 cmd 获取功能 modules
|
||||||
|
参数:
|
||||||
|
:param cmd: 命令
|
||||||
"""
|
"""
|
||||||
for key in self._data.keys():
|
for key in self._data.keys():
|
||||||
if self._data[key].get("cmd") and cmd in self._data[key]["cmd"]:
|
if self._data[key].cmd and cmd in self._data[key].cmd:
|
||||||
return key
|
return key
|
||||||
return None
|
return None
|
||||||
|
|||||||
0
utils/manager/configs_manager.py
Executable file → Normal file
0
utils/manager/configs_manager.py
Executable file → Normal file
@ -1,24 +1,29 @@
|
|||||||
from typing import Union, Optional
|
from typing import Union, Optional, TypeVar, Generic, Dict, NoReturn, Any
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
from ruamel.yaml import YAML
|
||||||
from ruamel import yaml
|
from ruamel import yaml
|
||||||
import ujson as json
|
import ujson as json
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from .models import *
|
||||||
|
|
||||||
_yaml = YAML(typ="safe")
|
_yaml = YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
class StaticData:
|
T = TypeVar("T", AdminSetting, BaseData, PluginBlock, PluginCd, PluginCount, PluginSetting, Plugin)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticData(Generic[T]):
|
||||||
"""
|
"""
|
||||||
静态数据共享类
|
静态数据共享类
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Optional[Path]):
|
def __init__(self, file: Optional[Path], load_file: bool = True):
|
||||||
self._data: dict = {}
|
self._data: dict = {}
|
||||||
if file:
|
if file:
|
||||||
file.parent.mkdir(exist_ok=True, parents=True)
|
file.parent.mkdir(exist_ok=True, parents=True)
|
||||||
self.file = file
|
self.file = file
|
||||||
if file.exists():
|
if file.exists() and load_file:
|
||||||
with open(file, "r", encoding="utf8") as f:
|
with open(file, "r", encoding="utf8") as f:
|
||||||
if file.name.endswith("json"):
|
if file.name.endswith("json"):
|
||||||
try:
|
try:
|
||||||
@ -29,30 +34,39 @@ class StaticData:
|
|||||||
elif file.name.endswith("yaml"):
|
elif file.name.endswith("yaml"):
|
||||||
self._data = _yaml.load(f)
|
self._data = _yaml.load(f)
|
||||||
|
|
||||||
def set(self, key, value):
|
def set(self, key, value) -> NoReturn:
|
||||||
self._data[key] = value
|
self._data[key] = value
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def set_module_data(self, module, key, value, auto_save: bool = True):
|
def set_module_data(self, module, key, value, auto_save: bool = True) -> NoReturn:
|
||||||
if module in self._data.keys():
|
if module in self._data.keys():
|
||||||
self._data[module][key] = value
|
self._data[module][key] = value
|
||||||
if auto_save:
|
if auto_save:
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key) -> T:
|
||||||
return self._data.get(key)
|
return self._data.get(key)
|
||||||
|
|
||||||
def keys(self):
|
def keys(self) -> List[str]:
|
||||||
return self._data.keys()
|
return self._data.keys()
|
||||||
|
|
||||||
def delete(self, key):
|
def delete(self, key) -> NoReturn:
|
||||||
if self._data.get(key) is not None:
|
if self._data.get(key) is not None:
|
||||||
del self._data[key]
|
del self._data[key]
|
||||||
|
|
||||||
def get_data(self) -> dict:
|
def get_data(self) -> Dict[str, T]:
|
||||||
return copy.deepcopy(self._data)
|
return copy.deepcopy(self._data)
|
||||||
|
|
||||||
def save(self, path: Union[str, Path] = None):
|
def dict(self) -> Dict[str, Any]:
|
||||||
|
temp = {}
|
||||||
|
for k, v in self._data.items():
|
||||||
|
try:
|
||||||
|
temp[k] = v.dict()
|
||||||
|
except AttributeError:
|
||||||
|
temp[k] = copy.deepcopy(v)
|
||||||
|
return temp
|
||||||
|
|
||||||
|
def save(self, path: Union[str, Path] = None) -> NoReturn:
|
||||||
path = path or self.file
|
path = path or self.file
|
||||||
if isinstance(path, str):
|
if isinstance(path, str):
|
||||||
path = Path(path)
|
path = Path(path)
|
||||||
@ -61,26 +75,26 @@ class StaticData:
|
|||||||
if path.name.endswith("yaml"):
|
if path.name.endswith("yaml"):
|
||||||
yaml.dump(self._data, f, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
yaml.dump(self._data, f, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
||||||
else:
|
else:
|
||||||
json.dump(self._data, f, ensure_ascii=False, indent=4)
|
json.dump(self.dict(), f, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
def reload(self):
|
def reload(self) -> NoReturn:
|
||||||
if self.file.exists():
|
if self.file.exists():
|
||||||
if self.file.name.endswith("json"):
|
if self.file.name.endswith("json"):
|
||||||
self._data: dict = json.load(open(self.file, "r", encoding="utf8"))
|
self._data: dict = json.load(open(self.file, "r", encoding="utf8"))
|
||||||
elif self.file.name.endswith("yaml"):
|
elif self.file.name.endswith("yaml"):
|
||||||
self._data: dict = _yaml.load(open(self.file, "r", encoding="utf8"))
|
self._data: dict = _yaml.load(open(self.file, "r", encoding="utf8"))
|
||||||
|
|
||||||
def is_exists(self):
|
def is_exists(self) -> bool:
|
||||||
return self.file.exists()
|
return self.file.exists()
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self) -> bool:
|
||||||
return bool(len(self._data))
|
return bool(len(self._data))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
return str(self._data)
|
return str(self._data)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value) -> NoReturn:
|
||||||
self._data[key] = value
|
self._data[key] = value
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key) -> T:
|
||||||
return self._data[key]
|
return self._data[key]
|
||||||
|
|||||||
314
utils/manager/group_manager.py
Executable file → Normal file
314
utils/manager/group_manager.py
Executable file → Normal file
@ -1,9 +1,11 @@
|
|||||||
from typing import Optional, List, Union, Dict
|
from typing import List, Union, Dict, Callable
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .data_class import StaticData
|
from .models import BaseData, BaseGroup
|
||||||
from utils.utils import get_matchers, get_bot
|
from utils.manager.data_class import StaticData
|
||||||
|
from utils.utils import get_matchers, is_number
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
import nonebot
|
import nonebot
|
||||||
|
import ujson as json
|
||||||
|
|
||||||
|
|
||||||
Config.add_plugin_config(
|
Config.add_plugin_config(
|
||||||
@ -15,39 +17,75 @@ Config.add_plugin_config(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def init_group(func: Callable):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
初始化群数据
|
||||||
|
参数:
|
||||||
|
:param func: func
|
||||||
|
"""
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
self = args[0]
|
||||||
|
group_id = list(filter(lambda x: is_number(x), args[1:]))[0]
|
||||||
|
if self and group_id and not self._data.group_manager.get(str(group_id)):
|
||||||
|
self._data.group_manager[str(group_id)] = BaseGroup()
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def init_task(func: Callable):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
初始化群被动
|
||||||
|
参数:
|
||||||
|
:param func: func
|
||||||
|
"""
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
self = args[0]
|
||||||
|
group_id = str(args[1])
|
||||||
|
task = args[2] if len(args) > 1 else None
|
||||||
|
if group_id and task and self._data.group_manager[group_id].group_task_status.get(task) is None:
|
||||||
|
for task in self._data.task:
|
||||||
|
if self._data.group_manager[group_id].group_task_status.get(task) is None:
|
||||||
|
self._data.group_manager[group_id].group_task_status[task] = Config.get_config('_task', f'DEFAULT_{task}', default=True)
|
||||||
|
for task in list(self._data.group_manager[group_id].group_task_status):
|
||||||
|
if task not in self._data.task:
|
||||||
|
del self._data.group_manager[group_id].group_task_status[task]
|
||||||
|
self.save()
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class GroupManager(StaticData):
|
class GroupManager(StaticData):
|
||||||
"""
|
"""
|
||||||
群权限 | 功能 | 总开关 | 聊天时间 管理器
|
群权限 | 功能 | 总开关 | 聊天时间 管理器
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Path):
|
def __init__(self, file: Path):
|
||||||
super().__init__(file)
|
super().__init__(file, False)
|
||||||
if not self._data:
|
self._data = BaseData.parse_file(file) if file.exists() else BaseData()
|
||||||
self._data = {
|
|
||||||
"super": {"white_group_list": []},
|
|
||||||
"group_manager": {},
|
|
||||||
}
|
|
||||||
self._task = {}
|
|
||||||
|
|
||||||
def block_plugin(self, module: str, group_id: int):
|
def block_plugin(self, module: str, group_id: int, is_save: bool = True):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
锁定插件
|
锁定插件
|
||||||
参数:
|
参数:
|
||||||
:param module: 功能模块名
|
:param module: 功能模块名
|
||||||
:param group_id: 群组,None时为超级用户禁用
|
:param group_id: 群组,None时为超级用户禁用
|
||||||
|
:param is_save: 是否保存文件
|
||||||
"""
|
"""
|
||||||
self._set_plugin_status(module, "block", group_id)
|
self._set_plugin_status(module, "block", group_id, is_save)
|
||||||
|
|
||||||
def unblock_plugin(self, module: str, group_id: int):
|
def unblock_plugin(self, module: str, group_id: int, is_save: bool = True):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
解锁插件
|
解锁插件
|
||||||
参数:
|
参数:
|
||||||
:param module: 功能模块名
|
:param module: 功能模块名
|
||||||
:param group_id: 群组
|
:param group_id: 群组
|
||||||
|
:param is_save: 是否保存文件
|
||||||
"""
|
"""
|
||||||
self._set_plugin_status(module, "unblock", group_id)
|
self._set_plugin_status(module, "unblock", group_id, is_save)
|
||||||
|
|
||||||
def turn_on_group_bot_status(self, group_id: int):
|
def turn_on_group_bot_status(self, group_id: int):
|
||||||
"""
|
"""
|
||||||
@ -67,6 +105,7 @@ class GroupManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
self._set_group_bot_status(group_id, False)
|
self._set_group_bot_status(group_id, False)
|
||||||
|
|
||||||
|
@init_group
|
||||||
def check_group_bot_status(self, group_id: int) -> bool:
|
def check_group_bot_status(self, group_id: int) -> bool:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -74,16 +113,9 @@ class GroupManager(StaticData):
|
|||||||
参数:
|
参数:
|
||||||
:param group_id: 说明
|
:param group_id: 说明
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id)
|
return self._data.group_manager[str(group_id)].status
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
if self._data["group_manager"][group_id].get("status") is None:
|
|
||||||
default_group_bot_status = Config.get_config("group_manager", "DEFAULT_GROUP_BOT_STATUS")
|
|
||||||
if default_group_bot_status:
|
|
||||||
default_group_bot_status = True
|
|
||||||
self._data["group_manager"][group_id]["status"] = default_group_bot_status
|
|
||||||
return self._data["group_manager"][group_id]["status"]
|
|
||||||
|
|
||||||
|
@init_group
|
||||||
def set_group_level(self, group_id: int, level: int):
|
def set_group_level(self, group_id: int, level: int):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -92,12 +124,10 @@ class GroupManager(StaticData):
|
|||||||
:param group_id: 群组
|
:param group_id: 群组
|
||||||
:param level: 权限等级
|
:param level: 权限等级
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id)
|
self._data.group_manager[str(group_id)].level = level
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
self._data["group_manager"][group_id]["level"] = level
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
@init_group
|
||||||
def get_plugin_status(self, module: str, group_id: int) -> bool:
|
def get_plugin_status(self, module: str, group_id: int) -> bool:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -106,14 +136,9 @@ class GroupManager(StaticData):
|
|||||||
:param module: 功能模块名
|
:param module: 功能模块名
|
||||||
:param group_id: 群组
|
:param group_id: 群组
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id) if group_id else group_id
|
return module not in self._data.group_manager[str(group_id)].close_plugins
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
return True
|
|
||||||
if module in self._data["group_manager"][group_id]["close_plugins"]:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
@init_group
|
||||||
def get_group_level(self, group_id: int) -> int:
|
def get_group_level(self, group_id: int) -> int:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -121,10 +146,7 @@ class GroupManager(StaticData):
|
|||||||
参数:
|
参数:
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id)
|
return self._data.group_manager[str(group_id)].level
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
return self._data["group_manager"][group_id]["level"]
|
|
||||||
|
|
||||||
def check_group_is_white(self, group_id: int) -> bool:
|
def check_group_is_white(self, group_id: int) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -133,7 +155,7 @@ class GroupManager(StaticData):
|
|||||||
参数:
|
参数:
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
"""
|
"""
|
||||||
return group_id in self._data["super"]["white_group_list"]
|
return group_id in self._data.white_group
|
||||||
|
|
||||||
def add_group_white_list(self, group_id: int):
|
def add_group_white_list(self, group_id: int):
|
||||||
"""
|
"""
|
||||||
@ -142,8 +164,8 @@ class GroupManager(StaticData):
|
|||||||
参数:
|
参数:
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
"""
|
"""
|
||||||
if group_id not in self._data["super"]["white_group_list"]:
|
if group_id not in self._data.white_group:
|
||||||
self._data["super"]["white_group_list"].append(group_id)
|
self._data.white_group.append(group_id)
|
||||||
|
|
||||||
def delete_group_white_list(self, group_id: int):
|
def delete_group_white_list(self, group_id: int):
|
||||||
"""
|
"""
|
||||||
@ -152,16 +174,34 @@ class GroupManager(StaticData):
|
|||||||
参数:
|
参数:
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
"""
|
"""
|
||||||
if group_id in self._data["super"]["white_group_list"]:
|
if group_id in self._data.white_group:
|
||||||
self._data["super"]["white_group_list"].remove(group_id)
|
self._data.white_group.remove(group_id)
|
||||||
|
|
||||||
def get_group_white_list(self) -> List[str]:
|
def get_group_white_list(self) -> List[int]:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
获取所有群白名单
|
获取所有群白名单
|
||||||
"""
|
"""
|
||||||
return self._data["super"]["white_group_list"]
|
return self._data.white_group
|
||||||
|
|
||||||
|
def load_task(self):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
加载被动技能
|
||||||
|
"""
|
||||||
|
for matcher in get_matchers(True):
|
||||||
|
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
||||||
|
try:
|
||||||
|
_module = _plugin.module
|
||||||
|
plugin_task = _module.__getattribute__("__plugin_task__")
|
||||||
|
for key in plugin_task.keys():
|
||||||
|
if key in self._data.task.keys():
|
||||||
|
raise ValueError(f"plugin_task:{key} 已存在!")
|
||||||
|
self._data.task[key] = plugin_task[key]
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@init_group
|
||||||
def delete_group(self, group_id: int):
|
def delete_group(self, group_id: int):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -169,13 +209,11 @@ class GroupManager(StaticData):
|
|||||||
参数:
|
参数:
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
"""
|
"""
|
||||||
if group_id in self._data["group_manager"]:
|
if group_id in self._data.white_group:
|
||||||
del self._data["group_manager"][str(group_id)]
|
self._data.white_group.remove(group_id)
|
||||||
if group_id in self._data["super"]["white_group_list"]:
|
self.save()
|
||||||
self._data["super"]["white_group_list"].remove(group_id)
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
async def open_group_task(self, group_id: int, task: str):
|
def open_group_task(self, group_id: int, task: str):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
开启群被动技能
|
开启群被动技能
|
||||||
@ -183,9 +221,9 @@ class GroupManager(StaticData):
|
|||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
:param task: 被动技能名称
|
:param task: 被动技能名称
|
||||||
"""
|
"""
|
||||||
await self._set_group_task_status(group_id, task, True)
|
self._set_group_group_task_status(group_id, task, True)
|
||||||
|
|
||||||
async def close_group_task(self, group_id: int, task: str):
|
def close_group_task(self, group_id: int, task: str):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
关闭群被动技能
|
关闭群被动技能
|
||||||
@ -193,9 +231,10 @@ class GroupManager(StaticData):
|
|||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
:param task: 被动技能名称
|
:param task: 被动技能名称
|
||||||
"""
|
"""
|
||||||
await self._set_group_task_status(group_id, task, False)
|
self._set_group_group_task_status(group_id, task, False)
|
||||||
|
|
||||||
async def check_group_task_status(self, group_id: int, task: str) -> bool:
|
@init_task
|
||||||
|
def check_group_task_status(self, group_id: int, task: str) -> bool:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
查看群被动技能状态
|
查看群被动技能状态
|
||||||
@ -203,23 +242,17 @@ class GroupManager(StaticData):
|
|||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
:param task: 被动技能名称
|
:param task: 被动技能名称
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id)
|
return self._data.group_manager[str(group_id)].group_task_status.get(task, False)
|
||||||
if (
|
|
||||||
not self._data["group_manager"][group_id].get("group_task_status")
|
|
||||||
or self._data["group_manager"][group_id]["group_task_status"].get(task)
|
|
||||||
is None
|
|
||||||
):
|
|
||||||
await self.init_group_task(group_id)
|
|
||||||
return self._data["group_manager"][group_id]["group_task_status"][task]
|
|
||||||
|
|
||||||
def get_task_data(self) -> Dict[str, str]:
|
def get_task_data(self) -> Dict[str, str]:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
获取所有被动任务
|
获取所有被动任务
|
||||||
"""
|
"""
|
||||||
return self._task
|
return self._data.task
|
||||||
|
|
||||||
async def group_task_status(self, group_id: int) -> str:
|
@init_task
|
||||||
|
def group_group_task_status(self, group_id: int) -> str:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
查看群被全部动技能状态
|
查看群被全部动技能状态
|
||||||
@ -228,13 +261,13 @@ class GroupManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
x = "[群被动技能]:\n"
|
x = "[群被动技能]:\n"
|
||||||
group_id = str(group_id)
|
group_id = str(group_id)
|
||||||
if not self._data["group_manager"][group_id].get("group_task_status"):
|
for key in self._data.group_manager[group_id].group_task_status.keys():
|
||||||
await self.init_group_task(group_id)
|
x += f'{self._data.task[key]}:{"√" if self.check_group_task_status(int(group_id), key) else "×"}\n'
|
||||||
for key in self._data["group_manager"][group_id]["group_task_status"].keys():
|
|
||||||
x += f'{self._task[key]}:{"√" if await self.check_group_task_status(int(group_id), key) else "×"}\n'
|
|
||||||
return x[:-1]
|
return x[:-1]
|
||||||
|
|
||||||
async def _set_group_task_status(self, group_id: int, task: str, status: bool):
|
@init_task
|
||||||
|
@init_group
|
||||||
|
def _set_group_group_task_status(self, group_id: int, task: str, status: bool):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
管理群被动技能状态
|
管理群被动技能状态
|
||||||
@ -243,74 +276,16 @@ class GroupManager(StaticData):
|
|||||||
:param task: 被动技能
|
:param task: 被动技能
|
||||||
:param status: 状态
|
:param status: 状态
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id)
|
self._data.group_manager[str(group_id)].group_task_status[task] = status
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
if (
|
|
||||||
not self._data["group_manager"][group_id].get("group_task_status")
|
|
||||||
or self._data["group_manager"][group_id]["group_task_status"].get(task)
|
|
||||||
is None
|
|
||||||
):
|
|
||||||
await self.init_group_task(group_id)
|
|
||||||
self._data["group_manager"][group_id]["group_task_status"][task] = status
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
async def init_group_task(self, group_id: Optional[Union[int, str]] = None):
|
|
||||||
"""
|
|
||||||
说明:
|
|
||||||
初始化群聊 被动技能 状态
|
|
||||||
"""
|
|
||||||
if not self._task:
|
|
||||||
_m = []
|
|
||||||
for matcher in get_matchers():
|
|
||||||
if matcher.plugin_name not in _m:
|
|
||||||
_m.append(matcher.plugin_name)
|
|
||||||
_plugin = nonebot.plugin.get_plugin(matcher.plugin_name)
|
|
||||||
try:
|
|
||||||
_module = _plugin.module
|
|
||||||
plugin_task = _module.__getattribute__("__plugin_task__")
|
|
||||||
for key in plugin_task.keys():
|
|
||||||
if key in self._task.keys():
|
|
||||||
raise ValueError(f"plugin_task:{key} 已存在!")
|
|
||||||
self._task[key] = plugin_task[key]
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
bot = get_bot()
|
|
||||||
if bot or group_id:
|
|
||||||
if group_id:
|
|
||||||
_group_list = [group_id]
|
|
||||||
else:
|
|
||||||
_group_list = [x["group_id"] for x in await bot.get_group_list()]
|
|
||||||
for group_id in _group_list:
|
|
||||||
group_id = str(group_id)
|
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
if not self._data["group_manager"][group_id].get("group_task_status"):
|
|
||||||
self._data["group_manager"][group_id]["group_task_status"] = {}
|
|
||||||
for task in self._task:
|
|
||||||
if (
|
|
||||||
self._data["group_manager"][group_id]["group_task_status"].get(
|
|
||||||
task
|
|
||||||
)
|
|
||||||
is None
|
|
||||||
):
|
|
||||||
self._data["group_manager"][group_id]["group_task_status"][
|
|
||||||
task
|
|
||||||
] = Config.get_config('_task', f'DEFAULT_{task}', default=True)
|
|
||||||
for task in list(
|
|
||||||
self._data["group_manager"][group_id]["group_task_status"]
|
|
||||||
):
|
|
||||||
if task not in self._task:
|
|
||||||
del self._data["group_manager"][group_id]["group_task_status"][
|
|
||||||
task
|
|
||||||
]
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
@init_group
|
||||||
def _set_plugin_status(
|
def _set_plugin_status(
|
||||||
self,
|
self,
|
||||||
module: str,
|
module: str,
|
||||||
status: str,
|
status: str,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
|
is_save: bool
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -319,39 +294,19 @@ class GroupManager(StaticData):
|
|||||||
:param module: 功能模块名
|
:param module: 功能模块名
|
||||||
:param status: 功能状态
|
:param status: 功能状态
|
||||||
:param group_id: 群组
|
:param group_id: 群组
|
||||||
|
:param is_save: 是否保存
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id) if group_id else group_id
|
group_id = str(group_id) if group_id else group_id
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
if status == "block":
|
if status == "block":
|
||||||
if module not in self._data["group_manager"][group_id]["close_plugins"]:
|
if module not in self._data.group_manager[group_id].close_plugins:
|
||||||
self._data["group_manager"][group_id]["close_plugins"].append(module)
|
self._data.group_manager[group_id].close_plugins.append(module)
|
||||||
else:
|
else:
|
||||||
if module in self._data["group_manager"][group_id]["close_plugins"]:
|
if module in self._data.group_manager[group_id].close_plugins:
|
||||||
self._data["group_manager"][group_id]["close_plugins"].remove(module)
|
self._data.group_manager[group_id].close_plugins.remove(module)
|
||||||
self.save()
|
if is_save:
|
||||||
|
self.save()
|
||||||
def _init_group(self, group_id: str):
|
|
||||||
"""
|
|
||||||
说明:
|
|
||||||
初始化群数据
|
|
||||||
参数:
|
|
||||||
:param group_id: 群号
|
|
||||||
"""
|
|
||||||
default_group_level = Config.get_config("group_manager", "DEFAULT_GROUP_LEVEL")
|
|
||||||
if default_group_level is None:
|
|
||||||
default_group_level = 5
|
|
||||||
default_group_bot_status = Config.get_config("group_manager", "DEFAULT_GROUP_BOT_STATUS")
|
|
||||||
if default_group_bot_status:
|
|
||||||
default_group_bot_status = True
|
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._data["group_manager"][group_id] = {
|
|
||||||
"level": default_group_level,
|
|
||||||
"status": default_group_bot_status,
|
|
||||||
"close_plugins": [],
|
|
||||||
"group_task_status": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@init_group
|
||||||
def _set_group_bot_status(self, group_id: Union[int, str], status: bool):
|
def _set_group_bot_status(self, group_id: Union[int, str], status: bool):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
@ -360,19 +315,38 @@ class GroupManager(StaticData):
|
|||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
:param status: 开关状态
|
:param status: 开关状态
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id)
|
self._data.group_manager[str(group_id)].status = status
|
||||||
if not self._data["group_manager"].get(group_id):
|
|
||||||
self._init_group(group_id)
|
|
||||||
self._data["group_manager"][group_id]["status"] = status
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_super_old_data(self) -> Optional[dict]:
|
def reload(self):
|
||||||
|
if self.file.exists():
|
||||||
|
t = self._data.task
|
||||||
|
self._data = BaseData.parse_file(self.file)
|
||||||
|
self._data.task = t
|
||||||
|
|
||||||
|
def save(self, path: Union[str, Path] = None):
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
获取旧数据,平时使用请不要调用
|
保存文件
|
||||||
|
参数:
|
||||||
|
:param path: 路径文件
|
||||||
"""
|
"""
|
||||||
if self._data["super"].get("close_plugins"):
|
path = path or self.file
|
||||||
_x = self._data["super"].get("close_plugins")
|
if isinstance(path, str):
|
||||||
del self._data["super"]["close_plugins"]
|
path = Path(path)
|
||||||
return _x
|
if path:
|
||||||
return None
|
dict_data = self._data.dict()
|
||||||
|
del dict_data["task"]
|
||||||
|
with open(path, "w", encoding="utf8") as f:
|
||||||
|
json.dump(dict_data, f, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
# def get_super_old_data(self) -> Optional[dict]:
|
||||||
|
# """
|
||||||
|
# 说明:
|
||||||
|
# 获取旧数据,平时使用请不要调用
|
||||||
|
# """
|
||||||
|
# if self._data["super"].get("close_plugins"):
|
||||||
|
# _x = self._data["super"].get("close_plugins")
|
||||||
|
# del self._data["super"]["close_plugins"]
|
||||||
|
# return _x
|
||||||
|
# return None
|
||||||
|
|||||||
95
utils/manager/models.py
Normal file
95
utils/manager/models.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
from typing import List, Optional, Dict, Literal, Tuple, Union
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from configs.config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class AdminSetting(BaseModel):
|
||||||
|
"""
|
||||||
|
管理员设置
|
||||||
|
"""
|
||||||
|
|
||||||
|
level: int
|
||||||
|
cmd: Optional[List[str]]
|
||||||
|
|
||||||
|
|
||||||
|
class BaseGroup(BaseModel):
|
||||||
|
"""
|
||||||
|
基础群聊信息
|
||||||
|
"""
|
||||||
|
|
||||||
|
level: int = Config.get_config("group_manager", "DEFAULT_GROUP_LEVEL") # 群等级
|
||||||
|
status: bool = Config.get_config(
|
||||||
|
"group_manager", "DEFAULT_GROUP_BOT_STATUS"
|
||||||
|
) # 总开关状态
|
||||||
|
close_plugins: List[str] = [] # 已关闭插件
|
||||||
|
group_task_status: Dict[str, bool] = {} # 被动状态
|
||||||
|
|
||||||
|
|
||||||
|
class BaseData(BaseModel):
|
||||||
|
"""
|
||||||
|
群基本信息
|
||||||
|
"""
|
||||||
|
|
||||||
|
white_group: List[int] = [] # 白名单
|
||||||
|
group_manager: Dict[str, BaseGroup] = {} # 群组管理
|
||||||
|
task: Dict[str, str] = {} # 被动任务 【英文:中文】
|
||||||
|
|
||||||
|
|
||||||
|
class PluginBlock(BaseModel):
|
||||||
|
"""
|
||||||
|
插件阻断
|
||||||
|
"""
|
||||||
|
|
||||||
|
status: bool # 限制状态
|
||||||
|
check_type: Literal["private", "group", "all"] # 检查类型
|
||||||
|
limit_type: Literal["user", "group"] # 监听对象
|
||||||
|
rst: Optional[str] # 阻断时回复
|
||||||
|
|
||||||
|
|
||||||
|
class PluginCd(BaseModel):
|
||||||
|
"""
|
||||||
|
插件阻断
|
||||||
|
"""
|
||||||
|
|
||||||
|
cd: int # cd
|
||||||
|
status: bool # 限制状态
|
||||||
|
check_type: Literal["private", "group", "all"] # 检查类型
|
||||||
|
limit_type: Literal["user", "group"] # 监听对象
|
||||||
|
rst: Optional[str] # 阻断时回复
|
||||||
|
|
||||||
|
|
||||||
|
class PluginCount(BaseModel):
|
||||||
|
"""
|
||||||
|
插件阻断
|
||||||
|
"""
|
||||||
|
|
||||||
|
max_count: int # 次数
|
||||||
|
status: bool # 限制状态
|
||||||
|
limit_type: Literal["user", "group"] # 监听对象
|
||||||
|
rst: Optional[str] # 阻断时回复
|
||||||
|
|
||||||
|
|
||||||
|
class PluginSetting(BaseModel):
|
||||||
|
"""
|
||||||
|
插件设置
|
||||||
|
"""
|
||||||
|
|
||||||
|
cmd: List[str] = [] # 命令 或 命令别名
|
||||||
|
default_status: bool = True # 默认开关状态
|
||||||
|
level: int = 5 # 功能权限等级
|
||||||
|
limit_superuser: bool = False # 功能状态是否限制超级用户
|
||||||
|
plugin_type: Tuple[Union[str, int], ...] = ("normal",) # 插件类型
|
||||||
|
cost_gold: int = 0 # 需要消费的金币
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin(BaseModel):
|
||||||
|
"""
|
||||||
|
插件数据
|
||||||
|
"""
|
||||||
|
|
||||||
|
plugin_name: str # 模块名
|
||||||
|
status: Optional[bool] = True # 开关状态
|
||||||
|
error: Optional[bool] = False # 是否加载报错
|
||||||
|
block_type: Optional[str] = None # 关闭类型
|
||||||
|
author: Optional[str] = None # 作者
|
||||||
|
version: Optional[int] = None # 版本
|
||||||
2
utils/manager/none_plugin_count_manager.py
Executable file → Normal file
2
utils/manager/none_plugin_count_manager.py
Executable file → Normal file
@ -1,4 +1,4 @@
|
|||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|||||||
153
utils/manager/plugins2block_manager.py
Executable file → Normal file
153
utils/manager/plugins2block_manager.py
Executable file → Normal file
@ -1,11 +1,12 @@
|
|||||||
from typing import Optional, Dict
|
from typing import Optional, Dict, Literal, Union
|
||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.utils import UserBlockLimiter
|
from utils.utils import UserBlockLimiter
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
from ruamel import yaml
|
||||||
|
from .models import PluginBlock
|
||||||
|
|
||||||
yaml = YAML(typ="safe")
|
_yaml = yaml.YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
class Plugins2blockManager(StaticData):
|
class Plugins2blockManager(StaticData):
|
||||||
@ -14,53 +15,45 @@ class Plugins2blockManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Path):
|
def __init__(self, file: Path):
|
||||||
self.file = file
|
super().__init__(file, False)
|
||||||
super().__init__(None)
|
|
||||||
self._block_limiter: Dict[str, UserBlockLimiter] = {}
|
self._block_limiter: Dict[str, UserBlockLimiter] = {}
|
||||||
if file.exists():
|
self.__load_file()
|
||||||
with open(file, "r", encoding="utf8") as f:
|
|
||||||
self._data = yaml.load(f)
|
|
||||||
if "PluginBlockLimit" in self._data.keys():
|
|
||||||
self._data = self._data["PluginBlockLimit"] or {}
|
|
||||||
|
|
||||||
def add_block_limit(
|
def add_block_limit(
|
||||||
self,
|
self,
|
||||||
plugin: str,
|
plugin: str,
|
||||||
*,
|
*,
|
||||||
status: Optional[bool] = True,
|
status: Optional[bool] = True,
|
||||||
check_type: Optional[str] = "all",
|
check_type: Literal["private", "group", "all"] = "all",
|
||||||
limit_type: Optional[str] = "user",
|
limit_type: Literal["user", "group"] = "user",
|
||||||
rst: Optional[str] = None,
|
rst: Optional[str] = None,
|
||||||
**kwargs # 用于接收额外实参
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
添加插件调用 block 限制
|
说明:
|
||||||
:param plugin: 插件模块名称
|
添加插件调用 block 限制
|
||||||
:param status: 默认开关状态
|
参数:
|
||||||
:param check_type: 检查类型 'private'/'group'/'all',限制私聊/群聊/全部
|
:param plugin: 插件模块名称
|
||||||
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
:param status: 默认开关状态
|
||||||
:param rst: 回复的话,为空则不回复
|
:param check_type: 检查类型 'private'/'group'/'all',限制私聊/群聊/全部
|
||||||
|
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
||||||
|
:param rst: 回复的话,为空则不回复
|
||||||
"""
|
"""
|
||||||
status = status or True
|
|
||||||
check_type = check_type or "all"
|
|
||||||
limit_type = limit_type or "user"
|
|
||||||
if check_type not in ["all", "group", "private"]:
|
if check_type not in ["all", "group", "private"]:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"{plugin} 添加block限制错误,‘check_type‘ 必须为 'private'/'group'/'all'"
|
f"{plugin} 添加block限制错误,‘check_type‘ 必须为 'private'/'group'/'all'"
|
||||||
)
|
)
|
||||||
if limit_type not in ["user", "group"]:
|
if limit_type not in ["user", "group"]:
|
||||||
raise ValueError(f"{plugin} 添加block限制错误,‘limit_type‘ 必须为 'user'/'group'")
|
raise ValueError(f"{plugin} 添加block限制错误,‘limit_type‘ 必须为 'user'/'group'")
|
||||||
self._data[plugin] = {
|
self._data[plugin] = PluginBlock(
|
||||||
"status": status,
|
status=status, check_type=check_type, limit_type=limit_type, rst=rst
|
||||||
"check_type": check_type,
|
)
|
||||||
"limit_type": limit_type,
|
|
||||||
"rst": rst,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_plugin_block_data(self, plugin: str) -> Optional[dict]:
|
def get_plugin_block_data(self, plugin: str) -> Optional[PluginBlock]:
|
||||||
"""
|
"""
|
||||||
获取插件block数据
|
说明:
|
||||||
:param plugin: 模块名
|
获取插件block数据
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self.check_plugin_block_status(plugin):
|
if self.check_plugin_block_status(plugin):
|
||||||
return self._data[plugin]
|
return self._data[plugin]
|
||||||
@ -68,16 +61,20 @@ class Plugins2blockManager(StaticData):
|
|||||||
|
|
||||||
def check_plugin_block_status(self, plugin: str) -> bool:
|
def check_plugin_block_status(self, plugin: str) -> bool:
|
||||||
"""
|
"""
|
||||||
检测插件是否有 block
|
说明:
|
||||||
:param plugin: 模块名
|
检测插件是否有 block
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
return plugin in self._data.keys() and self._data[plugin]["status"]
|
return plugin in self._data.keys() and self._data[plugin].status
|
||||||
|
|
||||||
def check(self, id_: int, plugin: str) -> bool:
|
def check(self, id_: int, plugin: str) -> bool:
|
||||||
"""
|
"""
|
||||||
检查 block
|
说明:
|
||||||
:param plugin: 模块名
|
检查 block
|
||||||
:param id_: 限制 id
|
参数:
|
||||||
|
:param id_: 限制 id
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self._block_limiter.get(plugin):
|
if self._block_limiter.get(plugin):
|
||||||
return self._block_limiter[plugin].check(id_)
|
return self._block_limiter[plugin].check(id_)
|
||||||
@ -85,26 +82,30 @@ class Plugins2blockManager(StaticData):
|
|||||||
|
|
||||||
def set_true(self, id_: int, plugin: str):
|
def set_true(self, id_: int, plugin: str):
|
||||||
"""
|
"""
|
||||||
对插件 block
|
说明:
|
||||||
:param plugin: 模块名
|
对插件 block
|
||||||
:param id_: 限制 id
|
参数:
|
||||||
|
:param id_: 限制 id
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self._block_limiter.get(plugin):
|
if self._block_limiter.get(plugin):
|
||||||
self._block_limiter[plugin].set_true(id_)
|
self._block_limiter[plugin].set_true(id_)
|
||||||
|
|
||||||
def set_false(self, id_: int, plugin: str):
|
def set_false(self, id_: int, plugin: str):
|
||||||
"""
|
"""
|
||||||
对插件 unblock
|
说明:
|
||||||
:param plugin: 模块名
|
对插件 unblock
|
||||||
:param id_: 限制 id
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
|
:param id_: 限制 id
|
||||||
"""
|
"""
|
||||||
if self._block_limiter.get(plugin):
|
if self._block_limiter.get(plugin):
|
||||||
self._block_limiter[plugin].set_false(id_)
|
self._block_limiter[plugin].set_false(id_)
|
||||||
|
|
||||||
def reload_block_limit(self):
|
def reload_block_limit(self):
|
||||||
"""
|
"""
|
||||||
加载 block 限制器
|
说明:
|
||||||
:return:
|
加载 block 限制器
|
||||||
"""
|
"""
|
||||||
for plugin in self._data:
|
for plugin in self._data:
|
||||||
if self.check_plugin_block_status(plugin):
|
if self.check_plugin_block_status(plugin):
|
||||||
@ -113,10 +114,62 @@ class Plugins2blockManager(StaticData):
|
|||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
"""
|
"""
|
||||||
重载本地数据
|
说明:
|
||||||
|
重载本地数据
|
||||||
"""
|
"""
|
||||||
|
self.__load_file()
|
||||||
|
self.reload_block_limit()
|
||||||
|
|
||||||
|
def save(self, path: Union[str, Path] = None):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
保存文件
|
||||||
|
参数:
|
||||||
|
:param path: 文件路径
|
||||||
|
"""
|
||||||
|
path = path or self.file
|
||||||
|
if isinstance(path, str):
|
||||||
|
path = Path(path)
|
||||||
|
if path:
|
||||||
|
with open(path, "w", encoding="utf8") as f:
|
||||||
|
yaml.dump(
|
||||||
|
{"PluginBlockLimit": self.dict()},
|
||||||
|
f,
|
||||||
|
indent=2,
|
||||||
|
Dumper=yaml.RoundTripDumper,
|
||||||
|
allow_unicode=True,
|
||||||
|
)
|
||||||
|
_data = yaml.round_trip_load(open(path, encoding="utf8"))
|
||||||
|
_data["PluginBlockLimit"].yaml_set_start_comment(
|
||||||
|
"""# 用户调用阻塞
|
||||||
|
# 即 当用户调用此功能还未结束时
|
||||||
|
# 用发送消息阻止用户重复调用此命令直到该命令结束
|
||||||
|
# key:模块名称
|
||||||
|
# status:此限制的开关状态
|
||||||
|
# check_type:'private'/'group'/'all',限制私聊/群聊/全部
|
||||||
|
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
||||||
|
# 示例:'user':阻塞用户,'group':阻塞群聊
|
||||||
|
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
|
||||||
|
# rst 为 "" 或 None 时则不回复
|
||||||
|
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
|
||||||
|
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
|
||||||
|
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
|
||||||
|
indent=2,
|
||||||
|
)
|
||||||
|
with open(path, "w", encoding="utf8") as wf:
|
||||||
|
yaml.round_trip_dump(
|
||||||
|
_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def __load_file(self):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
读取配置文件
|
||||||
|
"""
|
||||||
|
self._data: Dict[str, PluginBlock] = {}
|
||||||
if self.file.exists():
|
if self.file.exists():
|
||||||
with open(self.file, "r", encoding="utf8") as f:
|
with open(self.file, "r", encoding="utf8") as f:
|
||||||
self._data: dict = yaml.load(f)
|
temp = yaml.round_trip_load(f)
|
||||||
self._data = self._data["PluginBlockLimit"]
|
if "PluginBlockLimit" in temp.keys():
|
||||||
self.reload_block_limit()
|
for k, v in temp["PluginBlockLimit"].items():
|
||||||
|
self._data[k] = PluginBlock.parse_obj(v)
|
||||||
|
|||||||
167
utils/manager/plugins2cd_manager.py
Executable file → Normal file
167
utils/manager/plugins2cd_manager.py
Executable file → Normal file
@ -1,11 +1,12 @@
|
|||||||
from typing import Optional, Dict
|
from typing import Optional, Dict, Literal, Union
|
||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from utils.utils import FreqLimiter
|
from utils.utils import FreqLimiter
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
from ruamel import yaml
|
||||||
|
from .models import PluginCd
|
||||||
|
|
||||||
yaml = YAML(typ="safe")
|
_yaml = yaml.YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
class Plugins2cdManager(StaticData):
|
class Plugins2cdManager(StaticData):
|
||||||
@ -14,16 +15,9 @@ class Plugins2cdManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Path):
|
def __init__(self, file: Path):
|
||||||
self.file = file
|
super().__init__(file, False)
|
||||||
super().__init__(None)
|
|
||||||
self._freq_limiter: Dict[str, FreqLimiter] = {}
|
self._freq_limiter: Dict[str, FreqLimiter] = {}
|
||||||
if file.exists():
|
self.__load_file()
|
||||||
with open(file, "r", encoding="utf8") as f:
|
|
||||||
self._data = yaml.load(f)
|
|
||||||
if "PluginCdLimit" in self._data.keys():
|
|
||||||
self._data = (
|
|
||||||
self._data["PluginCdLimit"] if self._data["PluginCdLimit"] else {}
|
|
||||||
)
|
|
||||||
|
|
||||||
def add_cd_limit(
|
def add_cd_limit(
|
||||||
self,
|
self,
|
||||||
@ -31,42 +25,35 @@ class Plugins2cdManager(StaticData):
|
|||||||
*,
|
*,
|
||||||
cd: Optional[int] = 5,
|
cd: Optional[int] = 5,
|
||||||
status: Optional[bool] = True,
|
status: Optional[bool] = True,
|
||||||
check_type: Optional[str] = "all",
|
check_type: Literal["private", "group", "all"] = "all",
|
||||||
limit_type: Optional[str] = "user",
|
limit_type: Literal["user", "group"] = "user",
|
||||||
rst: Optional[str] = None,
|
rst: Optional[str] = None,
|
||||||
**kwargs # 用于接收额外实参
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
添加插件调用 cd 限制
|
说明:
|
||||||
:param plugin: 插件模块名称
|
添加插件调用 cd 限制
|
||||||
:param cd: cd 时长
|
参数:
|
||||||
:param status: 默认开关状态
|
:param plugin: 插件模块名称
|
||||||
:param check_type: 检查类型 'private'/'group'/'all',限制私聊/群聊/全部
|
:param cd: cd 时长
|
||||||
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
:param status: 默认开关状态
|
||||||
:param rst: 回复的话,为空则不回复
|
:param check_type: 检查类型 'private'/'group'/'all',限制私聊/群聊/全部
|
||||||
|
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
||||||
|
:param rst: 回复的话,为空则不回复
|
||||||
"""
|
"""
|
||||||
cd = cd or 5
|
|
||||||
status = status or True
|
|
||||||
check_type = check_type or "all"
|
|
||||||
limit_type = limit_type or "user"
|
|
||||||
if check_type not in ["all", "group", "private"]:
|
if check_type not in ["all", "group", "private"]:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"{plugin} 添加cd限制错误,‘check_type‘ 必须为 'private'/'group'/'all'"
|
f"{plugin} 添加cd限制错误,‘check_type‘ 必须为 'private'/'group'/'all'"
|
||||||
)
|
)
|
||||||
if limit_type not in ["user", "group"]:
|
if limit_type not in ["user", "group"]:
|
||||||
raise ValueError(f"{plugin} 添加cd限制错误,‘limit_type‘ 必须为 'user'/'group'")
|
raise ValueError(f"{plugin} 添加cd限制错误,‘limit_type‘ 必须为 'user'/'group'")
|
||||||
self._data[plugin] = {
|
self._data[plugin] = PluginCd(cd=cd, status=status, check_type=check_type, limit_type=limit_type, rst=rst)
|
||||||
"cd": cd,
|
|
||||||
"status": status,
|
|
||||||
"check_type": check_type,
|
|
||||||
"limit_type": limit_type,
|
|
||||||
"rst": rst,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_plugin_cd_data(self, plugin: str) -> Optional[dict]:
|
def get_plugin_cd_data(self, plugin: str) -> Optional[PluginCd]:
|
||||||
"""
|
"""
|
||||||
获取插件cd数据
|
说明:
|
||||||
:param plugin: 模块名
|
获取插件cd数据
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self.check_plugin_cd_status(plugin):
|
if self.check_plugin_cd_status(plugin):
|
||||||
return self._data[plugin]
|
return self._data[plugin]
|
||||||
@ -74,20 +61,24 @@ class Plugins2cdManager(StaticData):
|
|||||||
|
|
||||||
def check_plugin_cd_status(self, plugin: str) -> bool:
|
def check_plugin_cd_status(self, plugin: str) -> bool:
|
||||||
"""
|
"""
|
||||||
检测插件是否有 cd
|
说明:
|
||||||
:param plugin: 模块名
|
检测插件是否有 cd
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
plugin in self._data.keys()
|
plugin in self._data.keys()
|
||||||
and self._data[plugin]["cd"] > 0
|
and self._data[plugin].cd > 0
|
||||||
and self._data[plugin]["status"]
|
and self._data[plugin].status
|
||||||
)
|
)
|
||||||
|
|
||||||
def check(self, plugin: str, id_: int) -> bool:
|
def check(self, plugin: str, id_: int) -> bool:
|
||||||
"""
|
"""
|
||||||
检查 cd
|
说明:
|
||||||
:param plugin: 模块名
|
检查 cd
|
||||||
:param id_: 限制 id
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
|
:param id_: 限制 id
|
||||||
"""
|
"""
|
||||||
if self._freq_limiter.get(plugin):
|
if self._freq_limiter.get(plugin):
|
||||||
return self._freq_limiter[plugin].check(id_)
|
return self._freq_limiter[plugin].check(id_)
|
||||||
@ -95,42 +86,96 @@ class Plugins2cdManager(StaticData):
|
|||||||
|
|
||||||
def start_cd(self, plugin: str, id_: int, cd: int = 0):
|
def start_cd(self, plugin: str, id_: int, cd: int = 0):
|
||||||
"""
|
"""
|
||||||
开始cd
|
说明:
|
||||||
:param plugin: 模块名
|
开始cd
|
||||||
:param id_: cd 限制类型
|
参数:
|
||||||
:param cd: cd 时长
|
:param plugin: 模块名
|
||||||
:return:
|
:param id_: cd 限制类型
|
||||||
|
:param cd: cd 时长
|
||||||
"""
|
"""
|
||||||
if self._freq_limiter.get(plugin):
|
if self._freq_limiter.get(plugin):
|
||||||
self._freq_limiter[plugin].start_cd(id_, cd)
|
self._freq_limiter[plugin].start_cd(id_, cd)
|
||||||
|
|
||||||
def get_plugin_data(self, plugin: str) -> dict:
|
def get_plugin_data(self, plugin: str) -> Optional[PluginCd]:
|
||||||
"""
|
"""
|
||||||
获取单个模块限制数据
|
说明:
|
||||||
:param plugin: 模块名
|
获取单个模块限制数据
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self._data.get(plugin) is not None:
|
if self._data.get(plugin):
|
||||||
return self._data.get(plugin)
|
return self._data.get(plugin)
|
||||||
return {}
|
|
||||||
|
|
||||||
def reload_cd_limit(self):
|
def reload_cd_limit(self):
|
||||||
"""
|
"""
|
||||||
加载 cd 限制器
|
说明:
|
||||||
:return:
|
加载 cd 限制器
|
||||||
"""
|
"""
|
||||||
for plugin in self._data:
|
for plugin in self._data:
|
||||||
if self.check_plugin_cd_status(plugin):
|
if self.check_plugin_cd_status(plugin):
|
||||||
self._freq_limiter[plugin] = FreqLimiter(
|
self._freq_limiter[plugin] = FreqLimiter(
|
||||||
self.get_plugin_cd_data(plugin)["cd"]
|
self.get_plugin_cd_data(plugin).cd
|
||||||
)
|
)
|
||||||
logger.info(f"已成功加载 {len(self._freq_limiter)} 个Cd限制.")
|
logger.info(f"已成功加载 {len(self._freq_limiter)} 个Cd限制.")
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
"""
|
"""
|
||||||
重载本地数据
|
说明:
|
||||||
|
重载本地数据
|
||||||
"""
|
"""
|
||||||
|
self.__load_file()
|
||||||
|
self.reload_cd_limit()
|
||||||
|
|
||||||
|
def save(self, path: Union[str, Path] = None):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
保存文件
|
||||||
|
参数:
|
||||||
|
:param path: 文件路径
|
||||||
|
"""
|
||||||
|
path = path or self.file
|
||||||
|
if isinstance(path, str):
|
||||||
|
path = Path(path)
|
||||||
|
if path:
|
||||||
|
with open(path, "w", encoding="utf8") as f:
|
||||||
|
yaml.dump(
|
||||||
|
{"PluginCdLimit": self.dict()},
|
||||||
|
f,
|
||||||
|
indent=2,
|
||||||
|
Dumper=yaml.RoundTripDumper,
|
||||||
|
allow_unicode=True,
|
||||||
|
)
|
||||||
|
_data = yaml.round_trip_load(open(path, encoding="utf8"))
|
||||||
|
_data["PluginCdLimit"].yaml_set_start_comment(
|
||||||
|
"""# 需要cd的功能
|
||||||
|
# 自定义的功能需要cd也可以在此配置
|
||||||
|
# key:模块名称
|
||||||
|
# cd:cd 时长(秒)
|
||||||
|
# status:此限制的开关状态
|
||||||
|
# check_type:'private'/'group'/'all',限制私聊/群聊/全部
|
||||||
|
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
||||||
|
# 示例:'user':用户N秒内触发1次,'group':群N秒内触发1次
|
||||||
|
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
|
||||||
|
# rst 为 "" 或 None 时则不回复
|
||||||
|
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
|
||||||
|
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
|
||||||
|
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
|
||||||
|
indent=2,
|
||||||
|
)
|
||||||
|
with open(path, "w", encoding="utf8") as wf:
|
||||||
|
yaml.round_trip_dump(
|
||||||
|
_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def __load_file(self):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
读取配置文件
|
||||||
|
"""
|
||||||
|
self._data: Dict[str, PluginCd] = {}
|
||||||
if self.file.exists():
|
if self.file.exists():
|
||||||
with open(self.file, "r", encoding="utf8") as f:
|
with open(self.file, "r", encoding="utf8") as f:
|
||||||
self._data: dict = yaml.load(f)
|
temp = _yaml.load(f)
|
||||||
self._data = self._data["PluginCdLimit"]
|
if "PluginCdLimit" in temp.keys():
|
||||||
self.reload_cd_limit()
|
for k, v in temp["PluginCdLimit"].items():
|
||||||
|
self._data[k] = PluginCd.parse_obj(v)
|
||||||
|
|||||||
156
utils/manager/plugins2count_manager.py
Executable file → Normal file
156
utils/manager/plugins2count_manager.py
Executable file → Normal file
@ -1,11 +1,12 @@
|
|||||||
from typing import Optional, Dict
|
from typing import Optional, Dict, Literal, Union
|
||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from utils.utils import DailyNumberLimiter
|
from utils.utils import DailyNumberLimiter
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
from ruamel import yaml
|
||||||
|
from .models import PluginCount
|
||||||
|
|
||||||
yaml = YAML(typ="safe")
|
_yaml = yaml.YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
class Plugins2countManager(StaticData):
|
class Plugins2countManager(StaticData):
|
||||||
@ -14,16 +15,9 @@ class Plugins2countManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Path):
|
def __init__(self, file: Path):
|
||||||
self.file = file
|
super().__init__(file, False)
|
||||||
super().__init__(None)
|
|
||||||
self._daily_limiter: Dict[str, DailyNumberLimiter] = {}
|
self._daily_limiter: Dict[str, DailyNumberLimiter] = {}
|
||||||
if file.exists():
|
self.__load_file()
|
||||||
with open(file, "r", encoding="utf8") as f:
|
|
||||||
self._data = yaml.load(f)
|
|
||||||
if "PluginCountLimit" in self._data.keys():
|
|
||||||
self._data = (
|
|
||||||
self._data["PluginCountLimit"] if self._data["PluginCountLimit"] else {}
|
|
||||||
)
|
|
||||||
|
|
||||||
def add_count_limit(
|
def add_count_limit(
|
||||||
self,
|
self,
|
||||||
@ -31,64 +25,64 @@ class Plugins2countManager(StaticData):
|
|||||||
*,
|
*,
|
||||||
max_count: int = 5,
|
max_count: int = 5,
|
||||||
status: Optional[bool] = True,
|
status: Optional[bool] = True,
|
||||||
limit_type: Optional[str] = "user",
|
limit_type: Literal["user", "group"] = "user",
|
||||||
rst: Optional[str] = None,
|
rst: Optional[str] = None,
|
||||||
**kwargs # 用于接收额外实参
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
添加插件调用 次数 限制
|
说明:
|
||||||
:param plugin: 插件模块名称
|
添加插件调用 次数 限制
|
||||||
:param max_count: 最大次数限制
|
参数:
|
||||||
:param status: 默认开关状态
|
:param plugin: 插件模块名称
|
||||||
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
:param max_count: 最大次数限制
|
||||||
:param rst: 回复的话,为空则不回复
|
:param status: 默认开关状态
|
||||||
|
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
||||||
|
:param rst: 回复的话,为空则不回复
|
||||||
"""
|
"""
|
||||||
max_count = max_count or 5
|
|
||||||
status = status or True
|
|
||||||
limit_type = limit_type or "user"
|
|
||||||
if limit_type not in ["user", "group"]:
|
if limit_type not in ["user", "group"]:
|
||||||
raise ValueError(f"{plugin} 添加count限制错误,‘limit_type‘ 必须为 'user'/'group'")
|
raise ValueError(f"{plugin} 添加count限制错误,‘limit_type‘ 必须为 'user'/'group'")
|
||||||
self._data[plugin] = {
|
self._data[plugin] = PluginCount(max_count=max_count, status=status, limit_type=limit_type, rst=rst)
|
||||||
"max_count": max_count,
|
|
||||||
"status": status,
|
|
||||||
"limit_type": limit_type,
|
|
||||||
"rst": rst,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_plugin_count_data(self, plugin: str) -> Optional[dict]:
|
def get_plugin_count_data(self, plugin: str) -> Optional[PluginCount]:
|
||||||
"""
|
"""
|
||||||
获取插件次数数据
|
说明:
|
||||||
:param plugin: 模块名
|
获取插件次数数据
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self.check_plugin_count_status(plugin):
|
if self.check_plugin_count_status(plugin):
|
||||||
return self._data[plugin]
|
return self._data[plugin]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_plugin_data(self, plugin: str) -> Optional[dict]:
|
def get_plugin_data(self, plugin: str) -> Optional[PluginCount]:
|
||||||
"""
|
"""
|
||||||
获取单个模块限制数据
|
说明:
|
||||||
:param plugin: 模块名
|
获取单个模块限制数据
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
if self._data.get(plugin) is not None:
|
if self._data.get(plugin) is not None:
|
||||||
return self._data.get(plugin)
|
return self._data.get(plugin)
|
||||||
return None
|
|
||||||
|
|
||||||
def check_plugin_count_status(self, plugin: str) -> bool:
|
def check_plugin_count_status(self, plugin: str) -> bool:
|
||||||
"""
|
"""
|
||||||
检测插件是否有 次数 限制
|
说明:
|
||||||
:param plugin: 模块名
|
检测插件是否有 次数 限制
|
||||||
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
plugin in self._data.keys()
|
plugin in self._data.keys()
|
||||||
and self._data[plugin]["status"]
|
and self._data[plugin].status
|
||||||
and self._data[plugin]["max_count"] > 0
|
and self._data[plugin].max_count > 0
|
||||||
)
|
)
|
||||||
|
|
||||||
def check(self, plugin: str, id_: int) -> bool:
|
def check(self, plugin: str, id_: int) -> bool:
|
||||||
"""
|
"""
|
||||||
检查 count
|
说明:
|
||||||
:param plugin: 模块名
|
检查 count
|
||||||
:param id_: 限制 id
|
参数:
|
||||||
|
:param plugin: 模块名
|
||||||
|
:param id_: 限制 id
|
||||||
"""
|
"""
|
||||||
if self._daily_limiter.get(plugin):
|
if self._daily_limiter.get(plugin):
|
||||||
return self._daily_limiter[plugin].check(id_)
|
return self._daily_limiter[plugin].check(id_)
|
||||||
@ -96,24 +90,25 @@ class Plugins2countManager(StaticData):
|
|||||||
|
|
||||||
def increase(self, plugin: str, id_: int, num: int = 1):
|
def increase(self, plugin: str, id_: int, num: int = 1):
|
||||||
"""
|
"""
|
||||||
增加次数
|
说明:
|
||||||
:param plugin: 模块名
|
增加次数
|
||||||
:param id_: cd 限制类型
|
参数:
|
||||||
:param num: 增加次数
|
:param plugin: 模块名
|
||||||
:return:
|
:param id_: cd 限制类型
|
||||||
|
:param num: 增加次数
|
||||||
"""
|
"""
|
||||||
if self._daily_limiter.get(plugin):
|
if self._daily_limiter.get(plugin):
|
||||||
self._daily_limiter[plugin].increase(id_, num)
|
self._daily_limiter[plugin].increase(id_, num)
|
||||||
|
|
||||||
def reload_count_limit(self):
|
def reload_count_limit(self):
|
||||||
"""
|
"""
|
||||||
加载 cd 限制器
|
说明:
|
||||||
:return:
|
加载 cd 限制器
|
||||||
"""
|
"""
|
||||||
for plugin in self._data:
|
for plugin in self._data:
|
||||||
if self.check_plugin_count_status(plugin):
|
if self.check_plugin_count_status(plugin):
|
||||||
self._daily_limiter[plugin] = DailyNumberLimiter(
|
self._daily_limiter[plugin] = DailyNumberLimiter(
|
||||||
self.get_plugin_count_data(plugin)["max_count"]
|
self.get_plugin_count_data(plugin).max_count
|
||||||
)
|
)
|
||||||
logger.info(f"已成功加载 {len(self._daily_limiter)} 个Count限制.")
|
logger.info(f"已成功加载 {len(self._daily_limiter)} 个Count限制.")
|
||||||
|
|
||||||
@ -121,8 +116,59 @@ class Plugins2countManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
重载本地数据
|
重载本地数据
|
||||||
"""
|
"""
|
||||||
|
self.__load_file()
|
||||||
|
self.reload_count_limit()
|
||||||
|
|
||||||
|
def save(self, path: Union[str, Path] = None):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
保存文件
|
||||||
|
参数:
|
||||||
|
:param path: 文件路径
|
||||||
|
"""
|
||||||
|
path = path or self.file
|
||||||
|
if isinstance(path, str):
|
||||||
|
path = Path(path)
|
||||||
|
if path:
|
||||||
|
with open(path, "w", encoding="utf8") as f:
|
||||||
|
yaml.dump(
|
||||||
|
{"PluginCountLimit": self.dict()},
|
||||||
|
f,
|
||||||
|
indent=2,
|
||||||
|
Dumper=yaml.RoundTripDumper,
|
||||||
|
allow_unicode=True,
|
||||||
|
)
|
||||||
|
_data = yaml.round_trip_load(open(path, encoding="utf8"))
|
||||||
|
_data["PluginCountLimit"].yaml_set_start_comment(
|
||||||
|
"""# 命令每日次数限制
|
||||||
|
# 即 用户/群聊 每日可调用命令的次数 [数据内存存储,重启将会重置]
|
||||||
|
# 每日调用直到 00:00 刷新
|
||||||
|
# key:模块名称
|
||||||
|
# max_count: 每日调用上限
|
||||||
|
# status:此限制的开关状态
|
||||||
|
# limit_type:监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
|
||||||
|
# 示例:'user':用户上限,'group':群聊上限
|
||||||
|
# rst:回复的话,可以添加[at],[uname],[nickname]来对应艾特,用户群名称,昵称系统昵称
|
||||||
|
# rst 为 "" 或 None 时则不回复
|
||||||
|
# rst示例:"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
|
||||||
|
# rst回复:"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
|
||||||
|
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
|
||||||
|
indent=2,
|
||||||
|
)
|
||||||
|
with open(path, "w", encoding="utf8") as wf:
|
||||||
|
yaml.round_trip_dump(
|
||||||
|
_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def __load_file(self):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
读取配置文件
|
||||||
|
"""
|
||||||
|
self._data: Dict[str, PluginCount] = {}
|
||||||
if self.file.exists():
|
if self.file.exists():
|
||||||
with open(self.file, "r", encoding="utf8") as f:
|
with open(self.file, "r", encoding="utf8") as f:
|
||||||
self._data: dict = yaml.load(f)
|
temp = _yaml.load(f)
|
||||||
self._data = self._data["PluginCountLimit"]
|
if "PluginCountLimit" in temp.keys():
|
||||||
self.reload_count_limit()
|
for k, v in temp["PluginCountLimit"].items():
|
||||||
|
self._data[k] = PluginCount.parse_obj(v)
|
||||||
|
|||||||
143
utils/manager/plugins2settings_manager.py
Executable file → Normal file
143
utils/manager/plugins2settings_manager.py
Executable file → Normal file
@ -1,11 +1,11 @@
|
|||||||
from typing import List, Optional, Union, Tuple
|
from typing import List, Optional, Union, Tuple, Dict
|
||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
|
||||||
from ruamel import yaml
|
from ruamel import yaml
|
||||||
|
from .models import PluginSetting
|
||||||
|
|
||||||
|
|
||||||
_yaml = YAML(typ="safe")
|
_yaml = yaml.YAML(typ="safe")
|
||||||
|
|
||||||
|
|
||||||
class Plugins2settingsManager(StaticData):
|
class Plugins2settingsManager(StaticData):
|
||||||
@ -14,97 +14,120 @@ class Plugins2settingsManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Path):
|
def __init__(self, file: Path):
|
||||||
self.file = file
|
super().__init__(file, False)
|
||||||
super().__init__(None)
|
self.__load_file()
|
||||||
if file.exists():
|
|
||||||
with open(file, "r", encoding="utf8") as f:
|
|
||||||
self._data = _yaml.load(f)
|
|
||||||
if self._data:
|
|
||||||
if "PluginSettings" in self._data.keys():
|
|
||||||
self._data = (
|
|
||||||
self._data["PluginSettings"] if self._data["PluginSettings"] else {}
|
|
||||||
)
|
|
||||||
for x in self._data.keys():
|
|
||||||
if self._data[x].get("cost_gold") is None:
|
|
||||||
self._data[x]["cost_gold"] = 0
|
|
||||||
|
|
||||||
def add_plugin_settings(
|
def add_plugin_settings(
|
||||||
self,
|
self,
|
||||||
plugin: str,
|
plugin: str,
|
||||||
cmd: Optional[List[str]] = None,
|
cmd: Optional[List[str]] = None,
|
||||||
default_status: Optional[bool] = True,
|
default_status: bool = True,
|
||||||
level: Optional[int] = 5,
|
level: int = 5,
|
||||||
limit_superuser: Optional[bool] = False,
|
limit_superuser: bool = False,
|
||||||
plugin_type: Tuple[Union[str, int]] = ("normal",),
|
plugin_type: Tuple[Union[str, int]] = ("normal",),
|
||||||
cost_gold: int = 0,
|
cost_gold: int = 0,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
添加一个插件设置
|
说明:
|
||||||
:param plugin: 插件模块名称
|
添加一个插件设置
|
||||||
:param cmd: 命令 或 命令别名
|
参数:
|
||||||
:param default_status: 默认开关状态
|
:param plugin: 插件模块名称
|
||||||
:param level: 功能权限等级
|
:param cmd: 命令 或 命令别名
|
||||||
:param limit_superuser: 功能状态是否限制超级用户
|
:param default_status: 默认开关状态
|
||||||
:param plugin_type: 插件类型
|
:param level: 功能权限等级
|
||||||
:param cost_gold: 需要消费的金币
|
:param limit_superuser: 功能状态是否限制超级用户
|
||||||
|
:param plugin_type: 插件类型
|
||||||
|
:param cost_gold: 需要消费的金币
|
||||||
"""
|
"""
|
||||||
level = level or 5
|
self._data[plugin] = PluginSetting(
|
||||||
cmd = cmd or []
|
cmd=cmd,
|
||||||
cost_gold = cost_gold or 0
|
level=level,
|
||||||
self._data[plugin] = {
|
default_status=default_status,
|
||||||
"level": level if level is not None else 5,
|
limit_superuser=limit_superuser,
|
||||||
"default_status": default_status if default_status is not None else True,
|
plugin_type=plugin_type,
|
||||||
"limit_superuser": (
|
cost_gold=cost_gold,
|
||||||
limit_superuser
|
)
|
||||||
if limit_superuser is not None
|
|
||||||
else False
|
|
||||||
),
|
|
||||||
"cmd": cmd,
|
|
||||||
"plugin_type": list(
|
|
||||||
plugin_type if plugin_type is not None else ("normal",)
|
|
||||||
),
|
|
||||||
"cost_gold": cost_gold,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_plugin_data(self, module: str) -> dict:
|
def get_plugin_data(self, module: str) -> Optional[PluginSetting]:
|
||||||
"""
|
"""
|
||||||
通过模块名获取数据
|
说明:
|
||||||
:param module: 模块名称
|
通过模块名获取数据
|
||||||
|
参数:
|
||||||
|
:param module: 模块名称
|
||||||
"""
|
"""
|
||||||
if self._data.get(module) is not None:
|
return self._data.get(module)
|
||||||
return self._data.get(module)
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def get_plugin_module(
|
def get_plugin_module(
|
||||||
self, cmd: str, is_all: bool = False
|
self, cmd: str, is_all: bool = False
|
||||||
) -> Union[str, List[str]]:
|
) -> Union[str, List[str]]:
|
||||||
"""
|
"""
|
||||||
根据 cmd 获取功能 modules
|
说明:
|
||||||
:param cmd: 命令
|
根据 cmd 获取功能 modules
|
||||||
:param is_all: 获取全部包含cmd的模块
|
参数:
|
||||||
|
:param cmd: 命令
|
||||||
|
:param is_all: 获取全部包含cmd的模块
|
||||||
"""
|
"""
|
||||||
keys = []
|
keys = []
|
||||||
for key in self._data.keys():
|
for key in self._data.keys():
|
||||||
if cmd in self._data[key]["cmd"]:
|
if cmd in self._data[key].cmd:
|
||||||
if is_all:
|
if is_all:
|
||||||
keys.append(key)
|
keys.append(key)
|
||||||
else:
|
else:
|
||||||
return key
|
return key
|
||||||
return keys
|
return keys
|
||||||
|
|
||||||
|
def reload(self):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
重载本地数据
|
||||||
|
"""
|
||||||
|
self.__load_file()
|
||||||
|
|
||||||
def save(self, path: Union[str, Path] = None):
|
def save(self, path: Union[str, Path] = None):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
保存文件
|
||||||
|
参数:
|
||||||
|
:param path: 文件路径
|
||||||
|
"""
|
||||||
path = path or self.file
|
path = path or self.file
|
||||||
if isinstance(path, str):
|
if isinstance(path, str):
|
||||||
path = Path(path)
|
path = Path(path)
|
||||||
if path:
|
if path:
|
||||||
with open(path, "w", encoding="utf8") as f:
|
with open(path, "w", encoding="utf8") as f:
|
||||||
yaml.dump({"PluginSettings": self._data}, f, indent=2, Dumper=yaml.RoundTripDumper, allow_unicode=True)
|
yaml.dump(
|
||||||
|
{"PluginSettings": self.dict()},
|
||||||
|
f,
|
||||||
|
indent=2,
|
||||||
|
Dumper=yaml.RoundTripDumper,
|
||||||
|
allow_unicode=True,
|
||||||
|
)
|
||||||
|
_data = yaml.round_trip_load(open(path, encoding="utf8"))
|
||||||
|
_data["PluginSettings"].yaml_set_start_comment(
|
||||||
|
"""# 模块与对应命令和对应群权限
|
||||||
|
# 用于生成帮助图片 和 开关功能
|
||||||
|
# key:模块名称
|
||||||
|
# level:需要的群等级
|
||||||
|
# default_status:加入群时功能的默认开关状态
|
||||||
|
# limit_superuser: 功能状态是否限制超级用户
|
||||||
|
# cmd: 关闭[cmd] 都会触发命令 关闭对应功能,cmd列表第一个词为统计的功能名称
|
||||||
|
# plugin_type: 帮助类别 示例:('原神相关',) 或 ('原神相关', 1),1代表帮助命令列向排列,否则为横向排列""",
|
||||||
|
indent=2,
|
||||||
|
)
|
||||||
|
with open(path, "w", encoding="utf8") as wf:
|
||||||
|
yaml.round_trip_dump(
|
||||||
|
_data, wf, Dumper=yaml.RoundTripDumper, allow_unicode=True
|
||||||
|
)
|
||||||
|
|
||||||
def reload(self):
|
def __load_file(self):
|
||||||
"""
|
"""
|
||||||
重载本地数据
|
说明:
|
||||||
|
读取配置文件
|
||||||
"""
|
"""
|
||||||
|
self._data: Dict[str, PluginSetting] = {}
|
||||||
if self.file.exists():
|
if self.file.exists():
|
||||||
with open(self.file, "r", encoding="utf8") as f:
|
with open(self.file, "r", encoding="utf8") as f:
|
||||||
self._data: dict = _yaml.load(f)
|
temp = _yaml.load(f)
|
||||||
self._data = self._data["PluginSettings"]
|
if "PluginSettings" in temp.keys():
|
||||||
|
for k, v in temp["PluginSettings"].items():
|
||||||
|
self._data[k] = PluginSetting.parse_obj(v)
|
||||||
|
|||||||
123
utils/manager/plugins_manager.py
Executable file → Normal file
123
utils/manager/plugins_manager.py
Executable file → Normal file
@ -1,7 +1,33 @@
|
|||||||
from typing import Optional
|
from typing import Optional, Dict, Callable, Union
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from . import group_manager
|
from utils.manager import group_manager
|
||||||
|
from .models import Plugin
|
||||||
|
|
||||||
|
|
||||||
|
def init_plugin(func: Callable):
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
初始化群数据
|
||||||
|
参数:
|
||||||
|
:param func: func
|
||||||
|
"""
|
||||||
|
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
self = args[0]
|
||||||
|
module = args[1]
|
||||||
|
if module not in self._data.keys():
|
||||||
|
self._data[module] = Plugin(
|
||||||
|
plugin_name=module,
|
||||||
|
status=True,
|
||||||
|
error=False,
|
||||||
|
block_type=None,
|
||||||
|
author=None,
|
||||||
|
version=None,
|
||||||
|
)
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class PluginsManager(StaticData):
|
class PluginsManager(StaticData):
|
||||||
@ -10,9 +36,10 @@ class PluginsManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, file: Path):
|
def __init__(self, file: Path):
|
||||||
|
self._data: Dict[str, Plugin]
|
||||||
super().__init__(file)
|
super().__init__(file)
|
||||||
if not self._data:
|
for k, v in self._data.items():
|
||||||
self._data = {}
|
self._data[k] = Plugin.parse_obj(v)
|
||||||
|
|
||||||
def add_plugin_data(
|
def add_plugin_data(
|
||||||
self,
|
self,
|
||||||
@ -26,23 +53,25 @@ class PluginsManager(StaticData):
|
|||||||
version: Optional[int] = None,
|
version: Optional[int] = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
添加插件数据
|
说明:
|
||||||
:param module: 模块名称
|
添加插件数据
|
||||||
:param plugin_name: 插件名称
|
参数:
|
||||||
:param status: 插件开关状态
|
:param module: 模块名称
|
||||||
:param error: 加载状态
|
:param plugin_name: 插件名称
|
||||||
:param block_type: 限制类型
|
:param status: 插件开关状态
|
||||||
:param author: 作者
|
:param error: 加载状态
|
||||||
:param version: 版本
|
:param block_type: 限制类型
|
||||||
|
:param author: 作者
|
||||||
|
:param version: 版本
|
||||||
"""
|
"""
|
||||||
self._data[module] = {
|
self._data[module] = Plugin(
|
||||||
"plugin_name": plugin_name,
|
plugin_name=plugin_name,
|
||||||
"status": status,
|
status=status,
|
||||||
"error": error,
|
error=error,
|
||||||
"block_type": block_type,
|
block_type=block_type,
|
||||||
"author": author,
|
author=author,
|
||||||
"version": version,
|
version=version,
|
||||||
}
|
)
|
||||||
|
|
||||||
def block_plugin(
|
def block_plugin(
|
||||||
self, module: str, group_id: Optional[int] = None, block_type: str = "all"
|
self, module: str, group_id: Optional[int] = None, block_type: str = "all"
|
||||||
@ -67,9 +96,7 @@ class PluginsManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
self._set_plugin_status(module, "unblock", group_id)
|
self._set_plugin_status(module, "unblock", group_id)
|
||||||
|
|
||||||
def get_plugin_status(
|
def get_plugin_status(self, module: str, block_type: str = "all") -> bool:
|
||||||
self, module: str, block_type: str = "all"
|
|
||||||
) -> bool:
|
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
获取插件状态
|
获取插件状态
|
||||||
@ -78,13 +105,12 @@ class PluginsManager(StaticData):
|
|||||||
:param block_type: 限制类型
|
:param block_type: 限制类型
|
||||||
"""
|
"""
|
||||||
if module in self._data.keys():
|
if module in self._data.keys():
|
||||||
if self._data[module]["block_type"] == "all" and block_type == "all":
|
if self._data[module].block_type == "all" and block_type == "all":
|
||||||
return False
|
return False
|
||||||
else:
|
return not self._data[module].block_type == block_type
|
||||||
return not self._data[module]["block_type"] == block_type
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_plugin_block_type(self, module: str) -> str:
|
def get_plugin_block_type(self, module: str) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
说明:
|
说明:
|
||||||
获取功能限制类型
|
获取功能限制类型
|
||||||
@ -92,18 +118,19 @@ class PluginsManager(StaticData):
|
|||||||
:param module: 模块名称
|
:param module: 模块名称
|
||||||
"""
|
"""
|
||||||
if module in self._data.keys():
|
if module in self._data.keys():
|
||||||
return self._data[module]["block_type"]
|
return self._data[module].block_type
|
||||||
return ""
|
|
||||||
|
|
||||||
|
@init_plugin
|
||||||
def get_plugin_error_status(self, module: str) -> bool:
|
def get_plugin_error_status(self, module: str) -> bool:
|
||||||
"""
|
"""
|
||||||
插件是否成功加载
|
说明:
|
||||||
:param module: 模块名称
|
插件是否成功加载
|
||||||
|
参数:
|
||||||
|
:param module: 模块名称
|
||||||
"""
|
"""
|
||||||
if module not in self._data.keys():
|
return self._data[module].error
|
||||||
self.init_plugin(module)
|
|
||||||
return self._data[module]["error"]
|
|
||||||
|
|
||||||
|
@init_plugin
|
||||||
def _set_plugin_status(
|
def _set_plugin_status(
|
||||||
self,
|
self,
|
||||||
module: str,
|
module: str,
|
||||||
@ -120,7 +147,6 @@ class PluginsManager(StaticData):
|
|||||||
:param group_id: 群组
|
:param group_id: 群组
|
||||||
:param block_type: 限制类型
|
:param block_type: 限制类型
|
||||||
"""
|
"""
|
||||||
group_id = str(group_id) if group_id else group_id
|
|
||||||
if module:
|
if module:
|
||||||
if group_id:
|
if group_id:
|
||||||
if status == "block":
|
if status == "block":
|
||||||
@ -128,28 +154,11 @@ class PluginsManager(StaticData):
|
|||||||
else:
|
else:
|
||||||
group_manager.unblock_plugin(f"{module}:super", int(group_id))
|
group_manager.unblock_plugin(f"{module}:super", int(group_id))
|
||||||
else:
|
else:
|
||||||
if module not in self._data.keys():
|
|
||||||
self.init_plugin(module)
|
|
||||||
if status == "block":
|
if status == "block":
|
||||||
self._data[module]["status"] = False
|
self._data[module].status = False
|
||||||
self._data[module]["block_type"] = block_type
|
self._data[module].block_type = block_type
|
||||||
else:
|
else:
|
||||||
if module in self._data.keys():
|
if module in self._data.keys():
|
||||||
self._data[module]["status"] = True
|
self._data[module].status = True
|
||||||
self._data[module]["block_type"] = None
|
self._data[module].block_type = None
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def init_plugin(self, module: str):
|
|
||||||
"""
|
|
||||||
初始化插件数据
|
|
||||||
:param module: 模块名称
|
|
||||||
"""
|
|
||||||
if module not in self._data.keys():
|
|
||||||
self._data[module] = {
|
|
||||||
"plugin_name": module,
|
|
||||||
"status": True,
|
|
||||||
"error": False,
|
|
||||||
"block_type": None,
|
|
||||||
"author": None,
|
|
||||||
"version": None,
|
|
||||||
}
|
|
||||||
|
|||||||
2
utils/manager/requests_manager.py
Executable file → Normal file
2
utils/manager/requests_manager.py
Executable file → Normal file
@ -1,7 +1,7 @@
|
|||||||
from utils.manager.data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from nonebot.adapters.onebot.v11 import Bot, ActionFailed
|
from nonebot.adapters.onebot.v11 import Bot, ActionFailed
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from typing import Optional, Literal
|
from typing import Optional
|
||||||
from utils.image_utils import BuildImage
|
from utils.image_utils import BuildImage
|
||||||
from utils.utils import get_user_avatar
|
from utils.utils import get_user_avatar
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|||||||
2
utils/manager/resources_manager.py
Executable file → Normal file
2
utils/manager/resources_manager.py
Executable file → Normal file
@ -1,7 +1,7 @@
|
|||||||
from typing import Union, List, Optional
|
from typing import Union, List, Optional
|
||||||
|
|
||||||
from configs.path_config import IMAGE_PATH, DATA_PATH, RECORD_PATH, TEXT_PATH, FONT_PATH, LOG_PATH
|
from configs.path_config import IMAGE_PATH, DATA_PATH, RECORD_PATH, TEXT_PATH, FONT_PATH, LOG_PATH
|
||||||
from .data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
from ruamel.yaml import YAML
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
|
|||||||
0
utils/manager/withdraw_message_manager.py
Executable file → Normal file
0
utils/manager/withdraw_message_manager.py
Executable file → Normal file
@ -450,4 +450,4 @@ def change_img_md5(path_file: Union[str, Path]) -> bool:
|
|||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"改变图片MD5发生错误 {type(e)}:{e} Path:{path_file}")
|
logger.warning(f"改变图片MD5发生错误 {type(e)}:{e} Path:{path_file}")
|
||||||
return False
|
return False
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user