mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-29 01:23:52 +08:00
update:增加单台设备每天最多聊天字数,防止被ddos
* 添加清空redis所有库的接口 --AdminController.java 添加了清除所有的接口 --RedisUtils.java 添加了清除redis所有key的方法,redisTemplate提供的清空方法已经被标记为弃用了,所有选择用执行lua脚本方式 * fix:修复使用本地配置时忘记附带提示词 * fix:修复意图识别插件名称格式bug * update:版本升级后强制刷新redis * update:增加单台设备每天最多聊天字数,防止被ddos --------- Co-authored-by: 剑雨 <2375294554@qq.com>
This commit is contained in:
@@ -29,6 +29,7 @@ from core.auth import AuthMiddleware, AuthenticationError
|
||||
from core.mcp.manager import MCPManager
|
||||
from config.config_loader import get_private_config_from_api
|
||||
from config.manage_api_client import DeviceNotFoundException, DeviceBindException
|
||||
from core.utils.output_counter import add_device_output
|
||||
|
||||
TAG = __name__
|
||||
|
||||
@@ -57,6 +58,7 @@ class ConnectionHandler:
|
||||
self.session_id = None
|
||||
self.prompt = None
|
||||
self.welcome_msg = None
|
||||
self.max_output_size = 0
|
||||
|
||||
# 客户端状态相关
|
||||
self.client_abort = False
|
||||
@@ -315,7 +317,6 @@ class ConnectionHandler:
|
||||
self.config["selected_module"]["LLM"] = private_config["selected_module"][
|
||||
"LLM"
|
||||
]
|
||||
|
||||
if private_config.get("Memory", None) is not None:
|
||||
init_memory = True
|
||||
self.config["Memory"] = private_config["Memory"]
|
||||
@@ -328,6 +329,8 @@ class ConnectionHandler:
|
||||
self.config["selected_module"]["Intent"] = private_config[
|
||||
"selected_module"
|
||||
]["Intent"]
|
||||
if private_config.get("device_max_output_size", None) is not None:
|
||||
self.max_output_size = int(private_config["device_max_output_size"])
|
||||
try:
|
||||
modules = initialize_modules(
|
||||
self.logger,
|
||||
@@ -845,6 +848,8 @@ class ConnectionHandler:
|
||||
self.logger.bind(tag=TAG).error(f"tts转换失败,{text}")
|
||||
return None, text, text_index
|
||||
self.logger.bind(tag=TAG).debug(f"TTS 文件生成完毕: {tts_file}")
|
||||
if self.max_output_size > 0:
|
||||
add_device_output(self.headers.get("device-id"), len(text))
|
||||
return tts_file, text, text_index
|
||||
|
||||
def clearSpeakStatus(self):
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from config.logger import setup_logging
|
||||
import time
|
||||
import asyncio
|
||||
from core.utils.util import remove_punctuation_and_length
|
||||
from core.handle.sendAudioHandle import send_stt_message
|
||||
from core.handle.intentHandler import handle_user_intent
|
||||
from core.utils.output_counter import check_device_output_limit
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -51,6 +51,15 @@ async def startToChat(conn, text):
|
||||
if conn.need_bind:
|
||||
await check_bind_device(conn)
|
||||
return
|
||||
|
||||
# 如果当日的输出字数大于限定的字数
|
||||
if conn.max_output_size > 0:
|
||||
if check_device_output_limit(
|
||||
conn.headers.get("device-id"), conn.max_output_size
|
||||
):
|
||||
await max_out_size(conn)
|
||||
return
|
||||
|
||||
# 首先进行意图分析
|
||||
intent_handled = await handle_user_intent(conn, text)
|
||||
|
||||
@@ -89,6 +98,18 @@ async def no_voice_close_connect(conn):
|
||||
await startToChat(conn, prompt)
|
||||
|
||||
|
||||
async def max_out_size(conn):
|
||||
text = "不好意思,我现在有点事情要忙,明天这个时候我们再聊,约好了哦!明天不见不散,拜拜!"
|
||||
await send_stt_message(conn, text)
|
||||
conn.tts_first_text_index = 0
|
||||
conn.tts_last_text_index = 0
|
||||
conn.llm_finish_task = True
|
||||
file_path = "config/assets/max_output_size.wav"
|
||||
opus_packets, _ = conn.tts.audio_to_opus_data(file_path)
|
||||
conn.audio_play_queue.put((opus_packets, text, 0))
|
||||
conn.close_after_chat = True
|
||||
|
||||
|
||||
async def check_bind_device(conn):
|
||||
if conn.bind_code:
|
||||
# 确保bind_code是6位数字
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import datetime
|
||||
from typing import Dict, Tuple
|
||||
|
||||
# 全局字典,用于存储每个设备的每日输出字数
|
||||
_device_daily_output: Dict[Tuple[str, datetime.date], int] = {}
|
||||
# 记录最后一次检查的日期
|
||||
_last_check_date: datetime.date = None
|
||||
|
||||
|
||||
def reset_device_output():
|
||||
"""
|
||||
重置所有设备的每日输出字数
|
||||
每天0点调用此函数
|
||||
"""
|
||||
_device_daily_output.clear()
|
||||
|
||||
|
||||
def get_device_output(device_id: str) -> int:
|
||||
"""
|
||||
获取设备当日的输出字数
|
||||
"""
|
||||
current_date = datetime.datetime.now().date()
|
||||
return _device_daily_output.get((device_id, current_date), 0)
|
||||
|
||||
|
||||
def add_device_output(device_id: str, char_count: int):
|
||||
"""
|
||||
增加设备的输出字数
|
||||
"""
|
||||
current_date = datetime.datetime.now().date()
|
||||
global _last_check_date
|
||||
|
||||
# 如果是第一次调用或者日期发生变化,清空计数器
|
||||
if _last_check_date is None or _last_check_date != current_date:
|
||||
_device_daily_output.clear()
|
||||
_last_check_date = current_date
|
||||
|
||||
current_count = _device_daily_output.get((device_id, current_date), 0)
|
||||
_device_daily_output[(device_id, current_date)] = current_count + char_count
|
||||
|
||||
|
||||
def check_device_output_limit(device_id: str, max_output_size: int) -> bool:
|
||||
"""
|
||||
检查设备是否超过输出限制
|
||||
:return: True 如果超过限制,False 如果未超过
|
||||
"""
|
||||
if not device_id:
|
||||
return False
|
||||
current_output = get_device_output(device_id)
|
||||
return current_output >= max_output_size
|
||||
Reference in New Issue
Block a user