新增 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: 类型定义
62 lines
1.6 KiB
Python
62 lines
1.6 KiB
Python
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)
|