feat(mc-server-status): 服务器列表 Web 管理页 / 数据层抽离 / mcstatus 13 适配
- services/servers.py:校验 + 读写 + 增删改收敛成一份数据层(顶层不 import nonebot, 可脱离运行时单测),群命令与 Web API 都只经它改数据,校验不再各写一套 - web_hub.py + /hub/mc_server_status 页面:按群列出服务器,抽屉新增/编辑(改名)/ 测试连接,行内删除(删空一台连带删群);每条路由自带 require_admin - handlers/server.py 改为薄封装,只在需要命令特有提示时自己判断 - services/mc.py 的图标属性名兼容 mcstatus ≥13 的 icon(旧版叫 favicon, 读错会把整条查询打成"查询失败") - tests/test_mc_servers.py:数据层归一/改名/删群/坏文件兜底 + 图标解码两版属性名 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -5,15 +5,31 @@ from __future__ import annotations
|
||||
from base64 import b64decode
|
||||
from io import BytesIO
|
||||
from re import findall
|
||||
from typing import Union
|
||||
|
||||
from mcstatus import BedrockServer, JavaServer
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageSegment as MS
|
||||
|
||||
|
||||
def _server_icon(status) -> bytes | None:
|
||||
"""取服务器图标字节;没有图标或格式不认识就返回 None。
|
||||
|
||||
属性名跨版本换过:mcstatus ≥13 叫 `icon`,11.x/12.x 叫 `favicon`
|
||||
(13.0.0 的 changelog:`JavaStatusResponse.favicon` → `icon`,值没变)。
|
||||
值可能是完整的 data URI,也可能是不带前缀的裸 base64,两种都认。
|
||||
"""
|
||||
raw = getattr(status, "icon", None) or getattr(status, "favicon", None)
|
||||
if not raw:
|
||||
return None
|
||||
data = raw.split("base64,", 1)[-1] if "base64," in raw else raw
|
||||
try:
|
||||
return b64decode(data)
|
||||
except Exception: # noqa: BLE001 — 图标坏了不影响其它字段
|
||||
return None
|
||||
|
||||
|
||||
async def check_mc_status(
|
||||
name: str, host: str, server_type: str
|
||||
) -> Union[str, Message]:
|
||||
) -> str | Message:
|
||||
try:
|
||||
if server_type == "js":
|
||||
js = await JavaServer.async_lookup(host, timeout=2)
|
||||
@@ -38,11 +54,8 @@ async def check_mc_status(
|
||||
else:
|
||||
player_list = "没人在线"
|
||||
latency = round(status.latency)
|
||||
if status.favicon:
|
||||
aa, bb = status.favicon.split("base64,")
|
||||
icon = MS.image(BytesIO(b64decode(bb))) + "\n"
|
||||
else:
|
||||
icon = ""
|
||||
icon_data = _server_icon(status)
|
||||
icon = MS.image(BytesIO(icon_data)) + "\n" if icon_data else ""
|
||||
msg = (
|
||||
icon
|
||||
+ f"名称:{name}\n版本:{version}\n在线:{online}\n延迟:{latency}ms\n在线列表:\n{player_list}"
|
||||
|
||||
Reference in New Issue
Block a user