From c49ef3052fd031f3c72ab40bc6bf0c7f066907d4 Mon Sep 17 00:00:00 2001 From: HibiKier <775757368@qq.com> Date: Mon, 26 Dec 2022 18:40:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=85=A8=E5=B1=80=E8=A2=AB?= =?UTF-8?q?=E5=8A=A8=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../admin_bot_manage/_data_source.py | 71 +++++++++++++-- basic_plugins/admin_bot_manage/rule.py | 2 + basic_plugins/admin_bot_manage/switch_rule.py | 15 ++-- basic_plugins/hooks/task_hook.py | 73 +++++++-------- basic_plugins/super_help/data_source.py | 2 +- plugins/epic/__init__.py | 2 +- plugins/word_bank/word_handle.py | 8 +- utils/manager/group_manager.py | 89 ++++++++++++++++--- utils/manager/models.py | 1 + utils/manager/plugins_manager.py | 25 +++--- 11 files changed, 213 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index a5717045..45c35cf8 100644 --- a/README.md +++ b/README.md @@ -299,6 +299,8 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能 ### 2022/12/26 * 优化`gamedraw`插件 +* 提供全局被动控制 +* 群被动状态改为图片 ## 2022/12/24 diff --git a/basic_plugins/admin_bot_manage/_data_source.py b/basic_plugins/admin_bot_manage/_data_source.py index a6ee41c2..50a56879 100644 --- a/basic_plugins/admin_bot_manage/_data_source.py +++ b/basic_plugins/admin_bot_manage/_data_source.py @@ -1,7 +1,7 @@ from typing import List from nonebot.adapters.onebot.v11.message import MessageSegment from services.log import logger -from configs.path_config import DATA_PATH +from configs.path_config import DATA_PATH, IMAGE_PATH from utils.message_builder import image from utils.utils import get_bot, get_matchers from pathlib import Path @@ -23,8 +23,10 @@ custom_welcome_msg_json = ( Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json" ) +ICON_PATH = IMAGE_PATH / 'other' -def group_current_status(group_id: int) -> str: + +async def group_current_status(group_id: int) -> str: """ 说明: 获取当前群聊所有通知的开关 @@ -32,12 +34,33 @@ def group_current_status(group_id: int) -> str: :param group_id: 群号 """ _data = group_manager.get_task_data() - return "[被动技能 状态]\n" + "\n".join( - [ - f'{_data[task]}: {"√" if group_manager.check_group_task_status(group_id, task) else "×"}\n' - for task in _data - ] - ) + image_list = [] + for i, task in enumerate(_data): + name = _data[task] + name_image = BuildImage(0, 0, plain_text=f"{i+1}.{name}", font_size=20) + bk = BuildImage(name_image.w + 200, name_image.h + 20, color=(103, 177, 109), font_size=15) + await bk.apaste(name_image, (10, 0), True, "by_height") + a_icon = BuildImage(40, 40, background=ICON_PATH / "btn_false.png") + if group_manager.check_group_task_status(group_id, task): + a_icon = BuildImage(40, 40, background=ICON_PATH / "btn_true.png") + b_icon = BuildImage(40, 40, background=ICON_PATH / "btn_false.png") + if group_manager.check_task_super_status(task): + b_icon = BuildImage(40, 40, background=ICON_PATH / "btn_true.png") + await bk.atext((name_image.w + 20, 10), "状态") + await bk.apaste(a_icon, (name_image.w + 50, 0), True) + await bk.atext((name_image.w + 100, 10), "全局") + await bk.apaste(b_icon, (name_image.w + 130, 0), True) + image_list.append(bk) + w = max([x.w for x in image_list]) + h = sum([x.h + 10 for x in image_list]) + A = BuildImage(w + 20, h + 70, font_size=30, color=(119, 97, 177)) + await A.atext((15, 20), "群被动状态") + curr_h = 75 + for img in image_list: + # await img.acircle_corner() + await A.apaste(img, (0, curr_h), True) + curr_h += img.h + 10 + return A.pic2bs4() async def custom_group_welcome( @@ -88,6 +111,38 @@ async def custom_group_welcome( task_data = None +def change_global_task_status(cmd: str) -> str: + """ + 说明: + 修改全局被动任务状态 + 参数: + :param cmd: 功能名称 + """ + global task_data + if not task_data: + task_data = group_manager.get_task_data() + status = cmd[:2] + _cmd = cmd[4:] + if '全部被动' in cmd: + for task in task_data: + if status == "开启": + group_manager.open_global_task(task) + else: + group_manager.close_global_task(task) + group_manager.save() + return f"已 {status} 全局全部被动技能!" + else: + modules = [x for x in task_data if task_data[x].lower() == _cmd.lower()] + if not modules: + return '未查询到该被动任务' + if status == "开启": + group_manager.open_global_task(modules[0]) + else: + group_manager.close_global_task(modules[0]) + group_manager.save() + return f"已 {status} 全局{_cmd}" + + async def change_group_switch(cmd: str, group_id: int, is_super: bool = False) -> str: """ 说明: diff --git a/basic_plugins/admin_bot_manage/rule.py b/basic_plugins/admin_bot_manage/rule.py index bdce468b..e53cf6ae 100755 --- a/basic_plugins/admin_bot_manage/rule.py +++ b/basic_plugins/admin_bot_manage/rule.py @@ -24,6 +24,8 @@ def switch_rule(event: Event) -> bool: for key in _data: cmd.append(f"开启{_data[key]}") cmd.append(f"关闭{_data[key]}") + 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() diff --git a/basic_plugins/admin_bot_manage/switch_rule.py b/basic_plugins/admin_bot_manage/switch_rule.py index ea9a8054..b909af25 100755 --- a/basic_plugins/admin_bot_manage/switch_rule.py +++ b/basic_plugins/admin_bot_manage/switch_rule.py @@ -1,12 +1,14 @@ -from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent, GROUP +from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent, GROUP, PrivateMessageEvent from nonebot import on_command, on_message, on_regex from nonebot.params import RegexGroup + +from utils.message_builder import image from ._data_source import ( change_group_switch, set_plugin_status, get_plugin_status, group_current_status, - set_group_bot_status + set_group_bot_status, change_global_task_status ) from services.log import logger from configs.config import NICKNAME, Config @@ -31,11 +33,12 @@ usage: """.strip() __plugin_superuser_usage__ = """ usage: - 功能总开关与指定群禁用 + (私聊)功能总开关与指定群禁用 指令: 功能状态 开启/关闭[功能] [group] 开启/关闭[功能] ['private'/'group'] + 开启被动/关闭被动[被动名称] # 全局被动控制 """.strip() __plugin_des__ = "群内功能开关" __plugin_cmd__ = [ @@ -74,7 +77,9 @@ async def _(bot: Bot, event: MessageEvent): if str(event.user_id) in bot.config.superusers: block_type = " ".join(get_message_text(event.json()).split()[1:]) block_type = block_type if block_type else "a" - if is_number(block_type): + if ("关闭被动" in _cmd or "开启被动" in _cmd) and isinstance(event, PrivateMessageEvent): + await switch_rule_matcher.send(change_global_task_status(_cmd)) + elif is_number(block_type): if not int(block_type) in [ g["group_id"] for g in await bot.get_group_list() @@ -110,7 +115,7 @@ async def _(): @group_task_status.handle() async def _(event: GroupMessageEvent): - await group_task_status.send(group_current_status(event.group_id)) + await group_task_status.send(image(b64=await group_current_status(event.group_id))) @group_status.handle() diff --git a/basic_plugins/hooks/task_hook.py b/basic_plugins/hooks/task_hook.py index 308a5248..6675e86d 100644 --- a/basic_plugins/hooks/task_hook.py +++ b/basic_plugins/hooks/task_hook.py @@ -1,6 +1,7 @@ from nonebot.exception import MockApiException from nonebot.adapters.onebot.v11 import Bot, Message from utils.manager import group_manager +from services.log import logger from typing import Dict, Any import re @@ -8,42 +9,44 @@ import re @Bot.on_calling_api async def _(bot: Bot, api: str, data: Dict[str, Any]): r = None - if ( - ( - (api == "send_msg" and data.get("message_type") == "group") - or api == "send_group_msg" - ) - and ( + try: + if ( ( - r := re.search( - "^\[\[_task\|(.*)]]", - data["message"].strip() - if isinstance(data["message"], str) - else str(data["message"]["text"]).strip(), + (api == "send_msg" and data.get("message_type") == "group") + or api == "send_group_msg" + ) + and ( + ( + r := re.search( + "^\[\[_task\|(.*)]]", + data["message"].strip() + if isinstance(data["message"], str) + else str(data["message"]["text"]).strip(), + ) + ) + or ( + r := re.search( + "^[[_task\|(.*)]]", + data["message"].strip() + if isinstance(data["message"], str) + else str(data["message"]["text"]).strip(), + ) ) ) - or ( - r := re.search( - "^[[_task\|(.*)]]", - data["message"].strip() - if isinstance(data["message"], str) - else str(data["message"]["text"]).strip(), + and r.group(1) in group_manager.get_task_data().keys() + ): + task = r.group(1) + group_id = data["group_id"] + if ( + group_manager.get_group_level(group_id) < 0 + or not group_manager.check_task_status(task, group_id) + ): + raise MockApiException(f"被动技能 {task} 处于关闭状态...") + else: + msg = str(data["message"]).strip() + msg = msg.replace(f"[[_task|{task}]]", "").replace( + f"[[_task|{task}]]", "" ) - ) - ) - and r.group(1) in group_manager.get_task_data().keys() - ): - # if bot.self_id in bot.config.superusers: - # raise MockApiException(f"禁止社死...") - task = r.group(1) - group_id = data["group_id"] - if group_manager.get_group_level( - group_id - ) < 0 or not group_manager.check_group_task_status(group_id, task): - raise MockApiException(f"被动技能 {task} 处于关闭状态...") - else: - msg = str(data["message"]).strip() - msg = msg.replace(f"[[_task|{task}]]", "").replace( - f"[[_task|{task}]]", "" - ) - data["message"] = Message(msg) + data["message"] = Message(msg) + except Exception as e: + logger.error(f"TaskHook ERROR {type(e)}:{e}") diff --git a/basic_plugins/super_help/data_source.py b/basic_plugins/super_help/data_source.py index 3aa47451..6f22253e 100755 --- a/basic_plugins/super_help/data_source.py +++ b/basic_plugins/super_help/data_source.py @@ -55,7 +55,7 @@ async def create_help_image(): f"获取超级用户插件 {plugin_data.model}: {plugin_data.name} 设置失败... {type(e)}:{e}" ) task_str = "\n".join(task_list) - task_str = "通过 开启/关闭 来控制全局被动\n----------\n" + task_str + task_str = "通过私聊 开启被动/关闭被动 + [被动名称] 来控制全局被动\n----------\n" + task_str task_image = await text2image( task_str, padding=5, color=(204, 196, 151) ) diff --git a/plugins/epic/__init__.py b/plugins/epic/__init__.py index db094e34..62cb170d 100755 --- a/plugins/epic/__init__.py +++ b/plugins/epic/__init__.py @@ -67,7 +67,7 @@ async def _(): gl = [g["group_id"] for g in gl] msg_list, code = await get_epic_free(bot, "Group") for g in gl: - if group_manager.check_group_task_status(g, "epic_free_game"): + if group_manager.check_task_status("epic_free_game", g): try: if msg_list and code == 200: await bot.send_group_forward_msg(group_id=g, messages=msg_list) diff --git a/plugins/word_bank/word_handle.py b/plugins/word_bank/word_handle.py index 10e50e83..a56d4d91 100644 --- a/plugins/word_bank/word_handle.py +++ b/plugins/word_bank/word_handle.py @@ -54,7 +54,7 @@ usage: 私聊添加词条 (私聊情况下)删除词条: 删除私聊词条 (私聊情况下)删除全局词条 - (私聊情况下)修改词条: 修改词条私聊词条 + (私聊情况下)修改词条: 修改私聊词条 (私聊情况下)修改全局词条 用法与普通用法相同 """.strip() @@ -96,6 +96,8 @@ async def _( if isinstance(event, PrivateMessageEvent) and str(event.user_id) not in bot.config.superusers: await add_word.finish('权限不足捏') word_scope, word_type, problem, answer = reg_group + if not word_scope and isinstance(event, PrivateMessageEvent): + word_scope = '私聊' if ( word_scope and word_scope in ["全局", "私聊"] @@ -153,8 +155,8 @@ async def _( re.compile(problem) except re.error: await add_word.finish(f"添加词条失败,正则表达式 {problem} 非法!") - if str(event.user_id) in bot.config.superusers and isinstance(event, PrivateMessageEvent): - word_scope = "私聊" + # if str(event.user_id) in bot.config.superusers and isinstance(event, PrivateMessageEvent): + # word_scope = "私聊" nickname = None if problem and bot.config.nickname: nickname = [nk for nk in bot.config.nickname if problem.startswith(nk)] diff --git a/utils/manager/group_manager.py b/utils/manager/group_manager.py index b522dd8b..e29ffe5e 100644 --- a/utils/manager/group_manager.py +++ b/utils/manager/group_manager.py @@ -1,5 +1,5 @@ import copy -from typing import List, Union, Dict, Callable, Any +from typing import List, Union, Dict, Callable, Any, Optional from pathlib import Path from .models import BaseData, BaseGroup from utils.manager.data_class import StaticData @@ -14,7 +14,11 @@ Config.add_plugin_config( ) Config.add_plugin_config( - "group_manager", "DEFAULT_GROUP_BOT_STATUS", True, help_="默认进群总开关状态", default_value=True + "group_manager", + "DEFAULT_GROUP_BOT_STATUS", + True, + help_="默认进群总开关状态", + default_value=True, ) @@ -25,12 +29,14 @@ 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 @@ -41,19 +47,30 @@ 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: + 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) + 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 @@ -150,7 +167,10 @@ class GroupManager(StaticData[BaseData]): :param module: 功能模块名 :param group_id: 群组 """ - return f"{module}:super" not in self._data.group_manager[str(group_id)].close_plugins + return ( + f"{module}:super" + not in self._data.group_manager[str(group_id)].close_plugins + ) @init_group def get_group_level(self, group_id: int) -> int: @@ -237,6 +257,26 @@ class GroupManager(StaticData[BaseData]): """ self._set_group_group_task_status(group_id, task, True) + def close_global_task(self, task: str): + """ + 说明: + 关闭全局被动技能 + 参数: + :param task: 被动技能名称 + """ + if task not in self._data.close_task: + self._data.close_task.append(task) + + def open_global_task(self, task: str): + """ + 说明: + 开启全局被动技能 + 参数: + :param task: 被动技能名称 + """ + if task in self._data.close_task: + self._data.close_task.remove(task) + def close_group_task(self, group_id: int, task: str): """ 说明: @@ -247,6 +287,21 @@ class GroupManager(StaticData[BaseData]): """ self._set_group_group_task_status(group_id, task, False) + def check_task_status(self, task: str, group_id: Optional[int] = None) -> bool: + """ + 说明: + 检查该被动状态 + 参数: + :param task: 被动技能名称 + :param group_id: 群号 + """ + if group_id: + return self.check_group_task_status( + group_id, task + ) and self.check_task_super_status(task) + return self.check_task_super_status(task) + + @init_group @init_task def check_group_task_status(self, group_id: int, task: str) -> bool: """ @@ -256,7 +311,18 @@ class GroupManager(StaticData[BaseData]): :param group_id: 群号 :param task: 被动技能名称 """ - return self._data.group_manager[str(group_id)].group_task_status.get(task, False) + return self._data.group_manager[str(group_id)].group_task_status.get( + task, False + ) + + def check_task_super_status(self, task: str) -> bool: + """ + 说明: + 查看群被动技能状态(超级用户设置的状态) + 参数: + :param task: 被动技能名称 + """ + return task not in self._data.close_task def get_task_data(self) -> Dict[str, str]: """ @@ -265,6 +331,7 @@ class GroupManager(StaticData[BaseData]): """ return self._data.task + @init_group @init_task def group_group_task_status(self, group_id: int) -> str: """ @@ -279,8 +346,8 @@ class GroupManager(StaticData[BaseData]): x += f'{self._data.task[key]}:{"√" if self.check_group_task_status(int(group_id), key) else "×"}\n' return x[:-1] - @init_task @init_group + @init_task def _set_group_group_task_status(self, group_id: int, task: str, status: bool): """ 说明: @@ -295,11 +362,7 @@ class GroupManager(StaticData[BaseData]): @init_group def _set_plugin_status( - self, - module: str, - status: str, - group_id: int, - is_save: bool + self, module: str, status: str, group_id: int, is_save: bool ): """ 说明: diff --git a/utils/manager/models.py b/utils/manager/models.py index ae7da83f..d3cd88c9 100644 --- a/utils/manager/models.py +++ b/utils/manager/models.py @@ -33,6 +33,7 @@ class BaseData(BaseModel): """ white_group: List[int] = [] # 白名单 + close_task: List[str] = [] # 全局关闭的被动任务 group_manager: Dict[str, BaseGroup] = {} # 群组管理 task: Dict[str, str] = {} # 被动任务 【英文:中文】 diff --git a/utils/manager/plugins_manager.py b/utils/manager/plugins_manager.py index 909374cf..e67b6a33 100644 --- a/utils/manager/plugins_manager.py +++ b/utils/manager/plugins_manager.py @@ -14,17 +14,20 @@ def init_plugin(func: Callable): """ 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, - ) + try: + 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, + ) + except Exception as e: + pass return func(*args, **kwargs) return wrapper