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:
2026-09-22 14:23:46 +08:00
co-authored by Claude Code
parent 4badcfcf32
commit 814c1994b6
9 changed files with 1150 additions and 46 deletions
@@ -14,7 +14,8 @@ from nonebot.log import logger
from nonebot.params import RegexGroup
from nonebot.plugin import PluginMetadata
from ..config import pc, save_file, var
from ..config import pc, var
from ..services import servers as store
from ..services.mc import check_mc_status
__plugin_meta__ = PluginMetadata(
@@ -76,18 +77,13 @@ async def _(mp=RegexGroup()):
return
group = int(mp[1])
new_server_name = mp[2]
server_host = mp[3]
server_type = mp[4].lower()
if server_type not in ["js", "bds"]:
await add_server.finish("类型请填js或bds")
if group not in var.group_list:
var.group_list[group] = {new_server_name: [server_host, server_type]}
else:
for server_name in var.group_list[group]:
if new_server_name == server_name:
await add_server.finish("有同名服务器啦!")
var.group_list[group][new_server_name] = [server_host, server_type]
save_file()
if new_server_name in var.group_list.get(group, {}):
await add_server.finish("有同名服务器啦!")
# 校验 + 落盘都在 services/servers.py(与 Web 管理台同一套)
try:
store.set_server(group, new_server_name, mp[3], mp[4])
except store.ServerError as e:
await add_server.finish("类型请填js或bds" if "类型请填" in str(e) else str(e))
await add_server.finish("添加成功")
@@ -96,18 +92,11 @@ async def _(mp=RegexGroup()):
if not mp[0]:
await del_server.finish(f"删除服务器 [群号] [名称]")
return
group = int(mp[1])
name = mp[2]
if group not in var.group_list:
await del_server.finish("这个群没有添加服务器")
if name in var.group_list[group]:
var.group_list[group].pop(name)
if not var.group_list[group]:
var.group_list.pop(group)
save_file()
await del_server.finish("删除成功")
else:
await del_server.finish("没找到该名称的服务器")
try:
store.delete_server(int(mp[1]), mp[2])
except store.ServerError as e:
await del_server.finish(str(e))
await del_server.finish("删除成功")
@list_all.handle()
@@ -129,9 +118,9 @@ async def _(mp=RegexGroup()):
if not mp[0]:
await test_server.finish("测试服务器 [服务器地址] [类型]\n类型写js或bds,js是Java服务器,bds是基岩服务器")
return
server_host = mp[1]
server_type = mp[2].lower()
if server_type not in ["js", "bds"]:
await add_server.finish("类型请填js或bds")
msg = await check_mc_status("测试", server_host, server_type)
await list_all.finish(msg)
try:
server_type = store.normalize_type(mp[2])
except store.ServerError as e:
await test_server.finish(str(e))
msg = await check_mc_status("测试", mp[1], server_type)
await test_server.finish(msg)