feat:可接受 screen seg来读屏幕

This commit is contained in:
SengokuCola
2025-07-15 20:29:06 +08:00
parent 5148901f05
commit 7d448c5fdc
9 changed files with 177 additions and 8 deletions

2
.gitignore vendored
View File

@@ -44,6 +44,8 @@ config/lpmm_config.toml.bak
(临时版)麦麦开始学习.bat
src/plugins/utils/statistic.py
CLAUDE.md
s4u.s4u
s4u.s4u1
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

View File

@@ -24,7 +24,7 @@ from rich.progress import (
SpinnerColumn,
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.llm_models.utils_model import LLMRequest

View File

@@ -190,6 +190,7 @@ class MessageRecvS4U(MessageRecv):
self.superchat_info = None
self.superchat_price = None
self.superchat_message_text = None
self.is_screen = False
async def process(self) -> None:
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}元,请你认真回复)"
return self.processed_plain_text
elif segment.type == "screen":
self.is_screen = True
self.screen_info = segment.data
return "屏幕信息"
else:
return ""
except Exception as e:

View File

@@ -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` 文件查看完整的使用示例

View File

@@ -499,7 +499,7 @@ class ContextWebManager:
async def get_contexts_handler(self, request):
"""获取上下文API"""
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))
# 按时间排序,最新的在最后
@@ -609,7 +609,7 @@ class ContextWebManager:
async def send_contexts_to_websocket(self, ws: web.WebSocketResponse):
"""向单个WebSocket发送上下文数据"""
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))
# 按时间排序,最新的在最后
@@ -628,7 +628,7 @@ class ContextWebManager:
return
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))
# 按时间排序,最新的在最后

View File

@@ -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.context_web_manager import get_context_web_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
@@ -95,8 +96,12 @@ class S4UMessageProcessor:
# 处理礼物消息,如果消息被暂存则停止当前处理流程
if not skip_gift_debounce and not await self.handle_if_gift(message):
return
await self.check_if_fake_gift(message)
# 处理屏幕消息
if await self.handle_screen_message(message):
return
await self.storage.store_message(message, chat)
@@ -128,6 +133,12 @@ class S4UMessageProcessor:
else:
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:
"""检查消息是否为假礼物"""
if message.is_gift:

View File

@@ -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.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.screen_manager import screen_manager
logger = get_logger("prompt")
@@ -30,7 +31,8 @@ def init_prompt():
虽然是个AI但你在努力扮演真人, 人设的配色是橙色和紫色和绿色
你有一头法式橙色卷发,你很可爱,穿戴英式侦探风格学院风裙子和帽子,你正在一个教室场景里进行虚拟线上直播。
你可以看见用户发送的弹幕礼物和superchat
你可以看见面前的屏幕,
你可以看见面前的屏幕,目前屏幕的内容是:
{screen_info}
{relation_info_block}
{memory_block}
@@ -230,6 +232,8 @@ class PromptBuilder:
gift_info = self.build_gift_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')}"
@@ -241,6 +245,7 @@ class PromptBuilder:
time_block=time_block,
relation_info_block=relation_info_block,
memory_block=memory_block,
screen_info=screen_info,
gift_info=gift_info,
sc_info=sc_info,
sender_name=sender_name,

View 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()

View File

@@ -75,7 +75,6 @@ class SuperChatManager:
"""定期清理过期的SuperChat"""
while True:
try:
current_time = time.time()
total_removed = 0
for chat_id in list(self.super_chats.keys()):