Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
build-n-publish:
name: Use PDM to Build and publish Python 🐍 distributions 📦 to PyPI
name: Use uv to Build and publish Python 🐍 distributions 📦 to PyPI
runs-on: ubuntu-latest

permissions:
Expand All @@ -20,8 +20,15 @@ jobs:
with:
submodules: true

- name: Setup PDM
uses: pdm-project/setup-pdm@v3
- name: Install uv
uses: astral-sh/setup-uv@v5

- name: 'Set up Python'
uses: actions/setup-python@v5
with:
python-version-file: 'pyproject.toml'

- name: Build and Publish distribution 📦 to PyPI
run: pdm publish
run: |
uv build
uv publish
32 changes: 28 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

_✨ Minecraft 服务器 MOTD 查询 图片版 ✨_

<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="python">
<a href="https://pdm.fming.dev">
<img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm-managed">
<img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="python">
<a href="https://github.com/astral-sh/uv">
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
</a>
<a href="https://wakatime.com/badge/user/b61b0f9a-f40b-4c82-bc51-0a75c67bfccf/project/5bc0f141-d1ec-430a-8d21-0e312188fdae">
<img src="https://wakatime.com/badge/user/b61b0f9a-f40b-4c82-bc51-0a75c67bfccf/project/5bc0f141-d1ec-430a-8d21-0e312188fdae.svg" alt="wakatime">
Expand Down Expand Up @@ -172,7 +172,7 @@ plugins = [
(注意,nb2 以 JSON 格式解析配置项,所以当你要在正则表达式里表示`\`时,你需要将其转义为`\\`)
- `host` - 要查询的服务器地址,格式为 `<IP>[:端口]`,
例如 `hypixel.net` 或 `example.com:1919`
- `type` - 要查询服务器的类型,`je` 表示 Java 版服,`be` 表示基岩版服
- `type` - 要查询服务器的类型,`je` 表示 Java 版服,`be` 表示基岩版服,`auto` 代表自动检测
- `whitelist` - (仅支持 OneBot V11 适配器)群聊白名单,只有里面列出的群号可以查询,可以不填来对所有群开放查询

最终的配置项看起来是这样子的,当你发送 `查服` 时,机器人会把 EaseCation 服务器的状态发送出来
Expand All @@ -193,6 +193,15 @@ MCSTAT_SHORTCUTS='
如果你的服务器在运行 Clash 等拦截了 DNS 解析的软件,且查询部分地址时遇到了问题,请尝试关闭此配置项
此配置项不影响 Java 服务器的 SRV 记录解析

### `MCSTAT_RESOLVE_DNS_IPV6` - 是否启用 IPv6 解析

默认:`True`

是否优先使用 IPv6 地址进行查询
当启用此配置项时,会优先尝试使用 IPv6 地址进行连接,如连接失败则自动回落到 IPv4
如果你的网络环境不支持 IPv6,可以关闭此配置项以避免不必要的等待
此配置项仅在 `MCSTAT_RESOLVE_DNS` 启用时生效

### `MCSTAT_QUERY_TWICE` - 是否查询两遍服务器状态

默认:`True`
Expand All @@ -204,6 +213,12 @@ MCSTAT_SHORTCUTS='

默认:`767`

### `MCSTAT_ENABLE_AUTO_DETECT` - 是否在使用未指定服务器类型的 `motd` 指令时自动检测

默认:`True`

如设为 `False` 将默认指定为 Java 版

## 🎉 使用

发送 `motd` 指令 查看使用指南
Expand Down Expand Up @@ -231,6 +246,15 @@ Telegram:[@lgc2333](https://t.me/lgc2333)

## 📝 更新日志

### 0.8.1

- 添加配置项 `MCSTAT_RESOLVE_DNS_IPV6`,用于禁用 IPv6 解析([#29](https://github.com/lgc-NB2Dev/nonebot-plugin-picmcstat/issues/29))
- 当 IPv6 连接失败时自动回落到 IPv4

### 0.8.0

- 加入自动检测服务器类型的功能,默认启用(Thanks to [#28](https://github.com/lgc-NB2Dev/nonebot-plugin-picmcstat/pull/28))

### 0.7.1

- 修复文字下对齐的 Bug
Expand Down
2 changes: 1 addition & 1 deletion nonebot_plugin_picmcstat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from . import __main__ as __main__ # noqa: E402
from .config import ConfigClass # noqa: E402

__version__ = "0.7.2"
__version__ = "0.8.1"
__plugin_meta__ = PluginMetadata(
name="PicMCStat",
description="将一个 Minecraft 服务器的 MOTD 信息绘制为一张图片",
Expand Down
45 changes: 28 additions & 17 deletions nonebot_plugin_picmcstat/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from nonebot import logger, on_command, on_regex
from nonebot.adapters import Event as BaseEvent, Message
from nonebot.exception import FinishedException
from nonebot.params import CommandArg
from nonebot.params import CommandArg, CommandWhitespace
from nonebot.typing import T_State
from nonebot_plugin_alconna.uniseg import UniMessage

Expand All @@ -16,34 +16,45 @@
OB11GroupMessageEvent = None


async def finish_with_query(ip: str, svr_type: ServerType) -> NoReturn:
try:
ret = await draw(ip, svr_type)
except Exception:
msg = UniMessage("出现未知错误,请检查后台输出")
else:
msg = UniMessage.image(raw=ret)
await msg.send(reply_to=config.mcstat_reply_target)
raise FinishedException


motdje_matcher = on_command(
"motdje",
priority=98,
state={"svr_type": "je"},
)
motdpe_matcher = on_command(
"motdpe",
aliases={"motdbe", "!motdpe", "!motdpe", "!motdbe", "!motdbe"},
aliases={"motdbe"},
priority=98,
state={"svr_type": "be"},
)
motd_matcher = on_command(
"motd",
aliases={"!motd", "!motd", "motdje", "!motdje", "!motdje"},
priority=99,
state={"svr_type": "je"},
state={"svr_type": "auto" if config.enable_auto_detect else "je"},
)


async def finish_with_query(ip: str, svr_type: ServerType) -> NoReturn:
try:
ret = await draw(ip, svr_type)
except Exception:
msg = UniMessage("出现未知错误,请检查后台输出")
else:
msg = UniMessage.image(raw=ret)
await msg.send(reply_to=config.reply_target)
raise FinishedException


@motd_matcher.handle()
@motdje_matcher.handle()
@motdpe_matcher.handle()
async def _(state: T_State, arg_msg: Message = CommandArg()):
async def _(
state: T_State,
arg_msg: Message = CommandArg(),
space: str | None = CommandWhitespace(),
):
if arg_msg and (space is None):
return
arg = arg_msg.extract_plain_text().strip()
svr_type: ServerType = state["svr_type"]
await finish_with_query(arg, svr_type)
Expand All @@ -64,7 +75,7 @@ async def handler():


def startup():
if s := config.mcstat_shortcuts:
if s := config.shortcuts:
for v in s:
append_shortcut_handler(v)

Expand Down
31 changes: 17 additions & 14 deletions nonebot_plugin_picmcstat/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any, Optional
from typing import Any

from cookit.pyd import field_validator
from cookit.pyd import field_validator, model_with_alias_generator
from nonebot import get_plugin_config
from pydantic import BaseModel, Field

Expand All @@ -11,21 +11,24 @@ class ShortcutType(BaseModel):
regex: str
host: str
type: ServerType # noqa: A003
whitelist: Optional[list[int]] = []
whitelist: list[int] | None = []


@model_with_alias_generator(lambda x: f"mcstat_{x}")
class ConfigClass(BaseModel):
mcstat_font: list[str] = ["Minecraft Seven", "unifont"]
mcstat_show_addr: bool = False
mcstat_show_delay: bool = True
mcstat_show_mods: bool = False
mcstat_reply_target: bool = True
mcstat_shortcuts: list[ShortcutType] = Field(default_factory=list)
mcstat_resolve_dns: bool = True
mcstat_query_twice: bool = True
mcstat_java_protocol_version: int = 767

@field_validator("mcstat_font", mode="before")
font: list[str] = ["Minecraft Seven", "unifont"]
show_addr: bool = False
show_delay: bool = True
show_mods: bool = False
reply_target: bool = True
shortcuts: list[ShortcutType] = Field(default_factory=list)
resolve_dns: bool = True
resolve_dns_ipv6: bool = True
query_twice: bool = True
java_protocol_version: int = 772
enable_auto_detect: bool = True

@field_validator("font", mode="before")
def transform_to_list(cls, v: Any): # noqa: N805
return v if isinstance(v, list) else [v]

Expand Down
5 changes: 3 additions & 2 deletions nonebot_plugin_picmcstat/const.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import re
from typing import Literal
from typing import Literal, TypeAlias

from mcstatus.motd.components import Formatting, MinecraftColor

ServerType = Literal["je", "be"]
ServerTypeRaw: TypeAlias = Literal["je", "be"]
ServerType: TypeAlias = Literal[ServerTypeRaw, "auto"]

CODE_COLOR = {
"0": "#000000",
Expand Down
Loading