Merge branch 'MaiM-with-u:main' into dev
commit
647855a076
|
|
@ -271,4 +271,5 @@ $RECYCLE.BIN/
|
||||||
|
|
||||||
config.toml
|
config.toml
|
||||||
config.toml.back
|
config.toml.back
|
||||||
test
|
test
|
||||||
|
data/qq_bot.json
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
|
|
@ -5,4 +5,6 @@ requests
|
||||||
maim_message
|
maim_message
|
||||||
loguru
|
loguru
|
||||||
pillow
|
pillow
|
||||||
tomli
|
tomli
|
||||||
|
tomlkit
|
||||||
|
rich
|
||||||
|
|
@ -61,6 +61,9 @@ class ChatConfig(ConfigBase):
|
||||||
ban_user_id: list[int] = field(default_factory=[])
|
ban_user_id: list[int] = field(default_factory=[])
|
||||||
"""被封禁的用户ID列表,封禁后将无法与其进行交互"""
|
"""被封禁的用户ID列表,封禁后将无法与其进行交互"""
|
||||||
|
|
||||||
|
ban_qq_bot: bool = False
|
||||||
|
"""是否屏蔽QQ官方机器人,若为True,则所有QQ官方机器人将无法与MaiMCore进行交互"""
|
||||||
|
|
||||||
enable_poke: bool = True
|
enable_poke: bool = True
|
||||||
"""是否启用戳一戳功能"""
|
"""是否启用戳一戳功能"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ from .utils import (
|
||||||
get_self_info,
|
get_self_info,
|
||||||
get_stranger_info,
|
get_stranger_info,
|
||||||
get_message_detail,
|
get_message_detail,
|
||||||
|
read_bot_id,
|
||||||
|
update_bot_id,
|
||||||
)
|
)
|
||||||
from .response_pool import get_response
|
from .response_pool import get_response
|
||||||
|
|
||||||
|
|
@ -38,6 +40,7 @@ class RecvHandler:
|
||||||
self.server_connection: Server.ServerConnection = None
|
self.server_connection: Server.ServerConnection = None
|
||||||
self.interval = global_config.napcat_server.heartbeat_interval
|
self.interval = global_config.napcat_server.heartbeat_interval
|
||||||
self._interval_checking = False
|
self._interval_checking = False
|
||||||
|
self.bot_id_list: Dict[int, bool] = {}
|
||||||
|
|
||||||
async def handle_meta_event(self, message: dict) -> None:
|
async def handle_meta_event(self, message: dict) -> None:
|
||||||
event_type = message.get("meta_event_type")
|
event_type = message.get("meta_event_type")
|
||||||
|
|
@ -69,7 +72,7 @@ class RecvHandler:
|
||||||
logger.debug("心跳正常")
|
logger.debug("心跳正常")
|
||||||
await asyncio.sleep(self.interval)
|
await asyncio.sleep(self.interval)
|
||||||
|
|
||||||
def check_allow_to_chat(self, user_id: int, group_id: Optional[int]) -> bool:
|
async def check_allow_to_chat(self, user_id: int, group_id: Optional[int]) -> bool:
|
||||||
# sourcery skip: hoist-statement-from-if, merge-else-if-into-elif
|
# sourcery skip: hoist-statement-from-if, merge-else-if-into-elif
|
||||||
"""
|
"""
|
||||||
检查是否允许聊天
|
检查是否允许聊天
|
||||||
|
|
@ -79,7 +82,33 @@ class RecvHandler:
|
||||||
Returns:
|
Returns:
|
||||||
bool: 是否允许聊天
|
bool: 是否允许聊天
|
||||||
"""
|
"""
|
||||||
|
user_id = str(user_id)
|
||||||
logger.debug(f"群聊id: {group_id}, 用户id: {user_id}")
|
logger.debug(f"群聊id: {group_id}, 用户id: {user_id}")
|
||||||
|
if global_config.chat.ban_qq_bot and group_id:
|
||||||
|
logger.debug("开始判断是否为机器人")
|
||||||
|
if not self.bot_id_list:
|
||||||
|
self.bot_id_list = read_bot_id()
|
||||||
|
if user_id in self.bot_id_list:
|
||||||
|
if self.bot_id_list[user_id]:
|
||||||
|
logger.warning("QQ官方机器人消息拦截已启用,消息被丢弃")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
member_info = await get_member_info(self.server_connection, group_id, user_id)
|
||||||
|
if member_info:
|
||||||
|
is_bot = member_info.get("is_robot")
|
||||||
|
if is_bot is None:
|
||||||
|
logger.warning("无法获取用户是否为机器人,默认为不是但是不进行更新")
|
||||||
|
else:
|
||||||
|
if is_bot:
|
||||||
|
logger.warning("QQ官方机器人消息拦截已启用,消息被丢弃,新机器人加入拦截名单")
|
||||||
|
self.bot_id_list[user_id] = True
|
||||||
|
update_bot_id(self.bot_id_list)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
self.bot_id_list[user_id] = False
|
||||||
|
update_bot_id(self.bot_id_list)
|
||||||
|
user_id = int(user_id)
|
||||||
|
logger.debug("开始检查聊天白名单/黑名单")
|
||||||
if group_id:
|
if group_id:
|
||||||
if global_config.chat.group_list_type == "whitelist" and group_id not in global_config.chat.group_list:
|
if global_config.chat.group_list_type == "whitelist" and group_id not in global_config.chat.group_list:
|
||||||
logger.warning("群聊不在聊天白名单中,消息被丢弃")
|
logger.warning("群聊不在聊天白名单中,消息被丢弃")
|
||||||
|
|
@ -122,7 +151,7 @@ class RecvHandler:
|
||||||
if sub_type == MessageType.Private.friend:
|
if sub_type == MessageType.Private.friend:
|
||||||
sender_info: dict = raw_message.get("sender")
|
sender_info: dict = raw_message.get("sender")
|
||||||
|
|
||||||
if not self.check_allow_to_chat(sender_info.get("user_id"), None):
|
if not await self.check_allow_to_chat(sender_info.get("user_id"), None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 发送者用户信息
|
# 发送者用户信息
|
||||||
|
|
@ -181,7 +210,7 @@ class RecvHandler:
|
||||||
if sub_type == MessageType.Group.normal:
|
if sub_type == MessageType.Group.normal:
|
||||||
sender_info: dict = raw_message.get("sender")
|
sender_info: dict = raw_message.get("sender")
|
||||||
|
|
||||||
if not self.check_allow_to_chat(sender_info.get("user_id"), raw_message.get("group_id")):
|
if not await self.check_allow_to_chat(sender_info.get("user_id"), raw_message.get("group_id")):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 发送者用户信息
|
# 发送者用户信息
|
||||||
|
|
@ -486,7 +515,7 @@ class RecvHandler:
|
||||||
user_id = raw_message.get("user_id")
|
user_id = raw_message.get("user_id")
|
||||||
target_id = raw_message.get("target_id")
|
target_id = raw_message.get("target_id")
|
||||||
|
|
||||||
if not self.check_allow_to_chat(user_id, group_id):
|
if not await self.check_allow_to_chat(user_id, group_id):
|
||||||
logger.warning("notice消息被丢弃")
|
logger.warning("notice消息被丢弃")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
||||||
44
src/utils.py
44
src/utils.py
|
|
@ -7,9 +7,10 @@ from .response_pool import get_response
|
||||||
|
|
||||||
import urllib3
|
import urllib3
|
||||||
import ssl
|
import ssl
|
||||||
|
from pathlib import Path
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
import io
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
class SSLAdapter(urllib3.PoolManager):
|
class SSLAdapter(urllib3.PoolManager):
|
||||||
|
|
@ -88,6 +89,7 @@ async def get_image_base64(url: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def convert_image_to_gif(image_base64: str) -> str:
|
def convert_image_to_gif(image_base64: str) -> str:
|
||||||
|
# sourcery skip: extract-method
|
||||||
"""
|
"""
|
||||||
将Base64编码的图片转换为GIF格式
|
将Base64编码的图片转换为GIF格式
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
@ -192,3 +194,43 @@ async def get_message_detail(websocket: Server.ServerConnection, message_id: str
|
||||||
return None
|
return None
|
||||||
logger.debug(response)
|
logger.debug(response)
|
||||||
return response.get("data")
|
return response.get("data")
|
||||||
|
|
||||||
|
|
||||||
|
def update_bot_id(data: dict) -> None:
|
||||||
|
"""
|
||||||
|
更新用户是否为机器人的字典到根目录下的data文件夹中的qq_bot.json。
|
||||||
|
Parameters:
|
||||||
|
data: dict: 包含需要更新的信息。
|
||||||
|
"""
|
||||||
|
json_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "qq_bot.json")
|
||||||
|
try:
|
||||||
|
with open(json_path, "w", encoding="utf-8") as json_file:
|
||||||
|
json.dump(data, json_file, ensure_ascii=False, indent=4)
|
||||||
|
logger.info(f"ID字典已更新到文件: {json_path}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"更新ID字典失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def read_bot_id() -> dict:
|
||||||
|
"""
|
||||||
|
从根目录下的data文件夹中的文件读取机器人ID。
|
||||||
|
Returns:
|
||||||
|
list: 读取的机器人ID信息。
|
||||||
|
"""
|
||||||
|
json_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "qq_bot.json")
|
||||||
|
try:
|
||||||
|
with open(json_path, "r", encoding="utf-8") as json_file:
|
||||||
|
data = json.load(json_file)
|
||||||
|
logger.info(f"已读取机器人ID信息: {data}")
|
||||||
|
return data
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.warning(f"文件未找到: {json_path},正在自动创建文件")
|
||||||
|
json_path = Path(os.path.dirname(os.path.dirname(__file__))) / "data" / "qq_bot.json"
|
||||||
|
# 确保父目录存在
|
||||||
|
json_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
# 创建空文件
|
||||||
|
json_path.touch(exist_ok=True)
|
||||||
|
return {}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"读取机器人ID失败: {e}")
|
||||||
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[inner]
|
[inner]
|
||||||
version = "0.1.0" # 版本号
|
version = "0.1.1" # 版本号
|
||||||
# 请勿修改版本号,除非你知道自己在做什么
|
# 请勿修改版本号,除非你知道自己在做什么
|
||||||
|
|
||||||
[nickname] # 现在没用
|
[nickname] # 现在没用
|
||||||
|
|
@ -24,6 +24,7 @@ private_list = [] # 私聊名单
|
||||||
# 当private_list_type为whitelist时,只有私聊名单中的用户可以聊天
|
# 当private_list_type为whitelist时,只有私聊名单中的用户可以聊天
|
||||||
# 当private_list_type为blacklist时,私聊名单中的任何用户无法聊天
|
# 当private_list_type为blacklist时,私聊名单中的任何用户无法聊天
|
||||||
ban_user_id = [] # 全局禁止名单(全局禁止名单中的用户无法进行任何聊天)
|
ban_user_id = [] # 全局禁止名单(全局禁止名单中的用户无法进行任何聊天)
|
||||||
|
ban_qq_bot = false # 是否屏蔽QQ官方机器人
|
||||||
enable_poke = true # 是否启用戳一戳功能
|
enable_poke = true # 是否启用戳一戳功能
|
||||||
|
|
||||||
[voice] # 发送语音设置
|
[voice] # 发送语音设置
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue