ForcePilot/backend/package/yuxi/channel/extensions/minecraft/streaming.py
Kris b3b6c95094 feat(channel): 添加 Minecraft 渠道扩展
新增 Minecraft 渠道扩展,支持在 Yuxi 平台中集成 Minecraft 游戏服务器渠道。

包含以下功能模块:
- client: Minecraft 客户端封装
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- outbound: 外发消息管理
- streaming: 流式消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- auth: 认证管理
- accounts: 账户管理
- dedupe: 消息去重
- monitor: 渠道状态监控
- status: 会话状态管理
- protocol: Minecraft 协议处理
- rcon: RCON 远程控制
- keepalive: 连接保活
- version_adapter: 版本适配
- setup: 初始化设置
- types: 类型定义
2026-05-21 11:26:52 +08:00

62 lines
1.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
import logging
from collections.abc import Awaitable, Callable
logger = logging.getLogger(__name__)
MC_CHAT_MAX_CHARS = 256
CHUNK_PREFIX_OVERHEAD = 8
DELAY_BETWEEN_CHUNKS = 0.5
def split_for_minecraft(
content: str,
max_chars: int = MC_CHAT_MAX_CHARS,
page_indicator: bool = True,
) -> list[str]:
result: list[str] = []
remaining = content
while remaining:
available = max_chars
if len(remaining) <= available:
result.append(remaining)
break
split_at = -1
for sep in ("\n", "", "", "", ". ", "! ", "? ", "", ", ", " "):
pos = remaining.rfind(sep, 0, available)
if pos > available * 0.5:
split_at = pos + len(sep)
break
if split_at == -1:
split_at = available
result.append(remaining[:split_at].rstrip())
remaining = remaining[split_at:].lstrip()
if page_indicator and len(result) > 1:
total = len(result)
result = [f"[{i + 1}/{total}] {chunk}" for i, chunk in enumerate(result)]
return result
async def stream_block_minecraft(
send_fn: Callable[[str], Awaitable[None]],
content: str,
chunk_delay: float = DELAY_BETWEEN_CHUNKS,
) -> None:
chunks = split_for_minecraft(content)
total = len(chunks)
logger.info("Minecraft streaming: %d chars -> %d chunks", len(content), total)
for i, chunk in enumerate(chunks):
await send_fn(chunk)
if i < total - 1:
logger.debug("Chunk %d/%d sent, waiting %.1fs", i + 1, total, chunk_delay)
await asyncio.sleep(chunk_delay)