Skip to content

Commit

Permalink
0.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
lgc2333 committed Dec 19, 2023
1 parent 4bcc5bd commit c22bf4d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 27 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ plugins = [

默认:`False`

### `MCSTAT_SHOW_DELAY` - 是否显示测试延迟

默认:`True`

### `MCSTAT_SHOW_MODS` - 是否在生成的图片中显示 Mod 列表

默认:`False`
Expand Down Expand Up @@ -168,6 +172,13 @@ MCSTAT_SHORTCUTS='
如果你的服务器在运行 Clash 等拦截了 DNS 解析的软件,且查询部分地址时遇到了问题,请尝试关闭此配置项
此配置项不影响 Java 服务器的 SRV 记录解析

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

默认:`True`

由于第一次测得的延迟一般不准,所以做了这个配置,
开启后每次查询时,会丢掉第一次的结果再查询一次,且使用第二次查询到的结果

## 🎉 使用

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

## 📝 更新日志

### 0.5.1

- 修复 玩家 / Mod 列表 中出现的一些 Bug ~~果然又出 Bug 了~~
- 添加配置项 `MCSTAT_SHOW_DELAY``MCSTAT_QUERY_TWICE`

### 0.5.0

- 换用 Alconna 支持多平台
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.5.0"
__version__ = "0.5.1"
__plugin_meta__ = PluginMetadata(
name="PicMCStat",
description="将一个 Minecraft 服务器的 MOTD 信息绘制为一张图片",
Expand Down
2 changes: 2 additions & 0 deletions nonebot_plugin_picmcstat/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ class ShortcutType(BaseModel):
class ConfigClass(BaseModel):
mcstat_font: str = "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


config = ConfigClass.parse_obj(get_driver().config)
86 changes: 60 additions & 26 deletions nonebot_plugin_picmcstat/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from asyncio.exceptions import TimeoutError
from functools import partial
from io import BytesIO
from typing import List, Optional, Sequence, Tuple, Union
from typing import Any, List, Optional, Sequence, Tuple, Union, cast
from typing_extensions import TypeAlias

from mcstatus import BedrockServer, JavaServer
Expand Down Expand Up @@ -35,6 +35,7 @@
EXTRA_STROKE_WIDTH = 2
STROKE_RATIO = 0.0625
EXTRA_SPACING = 12
LIST_GAP = 32

JE_HEADER = "[MCJE服务器信息]"
BE_HEADER = "[MCBE服务器信息]"
Expand Down Expand Up @@ -86,7 +87,8 @@ def __init__(

@property
def width(self) -> int:
return self.left.width + self.gap + (self.right.width if self.right else 0)
rw = self.right.width if self.right else 0
return self.left.width + self.gap + rw

@property
def height(self) -> int:
Expand All @@ -103,19 +105,35 @@ def __init__(
*lines: ImageLine,
spacing: int = 6,
gap: Optional[int] = None,
align_items: bool = True,
):
if gap is not None:
lines = tuple(ImageLine(x.left, x.right, gap=gap) for x in lines)
super().__init__(lines)
self.spacing = spacing
self.align_items = align_items

@classmethod
def from_list(cls, li: Sequence[Union[ImageType, str]], **kwargs) -> "ImageGrid":
return cls(
*(ImageLine(*cast(Tuple[Any, Any], x)) for x in chunks(li, 2)),
**kwargs,
)

@property
def width(self) -> int:
return max([x.width for x in self])
return (
(
max(x.left.width for x in self)
+ max((x.right.width + x.gap if x.right else 0) for x in self)
)
if self.align_items
else max(x.width for x in self)
)

@property
def height(self) -> int:
return sum([x.height for x in self]) + self.spacing * (len(self) - 1)
return sum(x.height for x in self) + self.spacing * (len(self) - 1)

@property
def size(self) -> Tuple[int, int]:
Expand All @@ -125,6 +143,7 @@ def append_line(self, *args, **kwargs):
self.append(ImageLine(*args, **kwargs))

def draw_on(self, bg: BuildImage, offset_pos: Tuple[int, int]) -> None:
max_lw = max(x.left.width for x in self) if self.align_items else None
y_offset = 0
for line in self:
draw_image_type_on(
Expand All @@ -136,7 +155,10 @@ def draw_on(self, bg: BuildImage, offset_pos: Tuple[int, int]) -> None:
draw_image_type_on(
bg,
line.right,
calc_offset(offset_pos, (line.left.width + line.gap, y_offset)),
calc_offset(
offset_pos,
((max_lw or line.left.width) + line.gap, y_offset),
),
)
y_offset += line.height + self.spacing

Expand All @@ -154,10 +176,6 @@ def to_image(
return bg


def build_grid_from_list(li: Sequence[Union[ImageType, str]]) -> ImageGrid:
return ImageGrid(*(ImageLine(left, right) for left, right in chunks(li, 2)))


def get_header_by_svr_type(svr_type: ServerType) -> str:
return JE_HEADER if svr_type == "je" else BE_HEADER

Expand Down Expand Up @@ -273,7 +291,7 @@ def draw_java(res: JavaStatusResponse, addr: str) -> BytesIO:
mod_list = format_mod_list(tmp)

l_style = partial(ex_default_style, color_code="7")
grid = ImageGrid()
grid = ImageGrid(align_items=False)
grid.append_line(motd)
if config.mcstat_show_addr:
grid.append_line(l_style("测试地址: "), addr)
Expand All @@ -288,20 +306,25 @@ def draw_java(res: JavaStatusResponse, addr: str) -> BytesIO:
if mod_list:
grid.append_line(l_style("Mod 总数: "), str(len(mod_list)))
grid.append_line(l_style("聊天签名: "), "必需" if res.enforces_secure_chat else "无需")
grid.append_line(
l_style("测试延迟: "),
ex_default_style(f"{res.latency:.2f}ms", get_latency_color(res.latency)),
)
if config.mcstat_show_delay:
grid.append_line(
l_style("测试延迟: "),
ex_default_style(f"{res.latency:.2f}ms", get_latency_color(res.latency)),
)
if mod_list and config.mcstat_show_mods:
grid.append_line(l_style("Mod 列表: "), build_grid_from_list(mod_list))
grid.append_line(
l_style("Mod 列表: "),
ImageGrid.from_list(mod_list, gap=LIST_GAP),
)
if res.players.sample:
grid.append_line(
l_style("玩家列表: "),
build_grid_from_list(
ImageGrid.from_list(
[
transformer.transform(Motd.parse(x.name).parsed)
for x in res.players.sample
],
gap=LIST_GAP,
),
)

Expand All @@ -323,7 +346,7 @@ def draw_bedrock(res: BedrockStatusResponse, addr: str) -> BytesIO:
)

l_style = partial(ex_default_style, color_code="7")
grid = ImageGrid()
grid = ImageGrid(align_items=False)
grid.append_line(motd)
if config.mcstat_show_addr:
grid.append_line(l_style("测试地址: "), addr)
Expand All @@ -340,10 +363,11 @@ def draw_bedrock(res: BedrockStatusResponse, addr: str) -> BytesIO:
l_style("游戏模式: "),
GAME_MODE_MAP.get(res.gamemode, res.gamemode),
)
grid.append_line(
l_style("测试延迟: "),
ex_default_style(f"{res.latency:.2f}ms", get_latency_color(res.latency)),
)
if config.mcstat_show_delay:
grid.append_line(
l_style("测试延迟: "),
ex_default_style(f"{res.latency:.2f}ms", get_latency_color(res.latency)),
)

return build_img(BE_HEADER, SUCCESS_TITLE, extra=grid)

Expand All @@ -362,18 +386,28 @@ def draw_error(e: Exception, svr_type: ServerType) -> BytesIO:
return build_img(get_header_by_svr_type(svr_type), reason, extra=extra_img)


def draw_resp(
resp: Union[JavaStatusResponse, BedrockStatusResponse],
addr: str,
) -> BytesIO:
if isinstance(resp, JavaStatusResponse):
return draw_java(resp, addr)
return draw_bedrock(resp, addr)


async def draw(ip: str, svr_type: ServerType) -> BytesIO:
try:
if not ip:
return draw_help(svr_type)

is_java = svr_type == "je"
host, port = await resolve_ip(ip, is_java)
if is_java:
status = await JavaServer(host, port).async_status()
return draw_java(status, ip)
status = await BedrockServer(host, port).async_status()
return draw_bedrock(status, ip)

svr = JavaServer(host, port) if is_java else BedrockServer(host, port)
if config.mcstat_query_twice:
await svr.async_status() # 第一次延迟通常不准
resp = await svr.async_status()
return draw_resp(resp, ip)

except Exception as e:
logger.exception("获取服务器状态/画服务器状态图出错")
Expand Down

0 comments on commit c22bf4d

Please sign in to comment.