feat(group_horse_racing): 增加赛马消息图片渲染功能
- 在配置中新增图片渲染相关参数:RACE_RENDER_AS_IMAGE、RACE_IMAGE_WIDTH 等 - 复用 danding_qqpush 的 ImageRenderer,使其支持自定义标题 - 在比赛开始、结束和进度播报时,将文本消息转换为带标题的图片发送 - 修复测试用例中的消息发送函数调用
This commit is contained in:
@@ -3,8 +3,10 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, PrivateMessageEvent
|
||||
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, Message, MessageSegment, PrivateMessageEvent
|
||||
|
||||
from danding_bot.plugins.danding_qqpush.config import Config as QqPushConfig
|
||||
from danding_bot.plugins.danding_qqpush.image_render import ImageRenderer
|
||||
from .room_store import RoomStore
|
||||
from .points_service import PointsService
|
||||
from .race_engine import RaceEngine
|
||||
@@ -18,6 +20,39 @@ room_store = RoomStore(config)
|
||||
points_service = PointsService(config)
|
||||
race_engine = RaceEngine(config)
|
||||
message_service = MessageService(config)
|
||||
_race_image_renderer: ImageRenderer | None = None
|
||||
|
||||
|
||||
def _get_race_image_renderer() -> ImageRenderer:
|
||||
global _race_image_renderer
|
||||
if _race_image_renderer is None:
|
||||
qqpush_config = QqPushConfig()
|
||||
_race_image_renderer = ImageRenderer(
|
||||
width=config.RACE_IMAGE_WIDTH,
|
||||
font_size=config.RACE_IMAGE_FONT_SIZE,
|
||||
padding=config.RACE_IMAGE_PADDING,
|
||||
line_spacing=config.RACE_IMAGE_LINE_SPACING,
|
||||
font_paths=qqpush_config.FontPaths,
|
||||
)
|
||||
return _race_image_renderer
|
||||
|
||||
|
||||
def _build_race_image_message(message: str) -> Message:
|
||||
if message.startswith("比赛开始!"):
|
||||
title = "🏇 赛马开赛"
|
||||
body = message.replace("比赛开始!", "发令枪响,比赛正式开始!", 1)
|
||||
elif message.startswith("比赛结束!"):
|
||||
title = "🏆 赛马结果"
|
||||
body = message
|
||||
else:
|
||||
title = "📣 赛马进度"
|
||||
body = f"🏁 实时播报\n{message}"
|
||||
|
||||
renderer = _get_race_image_renderer()
|
||||
image_base64 = renderer.render_to_base64(body, title=title)
|
||||
message_obj = Message()
|
||||
message_obj.append(MessageSegment.image(image_base64))
|
||||
return message_obj
|
||||
|
||||
|
||||
def get_scope(event: Event) -> str:
|
||||
@@ -100,11 +135,14 @@ async def settle_race(room: Room):
|
||||
async def _send_to_scope(bot: Bot, scope: str, message: str):
|
||||
"""Send message to group or private chat based on scope."""
|
||||
try:
|
||||
outbound_message: str | Message = message
|
||||
if config.RACE_RENDER_AS_IMAGE:
|
||||
outbound_message = _build_race_image_message(message)
|
||||
await bot.send_msg(
|
||||
message_type="group" if scope.startswith("group_") else "private",
|
||||
group_id=int(scope.split("_", 1)[1]) if scope.startswith("group_") else None,
|
||||
user_id=int(scope.split("_", 1)[1]) if scope.startswith("test_") else None,
|
||||
message=message,
|
||||
message=outbound_message,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -22,6 +22,11 @@ class Config(BaseSettings):
|
||||
MIN_ODDS: float = 1.2
|
||||
RACE_DISTANCE: int = 100
|
||||
RACE_TICK_INTERVAL: int = 5
|
||||
RACE_RENDER_AS_IMAGE: bool = True
|
||||
RACE_IMAGE_WIDTH: int = 900
|
||||
RACE_IMAGE_FONT_SIZE: int = 26
|
||||
RACE_IMAGE_PADDING: int = 28
|
||||
RACE_IMAGE_LINE_SPACING: float = 1.35
|
||||
|
||||
# 消息撤回配置
|
||||
MESSAGE_RECALL: dict[str, int] = Field(
|
||||
|
||||
@@ -250,7 +250,7 @@ async def handle_test_simulate_race(bot: Bot, event: Event):
|
||||
progress_count += 1
|
||||
if progress_count > max_progress:
|
||||
return
|
||||
await test_simulate_race_cmd.send(message)
|
||||
await original_send_to_scope(bot, scope, message)
|
||||
|
||||
commands_mod._send_to_scope = _test_send_to_scope
|
||||
|
||||
|
||||
Reference in New Issue
Block a user