nonebot-plugin-l4d2-server 1.0.8__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/PKG-INFO +1 -1
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/__main__.py +6 -18
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/__init__.py +1 -1
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/convert.py +9 -3
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_local/__init__.py +30 -1
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_request/__init__.py +26 -4
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_request/draw_msg.py +92 -22
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_request/utils.py +4 -5
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/utils/utils.py +23 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/pyproject.toml +1 -1
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/LICENSE +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/README.md +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/__init__.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/config.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/data/font/loli.ttf +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/Help.json +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/draw.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//344/273/213/347/273/215.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//344/273/273/345/212/241.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//344/277/241/346/201/257.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/205/254/345/221/212.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/210/200/345/211/221.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/210/207/346/215/242.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/210/240/351/231/244.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/210/267/346/226/260.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/215/241/347/273/204.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/223/252/351/207/214.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/234/260/345/233/276.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/257/274/345/205/245.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/257/274/345/207/272.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//345/275/261.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/213/274/345/233/276.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/216/242/347/264/242.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/216/250/351/200/201.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/224/266/351/233/206.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/224/273/347/225/245.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/233/264/346/226/260.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/235/220/346/226/231.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/237/245/350/257/242.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/240/241/351/252/214.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/257/217/346/234/210.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/267/261/346/270/212.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/267/273/345/212/240.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//346/270/205/351/231/244.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//347/212/266/346/200/201.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//347/255/276/345/210/260.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//347/273/221/345/256/232.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//350/241/250.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//350/241/250/346/203/205.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//350/247/222/350/211/262.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//350/256/260/345/275/225.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//351/205/215/347/275/256.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/icon//351/207/215/345/220/257.png" +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/texture2d/badge.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/texture2d/banner.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/texture2d/bg.jpg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/texture2d/button.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_help/texture2d/icon.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/__init__.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/download.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/html_img.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/image_tools.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/anne/anne.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/anne/back.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/anne/back1.jpg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/anne/group_ip.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/anne/ip.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/head/head.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/header/logo.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/header/player1.jpg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Bocchi_The_Rock.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Bocchi_The_Rock.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/HYPixel11pxU-2.ttf +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Pixel.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Pixel.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Rainbow.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Rainbow.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/Tutumianhuatang-Bold-2.ttf +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/bilibili.svg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/fingerprint.svg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/github.svg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/l.svg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/m.svg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/normal.html +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/vac.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/vac_white.png +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/vue.css +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/img/template/w.svg +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/model.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_image/vtfs.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/l4_local/file.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/utils/api/api.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/utils/api/models.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/utils/api/request.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/utils/api/utils.py +0 -0
- {nonebot_plugin_l4d2_server-1.0.8 → nonebot_plugin_l4d2_server-1.1.0}/nonebot_plugin_l4d2_server/utils/database/models.py +0 -0
@@ -42,7 +42,7 @@ from .l4_request import (
|
|
42
42
|
)
|
43
43
|
from .utils.api.request import L4API
|
44
44
|
from .utils.api.utils import out_msg_out
|
45
|
-
from .utils.utils import split_maohao
|
45
|
+
from .utils.utils import log_and_send, read_config, split_maohao, write_config
|
46
46
|
|
47
47
|
if TYPE_CHECKING:
|
48
48
|
from .utils.api.models import OutServer
|
@@ -131,6 +131,8 @@ async def _(
|
|
131
131
|
):
|
132
132
|
# 以后有时间补img格式
|
133
133
|
msg: str = args.extract_plain_text().strip()
|
134
|
+
if not msg:
|
135
|
+
return UniMessage.text("请在指令后添加要找的昵称哦")
|
134
136
|
tag_list: List[str] = msg.split(" ", maxsplit=1)
|
135
137
|
if len(tag_list) == 1:
|
136
138
|
await UniMessage.text("未设置组,正在全服查找,时间较长").send()
|
@@ -202,29 +204,15 @@ l4_add_ban = on_command("l4addban", aliases={"l4添加ban"})
|
|
202
204
|
@l4_add_ban.handle()
|
203
205
|
async def _(args: Message = CommandArg()):
|
204
206
|
arg = args.extract_plain_text().strip().split(" ")
|
205
|
-
|
206
207
|
if len(arg) != 2:
|
207
208
|
await UniMessage.text("请在命令后增加响应指令名和网址").finish()
|
208
209
|
|
209
|
-
|
210
|
-
config_data = {}
|
211
|
-
else:
|
212
|
-
try:
|
213
|
-
with config_path.open("r") as f:
|
214
|
-
config_data = json.load(f)
|
215
|
-
except (json.JSONDecodeError, FileNotFoundError):
|
216
|
-
config_data = {}
|
217
|
-
|
210
|
+
config_data = read_config(config_path)
|
218
211
|
config_data.update({arg[0]: arg[1]})
|
219
|
-
|
220
|
-
try:
|
221
|
-
with config_path.open("w") as f:
|
222
|
-
json.dump(config_data, f, ensure_ascii=False, indent=4)
|
223
|
-
except IOError as e:
|
224
|
-
await UniMessage.text(f"文件写入失败: {e}").finish()
|
212
|
+
write_config(config_path, config_data)
|
225
213
|
|
226
214
|
await L4API.get_sourceban(arg[0], arg[1])
|
227
|
-
await
|
215
|
+
await log_and_send(l4_add_ban, f"添加成功\n组名: {arg[0]}\n网址: {arg[1]}")
|
228
216
|
|
229
217
|
|
230
218
|
l4_del_ban = on_command("l4delban", aliases={"l4删除ban", "l4移除ban"})
|
@@ -10,7 +10,7 @@ from ..l4_image.convert import core_font
|
|
10
10
|
from ..l4_image.model import PluginHelp
|
11
11
|
from .draw import get_help
|
12
12
|
|
13
|
-
__version__ = "1.0
|
13
|
+
__version__ = "1.1.0"
|
14
14
|
TEXT_PATH = Path(__file__).parent / "texture2d"
|
15
15
|
HELP_DATA = Path(__file__).parent / "Help.json"
|
16
16
|
|
@@ -152,20 +152,26 @@ async def text2pic(text: str, max_size: int = 800, font_size: int = 24):
|
|
152
152
|
if text.endswith("\n"):
|
153
153
|
text = text[:-1]
|
154
154
|
|
155
|
+
# 更准确的高度计算
|
156
|
+
line_count = text.count("\n") + 1
|
157
|
+
line_height = int(font_size * 1.2) # 每行高度,包含行间距
|
158
|
+
estimated_height = line_count * line_height + 80 # 加上上下边距
|
159
|
+
|
155
160
|
img = Image.new(
|
156
161
|
"RGB",
|
157
|
-
(max_size,
|
162
|
+
(max_size, estimated_height),
|
158
163
|
(255, 255, 255),
|
159
164
|
)
|
160
165
|
img_draw = ImageDraw.ImageDraw(img)
|
161
166
|
y = draw_center_text_by_line(
|
162
167
|
img_draw,
|
163
|
-
(50,
|
168
|
+
(50, 30),
|
164
169
|
text,
|
165
170
|
core_font(font_size),
|
166
171
|
"black",
|
167
172
|
max_size - 80,
|
168
173
|
True, # noqa: FBT003
|
169
174
|
)
|
170
|
-
|
175
|
+
# 裁剪时留一些余量
|
176
|
+
img = img.crop((0, 0, max_size, int(y + 55)))
|
171
177
|
return await convert_img(img)
|
@@ -45,7 +45,15 @@ else:
|
|
45
45
|
|
46
46
|
@search_map.handle()
|
47
47
|
async def _():
|
48
|
-
|
48
|
+
try:
|
49
|
+
supath = local_path[map_index] / "addons"
|
50
|
+
except IndexError:
|
51
|
+
logger.warning(
|
52
|
+
"未填写本地服务器路径,如果想要使用本地服务器功能,请填写本地服务器路径",
|
53
|
+
)
|
54
|
+
await UniMessage.text(
|
55
|
+
"未填写本地服务器路径,如果想要使用本地服务器功能,请填写本地服务器路径",
|
56
|
+
).finish()
|
49
57
|
vpk_list: list[str] = []
|
50
58
|
if supath.is_dir():
|
51
59
|
for sudir in supath.iterdir():
|
@@ -54,6 +62,27 @@ else:
|
|
54
62
|
vpk_list.append(sudir.name)
|
55
63
|
if not vpk_list:
|
56
64
|
await UniMessage.text("未找到可用的VPK文件").finish()
|
65
|
+
|
66
|
+
# 添加排序逻辑(数字升序)
|
67
|
+
def sort_key(filename: str):
|
68
|
+
# 提取文件名开头的数字(如果有)
|
69
|
+
num_part = ""
|
70
|
+
for char in filename:
|
71
|
+
if char.isdigit():
|
72
|
+
num_part += char
|
73
|
+
elif num_part: # 遇到非数字且已经有数字部分时停止
|
74
|
+
break
|
75
|
+
|
76
|
+
# 返回一个元组作为排序依据:(数字值, 整个文件名)
|
77
|
+
# 使用正数表示升序,没有数字的用无穷大排在最后
|
78
|
+
return (
|
79
|
+
int(num_part) if num_part else float("inf"),
|
80
|
+
filename,
|
81
|
+
)
|
82
|
+
|
83
|
+
# 按数字升序,然后按字母和中文排序
|
84
|
+
vpk_list.sort(key=sort_key)
|
85
|
+
|
57
86
|
out_msg = "\n".join(
|
58
87
|
f"{index + 1}、{line}" for index, line in enumerate(vpk_list)
|
59
88
|
)
|
@@ -119,6 +119,7 @@ async def get_group_detail(
|
|
119
119
|
command: str,
|
120
120
|
):
|
121
121
|
server_json = _get_server_json(command, ALLHOST)
|
122
|
+
# logger.debug(f"获取组服务器信息: {server_json}")
|
122
123
|
logger.info(server_json)
|
123
124
|
if server_json is None:
|
124
125
|
logger.warning("未找到这个组")
|
@@ -170,7 +171,7 @@ def reload_ip():
|
|
170
171
|
async def tj_request(command: str = "云", tj="tj"):
|
171
172
|
map_type = "普通药役"
|
172
173
|
server_json = ALLHOST.get(command)
|
173
|
-
logger.
|
174
|
+
logger.debug(server_json)
|
174
175
|
if server_json is None:
|
175
176
|
logger.warning("未找到这个组")
|
176
177
|
return None
|
@@ -186,8 +187,9 @@ async def tj_request(command: str = "云", tj="tj"):
|
|
186
187
|
logger.warning("没有找到符合条件的服务器")
|
187
188
|
return "没有符合条件的服务器"
|
188
189
|
|
190
|
+
server_list_str = [f"{ip['host']}:{ip['port']}" for ip in right_ip]
|
189
191
|
logger.info(
|
190
|
-
f"符合条件的服务器列表: {
|
192
|
+
f"符合条件的服务器列表: {server_list_str}",
|
191
193
|
)
|
192
194
|
s = random.choice(right_ip)
|
193
195
|
logger.info(f"最终选择的服务器: {s['host']}:{s['port']}")
|
@@ -211,11 +213,15 @@ async def tj_request(command: str = "云", tj="tj"):
|
|
211
213
|
|
212
214
|
|
213
215
|
async def server_find(
|
214
|
-
command: str = "
|
216
|
+
command: str = "",
|
215
217
|
_id: Optional[str] = None,
|
216
218
|
is_img: bool = True,
|
217
219
|
):
|
218
|
-
|
220
|
+
all_command = get_all_json_filenames()
|
221
|
+
server_json = []
|
222
|
+
for one_command in all_command:
|
223
|
+
server_j = _get_server_json(one_command, ALLHOST)
|
224
|
+
server_json.extend(server_j)
|
219
225
|
logger.info(server_json)
|
220
226
|
if server_json is None:
|
221
227
|
logger.warning("未找到这个组")
|
@@ -238,3 +244,19 @@ async def server_find(
|
|
238
244
|
if isinstance(out_msg, str):
|
239
245
|
return UniMessage.text(out_msg)
|
240
246
|
return None
|
247
|
+
|
248
|
+
|
249
|
+
def get_all_json_filenames():
|
250
|
+
"""
|
251
|
+
获取 server_all_path 路径下所有 json 文件的文件名(不带扩展名)的列表。
|
252
|
+
"""
|
253
|
+
json_files = []
|
254
|
+
for item in server_all_path.iterdir():
|
255
|
+
if item.is_file() and item.suffix == ".json":
|
256
|
+
json_files.append(item.stem)
|
257
|
+
return json_files
|
258
|
+
|
259
|
+
|
260
|
+
# 使用示例
|
261
|
+
|
262
|
+
# all_json_names 现在是一个包含所有 json 文件名(不带扩展名)的 list
|
@@ -1,5 +1,3 @@
|
|
1
|
-
import asyncio
|
2
|
-
|
3
1
|
# from logging import log
|
4
2
|
import io
|
5
3
|
from pathlib import Path
|
@@ -15,9 +13,9 @@ from ..utils.api.request import L4API
|
|
15
13
|
|
16
14
|
async def draw_one_ip(host: str, port: int, is_img: bool = config.l4_image):
|
17
15
|
"""输出单个ip"""
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
ser_list = await L4API.a2s_info([(host, port)], is_player=True)
|
17
|
+
if not ser_list or ser_list[0][0].max_players == 0:
|
18
|
+
# except asyncio.exceptions.TimeoutError:
|
21
19
|
return "服务器无响应"
|
22
20
|
one_server = ser_list[0][0]
|
23
21
|
one_player = ser_list[0][1]
|
@@ -40,15 +38,10 @@ async def draw_one_ip(host: str, port: int, is_img: bool = config.l4_image):
|
|
40
38
|
soc = "[{:>{}}]".format(player.score, max_score_len)
|
41
39
|
chines_dur = await convert_duration(player.duration)
|
42
40
|
dur = "{:^{}}".format(chines_dur, max_duration_len)
|
43
|
-
|
44
|
-
if name_leg > 2:
|
45
|
-
xing = ":)" * (name_leg - 2)
|
46
|
-
name = f"{player.name[0]}{xing}{player.name[-1]}"
|
47
|
-
else:
|
48
|
-
name = player.name
|
41
|
+
name = player.name
|
49
42
|
player_msg += f"{soc} | {dur} | {name} \n"
|
50
43
|
else:
|
51
|
-
player_msg = "
|
44
|
+
player_msg = "服务器感觉很安静啊\n"
|
52
45
|
return player_msg
|
53
46
|
|
54
47
|
def build_server_message(server, player_info: str) -> str:
|
@@ -59,13 +52,16 @@ async def draw_one_ip(host: str, port: int, is_img: bool = config.l4_image):
|
|
59
52
|
Returns:
|
60
53
|
完整的服务器信息字符串
|
61
54
|
"""
|
55
|
+
|
56
|
+
vac_status = "启用" if server.vac_enabled else "禁用"
|
62
57
|
msg = f"""-{server.server_name}-
|
63
58
|
游戏: {server.folder}
|
64
59
|
地图: {server.map_name}
|
65
|
-
人数: {server.player_count}/{server.max_players}"""
|
60
|
+
人数: {server.player_count} / {server.max_players}"""
|
66
61
|
if server.ping is not None:
|
67
62
|
msg += f"""
|
68
|
-
|
63
|
+
延迟: {server.ping * 1000:.0f} ms
|
64
|
+
VAC : {vac_status}\n
|
69
65
|
{player_info}"""
|
70
66
|
if config.l4_show_ip:
|
71
67
|
msg += f"""
|
@@ -112,7 +108,7 @@ connect {host}:{port}"""
|
|
112
108
|
|
113
109
|
# 计算图片尺寸
|
114
110
|
margin = 20
|
115
|
-
line_spacing =
|
111
|
+
line_spacing = 7
|
116
112
|
img_width = max(title_width, content_width) + 2 * margin
|
117
113
|
content_lines_count = len(content.split("\n")) if content else 0
|
118
114
|
img_height = max(
|
@@ -141,13 +137,87 @@ connect {host}:{port}"""
|
|
141
137
|
if content:
|
142
138
|
content_x = margin
|
143
139
|
content_y = title_y + title_height + margin
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
140
|
+
|
141
|
+
# 定义不同参数值的颜色(冒号后的内容)
|
142
|
+
value_colors = {
|
143
|
+
"游戏: ": (200, 180, 255), # 淡紫
|
144
|
+
"地图: ": (166, 202, 253), # 淡蓝
|
145
|
+
"人数: ": (100, 255, 100), # 绿色
|
146
|
+
"延迟: ": (100, 255, 100), # 绿色
|
147
|
+
"类型: ": (180, 220, 255), # 淡蓝
|
148
|
+
"密码: ": (255, 255, 255), # 白色
|
149
|
+
# connect不修改,保持原逻辑
|
150
|
+
}
|
151
|
+
|
152
|
+
# 按行绘制内容
|
153
|
+
current_y = content_y
|
154
|
+
for line in content_lines:
|
155
|
+
# 检查是否是参数行
|
156
|
+
colored = False
|
157
|
+
for prefix, color in value_colors.items():
|
158
|
+
if line.startswith(prefix):
|
159
|
+
# 绘制完整参数名(白色)
|
160
|
+
prefix_part = prefix
|
161
|
+
prefix_width = (
|
162
|
+
font.getbbox(prefix_part)[2]
|
163
|
+
- font.getbbox(prefix_part)[0]
|
164
|
+
)
|
165
|
+
draw.text(
|
166
|
+
(content_x, current_y),
|
167
|
+
prefix_part,
|
168
|
+
font=font,
|
169
|
+
fill=(255, 255, 255),
|
170
|
+
)
|
171
|
+
|
172
|
+
# 绘制参数值(带颜色)
|
173
|
+
value_part = line[len(prefix) :].strip()
|
174
|
+
draw.text(
|
175
|
+
(content_x + prefix_width, current_y),
|
176
|
+
value_part,
|
177
|
+
font=font,
|
178
|
+
fill=color,
|
179
|
+
)
|
180
|
+
|
181
|
+
colored = True
|
182
|
+
break
|
183
|
+
# 特殊处理VAC行
|
184
|
+
if not colored and line.startswith("VAC :"):
|
185
|
+
prefix = "VAC : "
|
186
|
+
prefix_width = (
|
187
|
+
font.getbbox(prefix)[2] - font.getbbox(prefix)[0]
|
188
|
+
)
|
189
|
+
draw.text(
|
190
|
+
(content_x, current_y),
|
191
|
+
prefix,
|
192
|
+
font=font,
|
193
|
+
fill=(255, 255, 255),
|
194
|
+
)
|
195
|
+
|
196
|
+
value_part = line[len(prefix) :].strip()
|
197
|
+
vac_color = (
|
198
|
+
(70, 209, 110)
|
199
|
+
if value_part == "启用"
|
200
|
+
else (255, 90, 90)
|
201
|
+
) # 启用绿/禁用红
|
202
|
+
draw.text(
|
203
|
+
(content_x + prefix_width, current_y),
|
204
|
+
value_part,
|
205
|
+
font=font,
|
206
|
+
fill=vac_color,
|
207
|
+
)
|
208
|
+
|
209
|
+
colored = True
|
210
|
+
|
211
|
+
# 普通行(玩家信息)和connect保持原样
|
212
|
+
if not colored:
|
213
|
+
draw.text(
|
214
|
+
(content_x, current_y),
|
215
|
+
line,
|
216
|
+
font=font,
|
217
|
+
fill=(255, 255, 255),
|
218
|
+
)
|
219
|
+
|
220
|
+
current_y += line_height + line_spacing
|
151
221
|
|
152
222
|
return img
|
153
223
|
except Exception as e:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Dict, List, Optional, Tuple, Union
|
1
|
+
from typing import Dict, List, Optional, Tuple, Union
|
2
2
|
|
3
3
|
from nonebot.log import logger
|
4
4
|
|
@@ -22,11 +22,13 @@ def _get_server_json(
|
|
22
22
|
Returns:
|
23
23
|
Optional[list]: 服务器JSON列表,未找到组时返回None
|
24
24
|
"""
|
25
|
+
logger.debug(f"获取服务器组 {allhost} 的信息")
|
25
26
|
if command:
|
26
27
|
return allhost.get(command)
|
27
28
|
server_json = []
|
28
29
|
for servers in allhost.values():
|
29
30
|
server_json.extend(servers)
|
31
|
+
logger.debug(f"获取到的服务器组信息: {server_json}")
|
30
32
|
return server_json
|
31
33
|
|
32
34
|
|
@@ -95,10 +97,7 @@ async def _handle_single_server(
|
|
95
97
|
return None
|
96
98
|
|
97
99
|
host, port = server_info
|
98
|
-
|
99
|
-
if is_img:
|
100
|
-
return cast(bytes, out_msg)
|
101
|
-
return out_msg
|
100
|
+
return await draw_one_ip(host, port, is_img=is_img)
|
102
101
|
|
103
102
|
|
104
103
|
async def _filter_servers(
|
@@ -13,6 +13,29 @@ from nonebot.log import logger
|
|
13
13
|
from nonebot_plugin_alconna import UniMessage
|
14
14
|
|
15
15
|
|
16
|
+
async def log_and_send(matcher, message: str, level="info"):
|
17
|
+
getattr(logger, level)(message)
|
18
|
+
await matcher.finish(UniMessage.text(message))
|
19
|
+
|
20
|
+
|
21
|
+
def read_config(config_path: Path) -> dict:
|
22
|
+
if not config_path.is_file():
|
23
|
+
return {}
|
24
|
+
try:
|
25
|
+
with config_path.open("r", encoding="utf-8") as f:
|
26
|
+
return json.load(f)
|
27
|
+
except (json.JSONDecodeError, FileNotFoundError):
|
28
|
+
return {}
|
29
|
+
|
30
|
+
|
31
|
+
def write_config(config_path: Path, data: dict) -> None:
|
32
|
+
try:
|
33
|
+
with config_path.open("w", encoding="utf-8") as f:
|
34
|
+
json.dump(data, f, ensure_ascii=False, indent=4)
|
35
|
+
except IOError as e:
|
36
|
+
raise RuntimeError(f"配置写入失败: {e}") from e
|
37
|
+
|
38
|
+
|
16
39
|
async def get_file(url: str, down_file: Path):
|
17
40
|
"""
|
18
41
|
下载指定Url到指定位置
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|