重构
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
import ast
|
||||
from asyncio import gather
|
||||
from base64 import b64decode
|
||||
from io import BytesIO
|
||||
from re import findall
|
||||
from typing import Union
|
||||
import json
|
||||
from mcstatus import BedrockServer, JavaServer
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
Bot,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
MessageEvent,
|
||||
)
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
MessageSegment as MS,
|
||||
)
|
||||
from nonebot.log import logger
|
||||
from nonebot.params import RegexGroup
|
||||
from nonebot.plugin import PluginMetadata
|
||||
|
||||
from .config import Config, pc, save_file, var
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="MC服务器信息查询插件",
|
||||
description="如名",
|
||||
type="application",
|
||||
homepage="https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_setu_customization",
|
||||
supported_adapters={"~onebot.v11"},
|
||||
config=Config,
|
||||
usage=f"""插件命令如下:
|
||||
信息 # 字面意思,需要加命令前缀,默认/
|
||||
信息数据 # 查看已启用群以及服务器信息,需要加命令前缀,默认/
|
||||
添加服务器 # 字面意思
|
||||
删除服务器 # 字面意思
|
||||
""",
|
||||
)
|
||||
|
||||
|
||||
async def group_check(event: GroupMessageEvent, bot: Bot) -> bool:
|
||||
return event.group_id in var.group_list and bot == var.handle_bot
|
||||
|
||||
|
||||
async def admin_check(event: MessageEvent, bot: Bot) -> bool:
|
||||
return bot == var.handle_bot and event.user_id in pc.mc_status_admin_qqnum
|
||||
|
||||
|
||||
xinxi = on_command("信息", rule=group_check)
|
||||
list_all = on_command("信息数据", rule=admin_check)
|
||||
add_server = on_regex(
|
||||
r"^添加服务器\s*((\d+)\s+(\S+)\s+(\S+)\s+(\S+))?", rule=admin_check
|
||||
)
|
||||
del_server = on_regex(r"^删除服务器\s*((\d+)\s+(\S+))?", rule=admin_check)
|
||||
test_server = on_regex(r"^测试服务器\s*((\S+)\s+(\S+))?", rule=admin_check)
|
||||
|
||||
|
||||
@xinxi.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
group = event.group_id
|
||||
task_list = []
|
||||
for server_name in var.group_list[group]:
|
||||
server_host = var.group_list[group][server_name][0]
|
||||
server_type = var.group_list[group][server_name][1]
|
||||
task_list.append(
|
||||
check_mc_status(
|
||||
server_name,
|
||||
server_host,
|
||||
server_type,
|
||||
)
|
||||
)
|
||||
result = await gather(*task_list)
|
||||
count = 0
|
||||
msg = ""
|
||||
print(result)
|
||||
for r in result:
|
||||
count += 1
|
||||
if count > 1:
|
||||
msg += "\n=== 分割线 ===\n"
|
||||
msg += r
|
||||
await xinxi.finish(msg)
|
||||
|
||||
|
||||
@add_server.handle()
|
||||
async def _(mp=RegexGroup()):
|
||||
if not mp[0]:
|
||||
await add_server.finish(
|
||||
f"添加服务器 [群号] [名称] [服务器地址] [类型]\n类型写js或bds,js是Java服务器,bds是基岩服务器\n服务器地址如果知道端口号把端口加上,否则查询速度会慢一点\n添加例子:\nexp1: 添加服务器 114514 哈皮咳嗽 mc.hypixel.net js\nexp2: 添加服务器 114514 某基岩服 mc.bds.net bds\nexp3: 添加服务器 114514 某Java服 mc.java.net:25577 js"
|
||||
)
|
||||
else:
|
||||
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()
|
||||
await add_server.finish("添加成功")
|
||||
|
||||
|
||||
@del_server.handle()
|
||||
async def _(mp=RegexGroup()):
|
||||
if not mp[0]:
|
||||
await del_server.finish(f"删除服务器 [群号] [名称]")
|
||||
else:
|
||||
group = int(mp[1])
|
||||
name = mp[2]
|
||||
|
||||
if group not in var.group_list:
|
||||
await del_server.finish("这个群没有添加服务器")
|
||||
else:
|
||||
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("没找到该名称的服务器")
|
||||
|
||||
|
||||
@list_all.handle()
|
||||
async def _():
|
||||
msg = ""
|
||||
for group_id in var.group_list:
|
||||
msg += f"群{group_id}服务器列表\n"
|
||||
for server_name in var.group_list[group_id]:
|
||||
server_host, server_type = var.group_list[group_id][server_name]
|
||||
msg += f"{server_name} {server_host} {server_type}\n"
|
||||
msg += "\n"
|
||||
if not msg:
|
||||
msg = "无数据"
|
||||
await list_all.finish(f"mc_status数据\n{msg}")
|
||||
|
||||
|
||||
@test_server.handle()
|
||||
async def _(mp=RegexGroup()):
|
||||
if not mp[0]:
|
||||
await test_server.finish(
|
||||
f"测试服务器 [服务器地址] [类型]\n类型写js或bds,js是Java服务器,bds是基岩服务器"
|
||||
)
|
||||
else:
|
||||
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)
|
||||
|
||||
|
||||
async def check_mc_status(
|
||||
name: str, host: str, server_type: str
|
||||
) -> Union[str, Message]:
|
||||
try:
|
||||
if server_type == "js":
|
||||
js = await JavaServer.async_lookup(host, timeout=2)
|
||||
status = js.status()
|
||||
# if status.description.strip():
|
||||
# print(f"des: {status.description}")
|
||||
version_list = findall(r"\d+\.\d+(?:\.[\dxX]+)?", status.version.name)
|
||||
if len(version_list) != 1:
|
||||
version = f"{version_list[0]}-{version_list[-1]}"
|
||||
else:
|
||||
version = version_list[0]
|
||||
|
||||
online = f"{status.players.online}/{status.players.max}"
|
||||
if status.players.online and status.players.sample:
|
||||
anonymous_player = 0
|
||||
_player_list = []
|
||||
for p in status.players.sample:
|
||||
if p.id == "00000000-0000-0000-0000-000000000000":
|
||||
anonymous_player += 1
|
||||
else:
|
||||
_player_list.append(p.name)
|
||||
|
||||
if anonymous_player:
|
||||
_player_list.append(f"[{anonymous_player}个匿名玩家]")
|
||||
|
||||
if _player_list:
|
||||
player_list = "\n".join(_player_list)
|
||||
|
||||
else:
|
||||
player_list = "没返回玩家列表"
|
||||
|
||||
else:
|
||||
player_list = "没人在线"
|
||||
|
||||
latency = round(status.latency)
|
||||
# base64图标
|
||||
if status.favicon:
|
||||
aa, bb = status.favicon.split("base64,")
|
||||
icon = MS.image(BytesIO(b64decode(bb))) + "\n"
|
||||
else:
|
||||
icon = ""
|
||||
msg = (
|
||||
icon
|
||||
+ f"名称:{name}\n版本:{version}\n在线:{online}\n延迟:{latency}ms\n在线列表:\n{player_list}"
|
||||
)
|
||||
|
||||
else:
|
||||
if host.find(":") != -1:
|
||||
host, port = host.split(":")
|
||||
else:
|
||||
host, port = host, 19132
|
||||
bds = BedrockServer(host=host, port=int(port))
|
||||
status = await bds.async_status()
|
||||
online = f"{status.players_online}/{status.players_max}"
|
||||
latency = round(status.latency)
|
||||
version = status.version.version
|
||||
msg = f"名称:{name} 【{version}】\n在线:{online} 延迟:{latency}ms"
|
||||
except Exception as e:
|
||||
msg = f"名称:{name} 查询失败!\n错误:{repr(e)}"
|
||||
|
||||
return msg
|
||||
@@ -0,0 +1,112 @@
|
||||
from json import dump, load
|
||||
from os import makedirs, path
|
||||
from typing import List, Optional
|
||||
|
||||
from nonebot import get_bot, get_bots, get_driver, get_plugin_config
|
||||
from nonebot.adapters import Bot
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Config(BaseModel):
|
||||
# 管理员的QQ号(别问我为什么)
|
||||
mc_status_admin_qqnum: List[int] = [] # 必填
|
||||
# 机器人的QQ号(如果写了就按优先级响应,否则就第一个连上的响应) ['1234','5678','6666']
|
||||
mc_status_bot_qqnum_list: List[str] = [] # 可选
|
||||
# 数据文件名
|
||||
mc_status_data_filename: str = "mc_status_data.json"
|
||||
|
||||
|
||||
class Var:
|
||||
# 处理消息的bot
|
||||
handle_bot: Optional[Bot] = None
|
||||
# {"123456": {"提肛": ["mc.hypixel.net:25565","java"]}}
|
||||
group_list = {}
|
||||
|
||||
|
||||
driver = get_driver()
|
||||
pc = get_plugin_config(Config)
|
||||
var = Var()
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
async def on_startup():
|
||||
if not path.exists(f"data"):
|
||||
makedirs(f"data")
|
||||
|
||||
if not path.exists(f"data/{pc.mc_status_data_filename}"):
|
||||
save_file()
|
||||
else:
|
||||
load_file()
|
||||
|
||||
|
||||
def load_file():
|
||||
with open(f"data/{pc.mc_status_data_filename}", "r", encoding="utf-8") as r:
|
||||
tmp_data = load(r)
|
||||
for i in tmp_data:
|
||||
var.group_list[int(i)] = tmp_data[i]
|
||||
|
||||
|
||||
def save_file():
|
||||
with open(f"data/{pc.mc_status_data_filename}", "w", encoding="utf-8") as w:
|
||||
dump(var.group_list, w, indent=4, ensure_ascii=False)
|
||||
|
||||
|
||||
# qq机器人连接时执行
|
||||
@driver.on_bot_connect
|
||||
async def on_bot_connect(bot: Bot):
|
||||
# 是否有写bot qq,如果写了只处理bot qq在列表里的
|
||||
if pc.mc_status_bot_qqnum_list and bot.self_id in pc.mc_status_bot_qqnum_list:
|
||||
# 如果已经有bot连了
|
||||
if var.handle_bot:
|
||||
# 当前bot qq 下标
|
||||
handle_bot_id_index = pc.mc_status_bot_qqnum_list.index(
|
||||
var.handle_bot.self_id
|
||||
)
|
||||
# 新连接的bot qq 下标
|
||||
new_bot_id_index = pc.mc_status_bot_qqnum_list.index(bot.self_id)
|
||||
# 判断优先级,下标越低优先级越高
|
||||
if new_bot_id_index < handle_bot_id_index:
|
||||
var.handle_bot = bot
|
||||
|
||||
# 没bot连就直接给
|
||||
else:
|
||||
var.handle_bot = bot
|
||||
|
||||
# 不写就给第一个连的
|
||||
elif not pc.mc_status_bot_qqnum_list and not var.handle_bot:
|
||||
var.handle_bot = bot
|
||||
|
||||
|
||||
# qq机器人断开时执行
|
||||
@driver.on_bot_disconnect
|
||||
async def on_bot_disconnect(bot: Bot):
|
||||
# 判断掉线的是否为handle bot
|
||||
if bot == var.handle_bot:
|
||||
# 如果有写bot qq列表
|
||||
if pc.mc_status_bot_qqnum_list:
|
||||
# 获取当前连着的bot列表(需要bot是在bot qq列表里)
|
||||
available_bot_id_list = [
|
||||
bot_id for bot_id in get_bots() if bot_id in pc.mc_status_bot_qqnum_list
|
||||
]
|
||||
if available_bot_id_list:
|
||||
# 打擂台排序?
|
||||
new_bot_index = pc.mc_status_bot_qqnum_list.index(
|
||||
available_bot_id_list[0]
|
||||
)
|
||||
for bot_id in available_bot_id_list:
|
||||
now_bot_index = pc.mc_status_bot_qqnum_list.index(bot_id)
|
||||
if now_bot_index < new_bot_index:
|
||||
new_bot_index = now_bot_index
|
||||
# 取下标在qq列表里最小的bot qq为新的handle bot
|
||||
var.handle_bot = get_bot(pc.mc_status_bot_qqnum_list[new_bot_index])
|
||||
|
||||
else:
|
||||
var.handle_bot = None
|
||||
|
||||
# 不写就随便给一个连着的(如果有)
|
||||
elif var.handle_bot:
|
||||
try:
|
||||
new_bot = get_bot()
|
||||
var.handle_bot = new_bot
|
||||
except ValueError:
|
||||
var.handle_bot = None
|
||||
Reference in New Issue
Block a user