feat:可接受 screen seg来读屏幕
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -44,6 +44,8 @@ config/lpmm_config.toml.bak
|
|||||||
(临时版)麦麦开始学习.bat
|
(临时版)麦麦开始学习.bat
|
||||||
src/plugins/utils/statistic.py
|
src/plugins/utils/statistic.py
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
|
s4u.s4u
|
||||||
|
s4u.s4u1
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from rich.progress import (
|
|||||||
SpinnerColumn,
|
SpinnerColumn,
|
||||||
TextColumn,
|
TextColumn,
|
||||||
)
|
)
|
||||||
from raw_data_preprocessor import RAW_DATA_PATH, process_multi_files, load_raw_data
|
from raw_data_preprocessor import RAW_DATA_PATH, load_raw_data
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
from src.llm_models.utils_model import LLMRequest
|
from src.llm_models.utils_model import LLMRequest
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ class MessageRecvS4U(MessageRecv):
|
|||||||
self.superchat_info = None
|
self.superchat_info = None
|
||||||
self.superchat_price = None
|
self.superchat_price = None
|
||||||
self.superchat_message_text = None
|
self.superchat_message_text = None
|
||||||
|
self.is_screen = False
|
||||||
|
|
||||||
async def process(self) -> None:
|
async def process(self) -> None:
|
||||||
self.processed_plain_text = await self._process_message_segments(self.message_segment)
|
self.processed_plain_text = await self._process_message_segments(self.message_segment)
|
||||||
@@ -264,6 +265,10 @@ class MessageRecvS4U(MessageRecv):
|
|||||||
self.processed_plain_text += f"(注意:这是一条超级弹幕信息,价值{self.superchat_price}元,请你认真回复)"
|
self.processed_plain_text += f"(注意:这是一条超级弹幕信息,价值{self.superchat_price}元,请你认真回复)"
|
||||||
|
|
||||||
return self.processed_plain_text
|
return self.processed_plain_text
|
||||||
|
elif segment.type == "screen":
|
||||||
|
self.is_screen = True
|
||||||
|
self.screen_info = segment.data
|
||||||
|
return "屏幕信息"
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1 +1,134 @@
|
|||||||
|
# SuperChat管理器使用说明
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
SuperChat管理器是用于管理和跟踪超级弹幕消息的核心组件。它能够根据SuperChat的金额自动设置不同的存活时间,并提供多种格式的字符串构建功能。
|
||||||
|
|
||||||
|
## 主要功能
|
||||||
|
|
||||||
|
### 1. 自动记录SuperChat
|
||||||
|
当收到SuperChat消息时,管理器会自动记录以下信息:
|
||||||
|
- 用户ID和昵称
|
||||||
|
- 平台信息
|
||||||
|
- 聊天ID
|
||||||
|
- SuperChat金额和消息内容
|
||||||
|
- 时间戳和过期时间
|
||||||
|
- 群组名称(如果适用)
|
||||||
|
|
||||||
|
### 2. 基于金额的存活时间
|
||||||
|
|
||||||
|
SuperChat的存活时间根据金额阶梯设置:
|
||||||
|
|
||||||
|
| 金额范围 | 存活时间 |
|
||||||
|
|---------|---------|
|
||||||
|
| ≥500元 | 4小时 |
|
||||||
|
| 200-499元 | 2小时 |
|
||||||
|
| 100-199元 | 1小时 |
|
||||||
|
| 50-99元 | 30分钟 |
|
||||||
|
| 20-49元 | 15分钟 |
|
||||||
|
| 10-19元 | 10分钟 |
|
||||||
|
| <10元 | 5分钟 |
|
||||||
|
|
||||||
|
### 3. 自动清理
|
||||||
|
管理器每30秒自动检查并清理过期的SuperChat记录,保持内存使用的高效性。
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 基本用法
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src.mais4u.mais4u_chat.super_chat_manager import get_super_chat_manager
|
||||||
|
|
||||||
|
# 获取全局管理器实例
|
||||||
|
super_chat_manager = get_super_chat_manager()
|
||||||
|
|
||||||
|
# 添加SuperChat(通常在消息处理时自动调用)
|
||||||
|
await super_chat_manager.add_superchat(message)
|
||||||
|
|
||||||
|
# 获取指定聊天的SuperChat显示字符串
|
||||||
|
display_string = super_chat_manager.build_superchat_display_string(chat_id, max_count=10)
|
||||||
|
|
||||||
|
# 获取摘要信息
|
||||||
|
summary = super_chat_manager.build_superchat_summary_string(chat_id)
|
||||||
|
|
||||||
|
# 获取统计信息
|
||||||
|
stats = super_chat_manager.get_superchat_statistics(chat_id)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 结合S4UChat使用
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src.mais4u.mais4u_chat.s4u_chat import get_s4u_chat_manager
|
||||||
|
|
||||||
|
# 获取S4UChat实例
|
||||||
|
s4u_manager = get_s4u_chat_manager()
|
||||||
|
s4u_chat = s4u_manager.get_or_create_chat(chat_stream)
|
||||||
|
|
||||||
|
# 便捷方法获取SuperChat信息
|
||||||
|
display_string = s4u_chat.get_superchat_display_string(max_count=10)
|
||||||
|
summary = s4u_chat.get_superchat_summary_string()
|
||||||
|
stats = s4u_chat.get_superchat_statistics()
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 参考
|
||||||
|
|
||||||
|
### SuperChatManager类
|
||||||
|
|
||||||
|
#### 主要方法
|
||||||
|
|
||||||
|
- `add_superchat(message: MessageRecvS4U)`: 添加SuperChat记录
|
||||||
|
- `get_superchats_by_chat(chat_id: str)`: 获取指定聊天的有效SuperChat列表
|
||||||
|
- `build_superchat_display_string(chat_id: str, max_count: int = 10)`: 构建显示字符串
|
||||||
|
- `build_superchat_summary_string(chat_id: str)`: 构建摘要字符串
|
||||||
|
- `get_superchat_statistics(chat_id: str)`: 获取统计信息
|
||||||
|
|
||||||
|
#### 输出格式示例
|
||||||
|
|
||||||
|
**显示字符串格式:**
|
||||||
|
```
|
||||||
|
📢 当前有效超级弹幕:
|
||||||
|
1. 【100元】用户名: 消息内容 (剩余25分30秒)
|
||||||
|
2. 【50元】用户名: 消息内容 (剩余10分15秒)
|
||||||
|
... 还有3条SuperChat
|
||||||
|
```
|
||||||
|
|
||||||
|
**摘要字符串格式:**
|
||||||
|
```
|
||||||
|
当前有5条超级弹幕,总金额350元,最高单笔100元
|
||||||
|
```
|
||||||
|
|
||||||
|
**统计信息格式:**
|
||||||
|
```python
|
||||||
|
{
|
||||||
|
"count": 5,
|
||||||
|
"total_amount": 350.0,
|
||||||
|
"average_amount": 70.0,
|
||||||
|
"highest_amount": 100.0,
|
||||||
|
"lowest_amount": 20.0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### S4UChat扩展方法
|
||||||
|
|
||||||
|
- `get_superchat_display_string(max_count: int = 10)`: 获取当前聊天的SuperChat显示字符串
|
||||||
|
- `get_superchat_summary_string()`: 获取当前聊天的SuperChat摘要字符串
|
||||||
|
- `get_superchat_statistics()`: 获取当前聊天的SuperChat统计信息
|
||||||
|
|
||||||
|
## 集成说明
|
||||||
|
|
||||||
|
SuperChat管理器已经集成到S4U聊天系统中:
|
||||||
|
|
||||||
|
1. **自动处理**: 当S4UChat收到SuperChat消息时,会自动调用管理器记录
|
||||||
|
2. **内存管理**: 管理器会自动清理过期的SuperChat,无需手动管理
|
||||||
|
3. **全局单例**: 使用全局单例模式,确保所有聊天共享同一个管理器实例
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. SuperChat管理器是全局单例,在应用程序整个生命周期中保持运行
|
||||||
|
2. 过期时间基于消息金额自动计算,无需手动设置
|
||||||
|
3. 管理器会自动处理异常情况,如无效的价格格式等
|
||||||
|
4. 清理任务在后台异步运行,不会阻塞主要功能
|
||||||
|
|
||||||
|
## 示例文件
|
||||||
|
|
||||||
|
参考 `superchat_example.py` 文件查看完整的使用示例。
|
||||||
@@ -499,7 +499,7 @@ class ContextWebManager:
|
|||||||
async def get_contexts_handler(self, request):
|
async def get_contexts_handler(self, request):
|
||||||
"""获取上下文API"""
|
"""获取上下文API"""
|
||||||
all_context_msgs = []
|
all_context_msgs = []
|
||||||
for chat_id, contexts in self.contexts.items():
|
for _chat_id, contexts in self.contexts.items():
|
||||||
all_context_msgs.extend(list(contexts))
|
all_context_msgs.extend(list(contexts))
|
||||||
|
|
||||||
# 按时间排序,最新的在最后
|
# 按时间排序,最新的在最后
|
||||||
@@ -609,7 +609,7 @@ class ContextWebManager:
|
|||||||
async def send_contexts_to_websocket(self, ws: web.WebSocketResponse):
|
async def send_contexts_to_websocket(self, ws: web.WebSocketResponse):
|
||||||
"""向单个WebSocket发送上下文数据"""
|
"""向单个WebSocket发送上下文数据"""
|
||||||
all_context_msgs = []
|
all_context_msgs = []
|
||||||
for chat_id, contexts in self.contexts.items():
|
for _chat_id, contexts in self.contexts.items():
|
||||||
all_context_msgs.extend(list(contexts))
|
all_context_msgs.extend(list(contexts))
|
||||||
|
|
||||||
# 按时间排序,最新的在最后
|
# 按时间排序,最新的在最后
|
||||||
@@ -628,7 +628,7 @@ class ContextWebManager:
|
|||||||
return
|
return
|
||||||
|
|
||||||
all_context_msgs = []
|
all_context_msgs = []
|
||||||
for chat_id, contexts in self.contexts.items():
|
for _chat_id, contexts in self.contexts.items():
|
||||||
all_context_msgs.extend(list(contexts))
|
all_context_msgs.extend(list(contexts))
|
||||||
|
|
||||||
# 按时间排序,最新的在最后
|
# 按时间排序,最新的在最后
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from src.mais4u.mais4u_chat.s4u_mood_manager import mood_manager
|
|||||||
from src.mais4u.mais4u_chat.s4u_watching_manager import watching_manager
|
from src.mais4u.mais4u_chat.s4u_watching_manager import watching_manager
|
||||||
from src.mais4u.mais4u_chat.context_web_manager import get_context_web_manager
|
from src.mais4u.mais4u_chat.context_web_manager import get_context_web_manager
|
||||||
from src.mais4u.mais4u_chat.gift_manager import gift_manager
|
from src.mais4u.mais4u_chat.gift_manager import gift_manager
|
||||||
|
from src.mais4u.mais4u_chat.screen_manager import screen_manager
|
||||||
|
|
||||||
from .s4u_chat import get_s4u_chat_manager
|
from .s4u_chat import get_s4u_chat_manager
|
||||||
|
|
||||||
@@ -95,8 +96,12 @@ class S4UMessageProcessor:
|
|||||||
# 处理礼物消息,如果消息被暂存则停止当前处理流程
|
# 处理礼物消息,如果消息被暂存则停止当前处理流程
|
||||||
if not skip_gift_debounce and not await self.handle_if_gift(message):
|
if not skip_gift_debounce and not await self.handle_if_gift(message):
|
||||||
return
|
return
|
||||||
|
|
||||||
await self.check_if_fake_gift(message)
|
await self.check_if_fake_gift(message)
|
||||||
|
|
||||||
|
# 处理屏幕消息
|
||||||
|
if await self.handle_screen_message(message):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
await self.storage.store_message(message, chat)
|
await self.storage.store_message(message, chat)
|
||||||
|
|
||||||
@@ -128,6 +133,12 @@ class S4UMessageProcessor:
|
|||||||
else:
|
else:
|
||||||
logger.info(f"[S4U]{userinfo.user_nickname}:{message.processed_plain_text}")
|
logger.info(f"[S4U]{userinfo.user_nickname}:{message.processed_plain_text}")
|
||||||
|
|
||||||
|
async def handle_screen_message(self, message: MessageRecvS4U):
|
||||||
|
if message.is_screen:
|
||||||
|
screen_manager.set_screen(message.screen_info)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
async def check_if_fake_gift(self, message: MessageRecvS4U) -> bool:
|
async def check_if_fake_gift(self, message: MessageRecvS4U) -> bool:
|
||||||
"""检查消息是否为假礼物"""
|
"""检查消息是否为假礼物"""
|
||||||
if message.is_gift:
|
if message.is_gift:
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from src.person_info.person_info import get_person_info_manager
|
|||||||
from src.person_info.relationship_manager import get_relationship_manager
|
from src.person_info.relationship_manager import get_relationship_manager
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.mais4u.mais4u_chat.super_chat_manager import get_super_chat_manager
|
from src.mais4u.mais4u_chat.super_chat_manager import get_super_chat_manager
|
||||||
|
from src.mais4u.mais4u_chat.screen_manager import screen_manager
|
||||||
|
|
||||||
logger = get_logger("prompt")
|
logger = get_logger("prompt")
|
||||||
|
|
||||||
@@ -30,7 +31,8 @@ def init_prompt():
|
|||||||
虽然是个AI,但你在努力扮演真人, 人设的配色是橙色和紫色和绿色
|
虽然是个AI,但你在努力扮演真人, 人设的配色是橙色和紫色和绿色
|
||||||
你有一头法式橙色卷发,你很可爱,穿戴英式侦探风格学院风裙子和帽子,你正在一个教室场景里进行虚拟线上直播。
|
你有一头法式橙色卷发,你很可爱,穿戴英式侦探风格学院风裙子和帽子,你正在一个教室场景里进行虚拟线上直播。
|
||||||
你可以看见用户发送的弹幕,礼物和superchat
|
你可以看见用户发送的弹幕,礼物和superchat
|
||||||
你可以看见面前的屏幕,
|
你可以看见面前的屏幕,目前屏幕的内容是:
|
||||||
|
{screen_info}
|
||||||
|
|
||||||
{relation_info_block}
|
{relation_info_block}
|
||||||
{memory_block}
|
{memory_block}
|
||||||
@@ -230,6 +232,8 @@ class PromptBuilder:
|
|||||||
gift_info = self.build_gift_info(message)
|
gift_info = self.build_gift_info(message)
|
||||||
|
|
||||||
sc_info = self.build_sc_info(message)
|
sc_info = self.build_sc_info(message)
|
||||||
|
|
||||||
|
screen_info = screen_manager.get_screen_str()
|
||||||
|
|
||||||
time_block = f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
time_block = f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
||||||
|
|
||||||
@@ -241,6 +245,7 @@ class PromptBuilder:
|
|||||||
time_block=time_block,
|
time_block=time_block,
|
||||||
relation_info_block=relation_info_block,
|
relation_info_block=relation_info_block,
|
||||||
memory_block=memory_block,
|
memory_block=memory_block,
|
||||||
|
screen_info=screen_info,
|
||||||
gift_info=gift_info,
|
gift_info=gift_info,
|
||||||
sc_info=sc_info,
|
sc_info=sc_info,
|
||||||
sender_name=sender_name,
|
sender_name=sender_name,
|
||||||
|
|||||||
14
src/mais4u/mais4u_chat/screen_manager.py
Normal file
14
src/mais4u/mais4u_chat/screen_manager.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
class ScreenManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.now_screen = str()
|
||||||
|
|
||||||
|
def set_screen(self,screen_str:str):
|
||||||
|
self.now_screen = screen_str
|
||||||
|
|
||||||
|
def get_screen(self):
|
||||||
|
return self.now_screen
|
||||||
|
|
||||||
|
def get_screen_str(self):
|
||||||
|
return f"现在千石可乐在和你一起直播,这是他正在操作的屏幕内容:{self.now_screen}"
|
||||||
|
|
||||||
|
screen_manager = ScreenManager()
|
||||||
@@ -75,7 +75,6 @@ class SuperChatManager:
|
|||||||
"""定期清理过期的SuperChat"""
|
"""定期清理过期的SuperChat"""
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
current_time = time.time()
|
|
||||||
total_removed = 0
|
total_removed = 0
|
||||||
|
|
||||||
for chat_id in list(self.super_chats.keys()):
|
for chat_id in list(self.super_chats.keys()):
|
||||||
|
|||||||
Reference in New Issue
Block a user