mirror of https://github.com/Mai-with-u/MaiBot.git
添加私聊功能,通过在群白名单中添加群号"0"开启
parent
0f5f1c920d
commit
77311a1125
|
|
@ -5,7 +5,7 @@ import time
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from nonebot import get_driver, on_command, on_message, require
|
from nonebot import get_driver, on_command, on_message, require
|
||||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageSegment
|
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageSegment,MessageEvent
|
||||||
from nonebot.rule import to_me
|
from nonebot.rule import to_me
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ async def _(bot: Bot):
|
||||||
print("\033[1;38;5;208m-----------开始偷表情包!-----------\033[0m")
|
print("\033[1;38;5;208m-----------开始偷表情包!-----------\033[0m")
|
||||||
|
|
||||||
@group_msg.handle()
|
@group_msg.handle()
|
||||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||||
await chat_bot.handle_message(event, bot)
|
await chat_bot.handle_message(event, bot)
|
||||||
|
|
||||||
# 添加build_memory定时任务
|
# 添加build_memory定时任务
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import time
|
||||||
from random import random
|
from random import random
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent
|
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, PrivateMessageEvent,MessageEvent
|
||||||
|
|
||||||
from ..memory_system.memory import hippocampus
|
from ..memory_system.memory import hippocampus
|
||||||
from ..moods.moods import MoodManager # 导入情绪管理器
|
from ..moods.moods import MoodManager # 导入情绪管理器
|
||||||
|
|
@ -40,8 +40,12 @@ class ChatBot:
|
||||||
if not self._started:
|
if not self._started:
|
||||||
self._started = True
|
self._started = True
|
||||||
|
|
||||||
async def handle_message(self, event: GroupMessageEvent, bot: Bot) -> None:
|
async def handle_message(self, event: MessageEvent, bot: Bot) -> None:
|
||||||
"""处理收到的群消息"""
|
"""处理收到的消息"""
|
||||||
|
|
||||||
|
# 私聊消息接口
|
||||||
|
if isinstance(event, PrivateMessageEvent):
|
||||||
|
event.group_id = 0
|
||||||
|
|
||||||
if event.group_id not in global_config.talk_allowed_groups:
|
if event.group_id not in global_config.talk_allowed_groups:
|
||||||
return
|
return
|
||||||
|
|
@ -50,17 +54,36 @@ class ChatBot:
|
||||||
if event.user_id in global_config.ban_user_id:
|
if event.user_id in global_config.ban_user_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
group_info = await bot.get_group_info(group_id=event.group_id)
|
if isinstance(event, GroupMessageEvent):
|
||||||
sender_info = await bot.get_group_member_info(group_id=event.group_id, user_id=event.user_id, no_cache=True)
|
group_info = await bot.get_group_info(
|
||||||
|
group_id=event.group_id, no_cache=True
|
||||||
|
)
|
||||||
|
sender_info = await bot.get_group_member_info(
|
||||||
|
group_id=event.group_id, user_id=event.user_id, no_cache=True
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
group_info = {"group_name": "私聊"}
|
||||||
|
sender_info = {
|
||||||
|
"user_id": event.user_id,
|
||||||
|
"nickname": (
|
||||||
|
await bot.get_stranger_info(user_id=event.user_id, no_cache=True)
|
||||||
|
)["nickname"],
|
||||||
|
"card": None,
|
||||||
|
}
|
||||||
|
|
||||||
await relationship_manager.update_relationship(user_id = event.user_id, data = sender_info)
|
|
||||||
await relationship_manager.update_relationship_value(user_id = event.user_id, relationship_value = 0.5)
|
await relationship_manager.update_relationship(
|
||||||
|
user_id=event.user_id, data=sender_info
|
||||||
|
)
|
||||||
|
await relationship_manager.update_relationship_value(
|
||||||
|
user_id=event.user_id, relationship_value=0.5
|
||||||
|
)
|
||||||
|
|
||||||
message = Message(
|
message = Message(
|
||||||
group_id=event.group_id,
|
group_id=event.group_id,
|
||||||
user_id=event.user_id,
|
user_id=event.user_id,
|
||||||
message_id=event.message_id,
|
message_id=event.message_id,
|
||||||
user_cardname=sender_info['card'],
|
user_cardname=sender_info["card"],
|
||||||
raw_message=str(event.original_message),
|
raw_message=str(event.original_message),
|
||||||
plain_text=event.get_plaintext(),
|
plain_text=event.get_plaintext(),
|
||||||
reply_message=event.reply,
|
reply_message=event.reply,
|
||||||
|
|
@ -70,19 +93,23 @@ class ChatBot:
|
||||||
# 过滤词
|
# 过滤词
|
||||||
for word in global_config.ban_words:
|
for word in global_config.ban_words:
|
||||||
if word in message.detailed_plain_text:
|
if word in message.detailed_plain_text:
|
||||||
logger.info(f"\033[1;32m[{message.group_name}]{message.user_nickname}:\033[0m {message.processed_plain_text}")
|
logger.info(
|
||||||
|
f"\033[1;32m[{group_info['group_name']}]{message.user_nickname}:\033[0m {message.processed_plain_text}"
|
||||||
|
)
|
||||||
logger.info(f"\033[1;32m[过滤词识别]\033[0m 消息中含有{word},filtered")
|
logger.info(f"\033[1;32m[过滤词识别]\033[0m 消息中含有{word},filtered")
|
||||||
return
|
return
|
||||||
|
|
||||||
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(message.time))
|
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(message.time))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# topic=await topic_identifier.identify_topic_llm(message.processed_plain_text)
|
# topic=await topic_identifier.identify_topic_llm(message.processed_plain_text)
|
||||||
topic = ''
|
topic = ""
|
||||||
interested_rate = 0
|
interested_rate = 0
|
||||||
interested_rate = await hippocampus.memory_activate_value(message.processed_plain_text)/100
|
interested_rate = (
|
||||||
print(f"\033[1;32m[记忆激活]\033[0m 对{message.processed_plain_text}的激活度:---------------------------------------{interested_rate}\n")
|
await hippocampus.memory_activate_value(message.processed_plain_text) / 100
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f"\033[1;32m[记忆激活]\033[0m 对{message.processed_plain_text}的激活度:---------------------------------------{interested_rate}\n"
|
||||||
|
)
|
||||||
# logger.info(f"\033[1;32m[主题识别]\033[0m 使用{global_config.topic_extract}主题: {topic}")
|
# logger.info(f"\033[1;32m[主题识别]\033[0m 使用{global_config.topic_extract}主题: {topic}")
|
||||||
|
|
||||||
await self.storage.store_message(message, topic[0] if topic else None)
|
await self.storage.store_message(message, topic[0] if topic else None)
|
||||||
|
|
@ -95,27 +122,27 @@ class ChatBot:
|
||||||
global_config,
|
global_config,
|
||||||
event.user_id,
|
event.user_id,
|
||||||
message.is_emoji,
|
message.is_emoji,
|
||||||
interested_rate
|
interested_rate,
|
||||||
)
|
)
|
||||||
current_willing = willing_manager.get_willing(event.group_id)
|
current_willing = willing_manager.get_willing(event.group_id)
|
||||||
|
|
||||||
|
print(
|
||||||
print(f"\033[1;32m[{current_time}][{message.group_name}]{message.user_nickname}:\033[0m {message.processed_plain_text}\033[1;36m[回复意愿:{current_willing:.2f}][概率:{reply_probability * 100:.1f}%]\033[0m")
|
f"\033[1;32m[{current_time}][{message.group_name}]{message.user_nickname}:\033[0m {message.processed_plain_text}\033[1;36m[回复意愿:{current_willing:.2f}][概率:{reply_probability * 100:.1f}%]\033[0m"
|
||||||
|
)
|
||||||
|
|
||||||
response = ""
|
response = ""
|
||||||
|
|
||||||
if random() < reply_probability:
|
if random() < reply_probability:
|
||||||
|
|
||||||
|
|
||||||
tinking_time_point = round(time.time(), 2)
|
tinking_time_point = round(time.time(), 2)
|
||||||
think_id = 'mt' + str(tinking_time_point)
|
think_id = "mt" + str(tinking_time_point)
|
||||||
thinking_message = Message_Thinking(message=message,message_id=think_id)
|
thinking_message = Message_Thinking(message=message, message_id=think_id)
|
||||||
|
|
||||||
message_manager.add_message(thinking_message)
|
message_manager.add_message(thinking_message)
|
||||||
|
|
||||||
willing_manager.change_reply_willing_sent(thinking_message.group_id)
|
willing_manager.change_reply_willing_sent(thinking_message.group_id)
|
||||||
|
|
||||||
response,raw_content = await self.gpt.generate_response(message)
|
response, raw_content = await self.gpt.generate_response(message)
|
||||||
|
|
||||||
if response:
|
if response:
|
||||||
container = message_manager.get_container(event.group_id)
|
container = message_manager.get_container(event.group_id)
|
||||||
|
|
@ -133,17 +160,19 @@ class ChatBot:
|
||||||
print(f"\033[1;33m[警告]\033[0m 未找到对应的思考消息,可能已超时被移除")
|
print(f"\033[1;33m[警告]\033[0m 未找到对应的思考消息,可能已超时被移除")
|
||||||
return
|
return
|
||||||
|
|
||||||
#记录开始思考的时间,避免从思考到回复的时间太久
|
# 记录开始思考的时间,避免从思考到回复的时间太久
|
||||||
thinking_start_time = thinking_message.thinking_start_time
|
thinking_start_time = thinking_message.thinking_start_time
|
||||||
message_set = MessageSet(event.group_id, global_config.BOT_QQ, think_id) # 发送消息的id和产生发送消息的message_thinking是一致的
|
message_set = MessageSet(
|
||||||
#计算打字时间,1是为了模拟打字,2是避免多条回复乱序
|
event.group_id, global_config.BOT_QQ, think_id
|
||||||
|
) # 发送消息的id和产生发送消息的message_thinking是一致的
|
||||||
|
# 计算打字时间,1是为了模拟打字,2是避免多条回复乱序
|
||||||
accu_typing_time = 0
|
accu_typing_time = 0
|
||||||
|
|
||||||
# print(f"\033[1;32m[开始回复]\033[0m 开始将回复1载入发送容器")
|
# print(f"\033[1;32m[开始回复]\033[0m 开始将回复1载入发送容器")
|
||||||
mark_head = False
|
mark_head = False
|
||||||
for msg in response:
|
for msg in response:
|
||||||
# print(f"\033[1;32m[回复内容]\033[0m {msg}")
|
# print(f"\033[1;32m[回复内容]\033[0m {msg}")
|
||||||
#通过时间改变时间戳
|
# 通过时间改变时间戳
|
||||||
typing_time = calculate_typing_time(msg)
|
typing_time = calculate_typing_time(msg)
|
||||||
accu_typing_time += typing_time
|
accu_typing_time += typing_time
|
||||||
timepoint = tinking_time_point + accu_typing_time
|
timepoint = tinking_time_point + accu_typing_time
|
||||||
|
|
@ -157,9 +186,11 @@ class ChatBot:
|
||||||
processed_plain_text=msg,
|
processed_plain_text=msg,
|
||||||
user_nickname=global_config.BOT_NICKNAME,
|
user_nickname=global_config.BOT_NICKNAME,
|
||||||
group_name=message.group_name,
|
group_name=message.group_name,
|
||||||
time=timepoint, #记录了回复生成的时间
|
time=timepoint, # 记录了回复生成的时间
|
||||||
thinking_start_time=thinking_start_time, #记录了思考开始的时间
|
thinking_start_time=thinking_start_time, # 记录了思考开始的时间
|
||||||
reply_message_id=message.message_id
|
reply_message_id=message.message_id,
|
||||||
|
reply_user_id=message.user_id,
|
||||||
|
|
||||||
)
|
)
|
||||||
await bot_message.initialize()
|
await bot_message.initialize()
|
||||||
if not mark_head:
|
if not mark_head:
|
||||||
|
|
@ -167,7 +198,7 @@ class ChatBot:
|
||||||
mark_head = True
|
mark_head = True
|
||||||
message_set.add_message(bot_message)
|
message_set.add_message(bot_message)
|
||||||
|
|
||||||
#message_set 可以直接加入 message_manager
|
# message_set 可以直接加入 message_manager
|
||||||
# print(f"\033[1;32m[回复]\033[0m 将回复载入发送容器")
|
# print(f"\033[1;32m[回复]\033[0m 将回复载入发送容器")
|
||||||
message_manager.add_message(message_set)
|
message_manager.add_message(message_set)
|
||||||
|
|
||||||
|
|
@ -178,7 +209,7 @@ class ChatBot:
|
||||||
|
|
||||||
# 检查是否 <没有找到> emoji
|
# 检查是否 <没有找到> emoji
|
||||||
if emoji_raw != None:
|
if emoji_raw != None:
|
||||||
emoji_path,discription = emoji_raw
|
emoji_path, discription = emoji_raw
|
||||||
|
|
||||||
emoji_cq = CQCode.create_emoji_cq(emoji_path)
|
emoji_cq = CQCode.create_emoji_cq(emoji_path)
|
||||||
|
|
||||||
|
|
@ -207,20 +238,25 @@ class ChatBot:
|
||||||
message_manager.add_message(bot_message)
|
message_manager.add_message(bot_message)
|
||||||
emotion = await self.gpt._get_emotion_tags(raw_content)
|
emotion = await self.gpt._get_emotion_tags(raw_content)
|
||||||
print(f"为 '{response}' 获取到的情感标签为:{emotion}")
|
print(f"为 '{response}' 获取到的情感标签为:{emotion}")
|
||||||
valuedict={
|
valuedict = {
|
||||||
'happy': 0.5,
|
"happy": 0.5,
|
||||||
'angry': -1,
|
"angry": -1,
|
||||||
'sad': -0.5,
|
"sad": -0.5,
|
||||||
'surprised': 0.2,
|
"surprised": 0.2,
|
||||||
'disgusted': -1.5,
|
"disgusted": -1.5,
|
||||||
'fearful': -0.7,
|
"fearful": -0.7,
|
||||||
'neutral': 0.1
|
"neutral": 0.1,
|
||||||
}
|
}
|
||||||
await relationship_manager.update_relationship_value(message.user_id, relationship_value=valuedict[emotion[0]])
|
await relationship_manager.update_relationship_value(
|
||||||
|
message.user_id, relationship_value=valuedict[emotion[0]]
|
||||||
|
)
|
||||||
# 使用情绪管理器更新情绪
|
# 使用情绪管理器更新情绪
|
||||||
self.mood_manager.update_mood_from_emotion(emotion[0], global_config.mood_intensity_factor)
|
self.mood_manager.update_mood_from_emotion(
|
||||||
|
emotion[0], global_config.mood_intensity_factor
|
||||||
|
)
|
||||||
|
|
||||||
# willing_manager.change_reply_willing_after_sent(event.group_id)
|
# willing_manager.change_reply_willing_after_sent(event.group_id)
|
||||||
|
|
||||||
|
|
||||||
# 创建全局ChatBot实例
|
# 创建全局ChatBot实例
|
||||||
chat_bot = ChatBot()
|
chat_bot = ChatBot()
|
||||||
|
|
@ -8,19 +8,19 @@ from .cq_code import CQCode, cq_code_tool
|
||||||
from .utils_cq import parse_cq_code
|
from .utils_cq import parse_cq_code
|
||||||
from .utils_user import get_groupname, get_user_cardname, get_user_nickname
|
from .utils_user import get_groupname, get_user_cardname, get_user_nickname
|
||||||
|
|
||||||
Message = ForwardRef('Message') # 添加这行
|
Message = ForwardRef("Message") # 添加这行
|
||||||
# 禁用SSL警告
|
# 禁用SSL警告
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
#这个类是消息数据类,用于存储和管理消息数据。
|
# 这个类是消息数据类,用于存储和管理消息数据。
|
||||||
#它定义了消息的属性,包括群组ID、用户ID、消息ID、原始消息内容、纯文本内容和时间戳。
|
# 它定义了消息的属性,包括群组ID、用户ID、消息ID、原始消息内容、纯文本内容和时间戳。
|
||||||
#它还定义了两个辅助属性:keywords用于提取消息的关键词,is_plain_text用于判断消息是否为纯文本。
|
# 它还定义了两个辅助属性:keywords用于提取消息的关键词,is_plain_text用于判断消息是否为纯文本。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Message:
|
class Message:
|
||||||
"""消息数据类"""
|
"""消息数据类"""
|
||||||
|
|
||||||
message_id: int = None
|
message_id: int = None
|
||||||
time: float = None
|
time: float = None
|
||||||
|
|
||||||
|
|
@ -59,11 +59,12 @@ class Message:
|
||||||
|
|
||||||
# 消息解析
|
# 消息解析
|
||||||
if self.raw_message:
|
if self.raw_message:
|
||||||
if not isinstance(self,Message_Sending):
|
if not isinstance(self, Message_Sending):
|
||||||
self.message_segments = await self.parse_message_segments(self.raw_message)
|
self.message_segments = await self.parse_message_segments(
|
||||||
self.processed_plain_text = ' '.join(
|
self.raw_message
|
||||||
seg.translated_plain_text
|
)
|
||||||
for seg in self.message_segments
|
self.processed_plain_text = " ".join(
|
||||||
|
seg.translated_plain_text for seg in self.message_segments
|
||||||
)
|
)
|
||||||
|
|
||||||
# 构建详细文本
|
# 构建详细文本
|
||||||
|
|
@ -75,10 +76,14 @@ class Message:
|
||||||
if self.user_cardname
|
if self.user_cardname
|
||||||
else f"{self.user_nickname or f'用户{self.user_id}'}"
|
else f"{self.user_nickname or f'用户{self.user_id}'}"
|
||||||
)
|
)
|
||||||
if isinstance(self,Message_Sending) and self.is_emoji:
|
if isinstance(self, Message_Sending) and self.is_emoji:
|
||||||
self.detailed_plain_text = f"[{time_str}] {name}: {self.detailed_plain_text}\n"
|
self.detailed_plain_text = (
|
||||||
|
f"[{time_str}] {name}: {self.detailed_plain_text}\n"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.detailed_plain_text = f"[{time_str}] {name}: {self.processed_plain_text}\n"
|
self.detailed_plain_text = (
|
||||||
|
f"[{time_str}] {name}: {self.processed_plain_text}\n"
|
||||||
|
)
|
||||||
|
|
||||||
self._initialized = True
|
self._initialized = True
|
||||||
|
|
||||||
|
|
@ -96,8 +101,8 @@ class Message:
|
||||||
start = 0
|
start = 0
|
||||||
while True:
|
while True:
|
||||||
# 查找下一个CQ码的开始位置
|
# 查找下一个CQ码的开始位置
|
||||||
cq_start = message.find('[CQ:', start)
|
cq_start = message.find("[CQ:", start)
|
||||||
#如果没有cq码,直接返回文本内容
|
# 如果没有cq码,直接返回文本内容
|
||||||
if cq_start == -1:
|
if cq_start == -1:
|
||||||
# 如果没有找到更多CQ码,添加剩余文本
|
# 如果没有找到更多CQ码,添加剩余文本
|
||||||
if start < len(message):
|
if start < len(message):
|
||||||
|
|
@ -111,42 +116,48 @@ class Message:
|
||||||
if text: # 只添加非空文本
|
if text: # 只添加非空文本
|
||||||
cq_code_dict_list.append(parse_cq_code(text))
|
cq_code_dict_list.append(parse_cq_code(text))
|
||||||
# 查找CQ码的结束位置
|
# 查找CQ码的结束位置
|
||||||
cq_end = message.find(']', cq_start)
|
cq_end = message.find("]", cq_start)
|
||||||
if cq_end == -1:
|
if cq_end == -1:
|
||||||
# CQ码未闭合,作为普通文本处理
|
# CQ码未闭合,作为普通文本处理
|
||||||
text = message[cq_start:].strip()
|
text = message[cq_start:].strip()
|
||||||
if text:
|
if text:
|
||||||
cq_code_dict_list.append(parse_cq_code(text))
|
cq_code_dict_list.append(parse_cq_code(text))
|
||||||
break
|
break
|
||||||
cq_code = message[cq_start:cq_end + 1]
|
cq_code = message[cq_start : cq_end + 1]
|
||||||
|
|
||||||
#将cq_code解析成字典
|
# 将cq_code解析成字典
|
||||||
cq_code_dict_list.append(parse_cq_code(cq_code))
|
cq_code_dict_list.append(parse_cq_code(cq_code))
|
||||||
# 更新start位置到当前CQ码之后
|
# 更新start位置到当前CQ码之后
|
||||||
start = cq_end + 1
|
start = cq_end + 1
|
||||||
|
|
||||||
# print(f"\033[1;34m[调试信息]\033[0m 提取的消息对象:列表: {cq_code_dict_list}")
|
# print(f"\033[1;34m[调试信息]\033[0m 提取的消息对象:列表: {cq_code_dict_list}")
|
||||||
|
|
||||||
#判定是否是表情包消息,以及是否含有表情包
|
# 判定是否是表情包消息,以及是否含有表情包
|
||||||
if len(cq_code_dict_list) == 1 and cq_code_dict_list[0]['type'] == 'image':
|
if len(cq_code_dict_list) == 1 and cq_code_dict_list[0]["type"] == "image":
|
||||||
self.is_emoji = True
|
self.is_emoji = True
|
||||||
self.has_emoji_emoji = True
|
self.has_emoji_emoji = True
|
||||||
else:
|
else:
|
||||||
for segment in cq_code_dict_list:
|
for segment in cq_code_dict_list:
|
||||||
if segment['type'] == 'image' and segment['data'].get('sub_type') == '1':
|
if (
|
||||||
|
segment["type"] == "image"
|
||||||
|
and segment["data"].get("sub_type") == "1"
|
||||||
|
):
|
||||||
self.has_emoji_emoji = True
|
self.has_emoji_emoji = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# 翻译作为字典的CQ码
|
||||||
#翻译作为字典的CQ码
|
|
||||||
for _code_item in cq_code_dict_list:
|
for _code_item in cq_code_dict_list:
|
||||||
message_obj = await cq_code_tool.cq_from_dict_to_class(_code_item,reply = self.reply_message)
|
message_obj = await cq_code_tool.cq_from_dict_to_class(
|
||||||
|
_code_item, reply=self.reply_message
|
||||||
|
)
|
||||||
trans_list.append(message_obj)
|
trans_list.append(message_obj)
|
||||||
return trans_list
|
return trans_list
|
||||||
|
|
||||||
|
|
||||||
class Message_Thinking:
|
class Message_Thinking:
|
||||||
"""消息思考类"""
|
"""消息思考类"""
|
||||||
def __init__(self, message: Message,message_id: str):
|
|
||||||
|
def __init__(self, message: Message, message_id: str):
|
||||||
# 复制原始消息的基本属性
|
# 复制原始消息的基本属性
|
||||||
self.group_id = message.group_id
|
self.group_id = message.group_id
|
||||||
self.user_id = message.user_id
|
self.user_id = message.user_id
|
||||||
|
|
@ -159,7 +170,7 @@ class Message_Thinking:
|
||||||
# 思考状态相关属性
|
# 思考状态相关属性
|
||||||
self.thinking_start_time = int(time.time())
|
self.thinking_start_time = int(time.time())
|
||||||
self.thinking_time = 0
|
self.thinking_time = 0
|
||||||
self.interupt=False
|
self.interupt = False
|
||||||
|
|
||||||
def update_thinking_time(self):
|
def update_thinking_time(self):
|
||||||
self.thinking_time = round(time.time(), 2) - self.thinking_start_time
|
self.thinking_time = round(time.time(), 2) - self.thinking_start_time
|
||||||
|
|
@ -168,10 +179,12 @@ class Message_Thinking:
|
||||||
@dataclass
|
@dataclass
|
||||||
class Message_Sending(Message):
|
class Message_Sending(Message):
|
||||||
"""发送中的消息类"""
|
"""发送中的消息类"""
|
||||||
|
|
||||||
thinking_start_time: float = None # 思考开始时间
|
thinking_start_time: float = None # 思考开始时间
|
||||||
thinking_time: float = None # 思考时间
|
thinking_time: float = None # 思考时间
|
||||||
|
|
||||||
reply_message_id: int = None # 存储 回复的 源消息ID
|
reply_message_id: int = None # 存储 回复的 源消息ID
|
||||||
|
reply_user_id: int = None # 私聊中需要回复的用户ID
|
||||||
|
|
||||||
is_head: bool = False # 是否是头部消息
|
is_head: bool = False # 是否是头部消息
|
||||||
|
|
||||||
|
|
@ -180,9 +193,9 @@ class Message_Sending(Message):
|
||||||
return self.thinking_time
|
return self.thinking_time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MessageSet:
|
class MessageSet:
|
||||||
"""消息集合类,可以存储多个发送消息"""
|
"""消息集合类,可以存储多个发送消息"""
|
||||||
|
|
||||||
def __init__(self, group_id: int, user_id: int, message_id: str):
|
def __init__(self, group_id: int, user_id: int, message_id: str):
|
||||||
self.group_id = group_id
|
self.group_id = group_id
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
@ -220,7 +233,6 @@ class MessageSet:
|
||||||
|
|
||||||
return self.messages[left]
|
return self.messages[left]
|
||||||
|
|
||||||
|
|
||||||
def clear_messages(self) -> None:
|
def clear_messages(self) -> None:
|
||||||
"""清空所有消息"""
|
"""清空所有消息"""
|
||||||
self.messages.clear()
|
self.messages.clear()
|
||||||
|
|
@ -237,6 +249,3 @@ class MessageSet:
|
||||||
|
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int:
|
||||||
return len(self.messages)
|
return len(self.messages)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,12 @@ from .storage import MessageStorage
|
||||||
from .utils import calculate_typing_time
|
from .utils import calculate_typing_time
|
||||||
from .config import global_config
|
from .config import global_config
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
class Message_Sender:
|
class Message_Sender:
|
||||||
"""发送器"""
|
"""发送器"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.message_interval = (0.5, 1) # 消息间隔时间范围(秒)
|
self.message_interval = (0.5, 1) # 消息间隔时间范围(秒)
|
||||||
self.last_send_time = 0
|
self.last_send_time = 0
|
||||||
|
|
@ -28,7 +31,7 @@ class Message_Sender:
|
||||||
send_text: str,
|
send_text: str,
|
||||||
auto_escape: bool = False,
|
auto_escape: bool = False,
|
||||||
reply_message_id: int = None,
|
reply_message_id: int = None,
|
||||||
at_user_id: int = None
|
at_user_id: int = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
if not self._current_bot:
|
if not self._current_bot:
|
||||||
|
|
@ -46,7 +49,6 @@ class Message_Sender:
|
||||||
# at_cq = cq_code_tool.create_at_cq(at_user_id)
|
# at_cq = cq_code_tool.create_at_cq(at_user_id)
|
||||||
# message = at_cq + " " + message
|
# message = at_cq + " " + message
|
||||||
|
|
||||||
|
|
||||||
typing_time = calculate_typing_time(message)
|
typing_time = calculate_typing_time(message)
|
||||||
if typing_time > 10:
|
if typing_time > 10:
|
||||||
typing_time = 10
|
typing_time = 10
|
||||||
|
|
@ -55,18 +57,34 @@ class Message_Sender:
|
||||||
# 发送消息
|
# 发送消息
|
||||||
try:
|
try:
|
||||||
await self._current_bot.send_group_msg(
|
await self._current_bot.send_group_msg(
|
||||||
group_id=group_id,
|
group_id=group_id, message=message, auto_escape=auto_escape
|
||||||
message=message,
|
|
||||||
auto_escape=auto_escape
|
|
||||||
)
|
)
|
||||||
print(f"\033[1;34m[调试]\033[0m 发送消息{message}成功")
|
print(f"\033[1;34m[调试]\033[0m 发送消息{message}成功")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"发生错误 {e}")
|
print(f"发生错误 {e}")
|
||||||
print(f"\033[1;34m[调试]\033[0m 发送消息{message}失败")
|
print(f"\033[1;34m[调试]\033[0m 发送消息{message}失败")
|
||||||
|
|
||||||
|
async def send_private_message(
|
||||||
|
self, user_id: int, send_text: str, auto_escape: bool = False
|
||||||
|
) -> None:
|
||||||
|
if not self._current_bot:
|
||||||
|
raise RuntimeError("Bot未设置,请先调用set_bot方法设置bot实例")
|
||||||
|
|
||||||
|
message = send_text
|
||||||
|
|
||||||
|
# 发送消息
|
||||||
|
try:
|
||||||
|
await self._current_bot.send_private_msg(
|
||||||
|
user_id=user_id, message=message, auto_escape=auto_escape
|
||||||
|
)
|
||||||
|
logger.info(f"发送私聊消息{message}成功")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"发送私聊消息{message}失败,错误信息:{e}")
|
||||||
|
|
||||||
|
|
||||||
class MessageContainer:
|
class MessageContainer:
|
||||||
"""单个群的发送/思考消息容器"""
|
"""单个群的发送/思考消息容器"""
|
||||||
|
|
||||||
def __init__(self, group_id: int, max_size: int = 100):
|
def __init__(self, group_id: int, max_size: int = 100):
|
||||||
self.group_id = group_id
|
self.group_id = group_id
|
||||||
self.max_size = max_size
|
self.max_size = max_size
|
||||||
|
|
@ -89,11 +107,13 @@ class MessageContainer:
|
||||||
|
|
||||||
return timeout_messages
|
return timeout_messages
|
||||||
|
|
||||||
def get_earliest_message(self) -> Optional[Union[Message_Thinking, Message_Sending]]:
|
def get_earliest_message(
|
||||||
|
self,
|
||||||
|
) -> Optional[Union[Message_Thinking, Message_Sending]]:
|
||||||
"""获取thinking_start_time最早的消息对象"""
|
"""获取thinking_start_time最早的消息对象"""
|
||||||
if not self.messages:
|
if not self.messages:
|
||||||
return None
|
return None
|
||||||
earliest_time = float('inf')
|
earliest_time = float("inf")
|
||||||
earliest_message = None
|
earliest_message = None
|
||||||
for msg in self.messages:
|
for msg in self.messages:
|
||||||
msg_time = msg.thinking_start_time
|
msg_time = msg.thinking_start_time
|
||||||
|
|
@ -133,6 +153,7 @@ class MessageContainer:
|
||||||
|
|
||||||
class MessageManager:
|
class MessageManager:
|
||||||
"""管理所有群的消息容器"""
|
"""管理所有群的消息容器"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.containers: Dict[int, MessageContainer] = {}
|
self.containers: Dict[int, MessageContainer] = {}
|
||||||
self.storage = MessageStorage()
|
self.storage = MessageStorage()
|
||||||
|
|
@ -144,46 +165,81 @@ class MessageManager:
|
||||||
self.containers[group_id] = MessageContainer(group_id)
|
self.containers[group_id] = MessageContainer(group_id)
|
||||||
return self.containers[group_id]
|
return self.containers[group_id]
|
||||||
|
|
||||||
def add_message(self, message: Union[Message_Thinking, Message_Sending, MessageSet]) -> None:
|
def add_message(
|
||||||
|
self, message: Union[Message_Thinking, Message_Sending, MessageSet]
|
||||||
|
) -> None:
|
||||||
container = self.get_container(message.group_id)
|
container = self.get_container(message.group_id)
|
||||||
container.add_message(message)
|
container.add_message(message)
|
||||||
|
|
||||||
async def process_group_messages(self, group_id: int):
|
async def process_group_messages(self, group_id: int):
|
||||||
"""处理群消息"""
|
"""处理群消息"""
|
||||||
# if int(time.time() / 3) == time.time() / 3:
|
# if int(time.time() / 3) == time.time() / 3:
|
||||||
# print(f"\033[1;34m[调试]\033[0m 开始处理群{group_id}的消息")
|
# print(f"\033[1;34m[调试]\033[0m 开始处理群{group_id}的消息")
|
||||||
container = self.get_container(group_id)
|
container = self.get_container(group_id)
|
||||||
if container.has_messages():
|
if container.has_messages():
|
||||||
#最早的对象,可能是思考消息,也可能是发送消息
|
# 最早的对象,可能是思考消息,也可能是发送消息
|
||||||
message_earliest = container.get_earliest_message() #一个message_thinking or message_sending
|
message_earliest = (
|
||||||
|
container.get_earliest_message()
|
||||||
|
) # 一个message_thinking or message_sending
|
||||||
|
|
||||||
#如果是思考消息
|
# 如果是思考消息
|
||||||
if isinstance(message_earliest, Message_Thinking):
|
if isinstance(message_earliest, Message_Thinking):
|
||||||
#优先等待这条消息
|
# 优先等待这条消息
|
||||||
message_earliest.update_thinking_time()
|
message_earliest.update_thinking_time()
|
||||||
thinking_time = message_earliest.thinking_time
|
thinking_time = message_earliest.thinking_time
|
||||||
print(f"\033[1;34m[调试]\033[0m 消息正在思考中,已思考{int(thinking_time)}秒\033[K\r", end='', flush=True)
|
print(
|
||||||
|
f"\033[1;34m[调试]\033[0m 消息正在思考中,已思考{int(thinking_time)}秒\033[K\r",
|
||||||
|
end="",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
# 检查是否超时
|
# 检查是否超时
|
||||||
if thinking_time > global_config.thinking_timeout:
|
if thinking_time > global_config.thinking_timeout:
|
||||||
print(f"\033[1;33m[警告]\033[0m 消息思考超时({thinking_time}秒),移除该消息")
|
print(
|
||||||
|
f"\033[1;33m[警告]\033[0m 消息思考超时({thinking_time}秒),移除该消息"
|
||||||
|
)
|
||||||
container.remove_message(message_earliest)
|
container.remove_message(message_earliest)
|
||||||
else:# 如果不是message_thinking就只能是message_sending
|
else: # 如果不是message_thinking就只能是message_sending
|
||||||
print(f"\033[1;34m[调试]\033[0m 消息'{message_earliest.processed_plain_text}'正在发送中")
|
print(
|
||||||
#直接发,等什么呢
|
f"\033[1;34m[调试]\033[0m 消息'{message_earliest.processed_plain_text}'正在发送中"
|
||||||
if message_earliest.is_head and message_earliest.update_thinking_time() >30:
|
)
|
||||||
await message_sender.send_group_message(group_id, message_earliest.processed_plain_text, auto_escape=False, reply_message_id=message_earliest.reply_message_id)
|
# 直接发,等什么呢
|
||||||
|
|
||||||
|
if group_id == 0:
|
||||||
|
await message_sender.send_private_message(
|
||||||
|
user_id=message_earliest.reply_user_id,
|
||||||
|
send_text=message_earliest.processed_plain_text,
|
||||||
|
auto_escape=False,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await message_sender.send_group_message(group_id, message_earliest.processed_plain_text, auto_escape=False)
|
if (
|
||||||
#移除消息
|
message_earliest.is_head
|
||||||
|
and message_earliest.update_thinking_time() > 30
|
||||||
|
):
|
||||||
|
await message_sender.send_group_message(
|
||||||
|
group_id,
|
||||||
|
message_earliest.processed_plain_text,
|
||||||
|
auto_escape=False,
|
||||||
|
reply_message_id=message_earliest.reply_message_id,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await message_sender.send_group_message(
|
||||||
|
group_id,
|
||||||
|
message_earliest.processed_plain_text,
|
||||||
|
auto_escape=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 移除消息
|
||||||
if message_earliest.is_emoji:
|
if message_earliest.is_emoji:
|
||||||
message_earliest.processed_plain_text = "[表情包]"
|
message_earliest.processed_plain_text = "[表情包]"
|
||||||
await self.storage.store_message(message_earliest, None)
|
await self.storage.store_message(message_earliest, None)
|
||||||
|
|
||||||
container.remove_message(message_earliest)
|
container.remove_message(message_earliest)
|
||||||
|
|
||||||
#获取并处理超时消息
|
# 获取并处理超时消息
|
||||||
message_timeout = container.get_timeout_messages() #也许是一堆message_sending
|
message_timeout = (
|
||||||
|
container.get_timeout_messages()
|
||||||
|
) # 也许是一堆message_sending
|
||||||
if message_timeout:
|
if message_timeout:
|
||||||
print(f"\033[1;34m[调试]\033[0m 发现{len(message_timeout)}条超时消息")
|
print(f"\033[1;34m[调试]\033[0m 发现{len(message_timeout)}条超时消息")
|
||||||
for msg in message_timeout:
|
for msg in message_timeout:
|
||||||
|
|
@ -191,14 +247,20 @@ class MessageManager:
|
||||||
continue # 跳过已经处理过的消息
|
continue # 跳过已经处理过的消息
|
||||||
|
|
||||||
try:
|
try:
|
||||||
#发送
|
# 发送
|
||||||
if msg.is_head and msg.update_thinking_time() >30:
|
if msg.is_head and msg.update_thinking_time() > 30:
|
||||||
await message_sender.send_group_message(group_id, msg.processed_plain_text, auto_escape=False, reply_message_id=msg.reply_message_id)
|
await message_sender.send_group_message(
|
||||||
|
group_id,
|
||||||
|
msg.processed_plain_text,
|
||||||
|
auto_escape=False,
|
||||||
|
reply_message_id=msg.reply_message_id,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await message_sender.send_group_message(group_id, msg.processed_plain_text, auto_escape=False)
|
await message_sender.send_group_message(
|
||||||
|
group_id, msg.processed_plain_text, auto_escape=False
|
||||||
|
)
|
||||||
|
|
||||||
|
# 如果是表情包,则替换为"[表情包]"
|
||||||
#如果是表情包,则替换为"[表情包]"
|
|
||||||
if msg.is_emoji:
|
if msg.is_emoji:
|
||||||
msg.processed_plain_text = "[表情包]"
|
msg.processed_plain_text = "[表情包]"
|
||||||
await self.storage.store_message(msg, None)
|
await self.storage.store_message(msg, None)
|
||||||
|
|
@ -220,6 +282,7 @@ class MessageManager:
|
||||||
|
|
||||||
await asyncio.gather(*tasks)
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
# 创建全局消息管理器实例
|
# 创建全局消息管理器实例
|
||||||
message_manager = MessageManager()
|
message_manager = MessageManager()
|
||||||
# 创建全局发送器实例
|
# 创建全局发送器实例
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ enable_kuuki_read = true # 是否启用读空气功能
|
||||||
talk_allowed = [
|
talk_allowed = [
|
||||||
123,
|
123,
|
||||||
123,
|
123,
|
||||||
|
#0, 如果填0则开启私聊功能
|
||||||
] #可以回复消息的群
|
] #可以回复消息的群
|
||||||
talk_frequency_down = [] #降低回复频率的群
|
talk_frequency_down = [] #降低回复频率的群
|
||||||
ban_user_id = [] #禁止回复消息的QQ号
|
ban_user_id = [] #禁止回复消息的QQ号
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue