nonebot-plugin-l4d2-server 0.6.6__py3-none-any.whl → 1.0.0a2__py3-none-any.whl
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/__init__.py +10 -93
- nonebot_plugin_l4d2_server/__main__.py +140 -0
- nonebot_plugin_l4d2_server/config.py +35 -0
- nonebot_plugin_l4d2_server/data/font/loli.ttf +0 -0
- nonebot_plugin_l4d2_server/l4_anne/__init__.py +124 -0
- nonebot_plugin_l4d2_server/l4_anne/ranne.py +18 -0
- nonebot_plugin_l4d2_server/l4_help/Help.json +102 -0
- nonebot_plugin_l4d2_server/l4_help/__init__.py +57 -0
- nonebot_plugin_l4d2_server/l4_help/draw.py +206 -0
- nonebot_plugin_l4d2_server/l4_help/icon//344/273/213/347/273/215.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//344/273/273/345/212/241.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//344/277/241/346/201/257.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/205/254/345/221/212.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/210/200/345/211/221.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/210/207/346/215/242.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/210/240/351/231/244.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/210/267/346/226/260.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/215/241/347/273/204.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/223/252/351/207/214.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/234/260/345/233/276.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/257/274/345/205/245.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/257/274/345/207/272.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//345/275/261.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/213/274/345/233/276.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/216/242/347/264/242.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/216/250/351/200/201.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/224/266/351/233/206.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/224/273/347/225/245.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/233/264/346/226/260.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/235/220/346/226/231.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/237/245/350/257/242.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/240/241/351/252/214.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/257/217/346/234/210.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/267/261/346/270/212.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/267/273/345/212/240.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//346/270/205/351/231/244.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//347/212/266/346/200/201.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//347/255/276/345/210/260.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//347/273/221/345/256/232.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//350/241/250.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//350/241/250/346/203/205.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//350/247/222/350/211/262.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//350/256/260/345/275/225.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//351/205/215/347/275/256.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/icon//351/207/215/345/220/257.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/texture2d/badge.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/texture2d/banner.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/texture2d/bg.jpg +0 -0
- nonebot_plugin_l4d2_server/l4_help/texture2d/button.png +0 -0
- nonebot_plugin_l4d2_server/l4_help/texture2d/icon.png +0 -0
- nonebot_plugin_l4d2_server/l4_image/__init__.py +16 -0
- nonebot_plugin_l4d2_server/l4_image/anne_pil.py +17 -0
- nonebot_plugin_l4d2_server/l4_image/convert.py +175 -0
- nonebot_plugin_l4d2_server/{l4d2_image → l4_image}/download.py +11 -35
- nonebot_plugin_l4d2_server/l4_image/html_img.py +105 -0
- nonebot_plugin_l4d2_server/l4_image/image_tools.py +468 -0
- nonebot_plugin_l4d2_server/{data/L4D2/image/template → l4_image/img/anne}/back.png +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/anne/back1.jpg +0 -0
- nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/head/head.png +0 -0
- nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/header/logo.png +0 -0
- nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/header/player1.jpg +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Bocchi_The_Rock.html +299 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Bocchi_The_Rock.png +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/HYPixel11pxU-2.ttf +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Pixel.html +341 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Pixel.png +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Rainbow.html +355 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Rainbow.png +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/Tutumianhuatang-Bold-2.ttf +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/bilibili.svg +1 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/github.svg +1 -0
- nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/template/l.svg +0 -1
- nonebot_plugin_l4d2_server/l4_image/img/template/m.svg +1 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/normal.html +247 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/vac.png +0 -0
- nonebot_plugin_l4d2_server/l4_image/img/template/vac_white.png +0 -0
- nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/template/w.svg +1 -1
- nonebot_plugin_l4d2_server/l4_image/model.py +15 -0
- nonebot_plugin_l4d2_server/{l4d2_image → l4_image}/vtfs.py +4 -2
- nonebot_plugin_l4d2_server/l4_request/__init__.py +143 -0
- nonebot_plugin_l4d2_server/l4_request/draw_msg.py +83 -0
- nonebot_plugin_l4d2_server/utils/api/api.py +10 -0
- nonebot_plugin_l4d2_server/utils/api/models.py +137 -0
- nonebot_plugin_l4d2_server/utils/api/request.py +337 -0
- nonebot_plugin_l4d2_server/utils/database/models.py +18 -0
- nonebot_plugin_l4d2_server/{l4d2_utils → utils}/utils.py +60 -63
- {nonebot_plugin_l4d2_server-0.6.6.dist-info → nonebot_plugin_l4d2_server-1.0.0a2.dist-info}/METADATA +57 -66
- nonebot_plugin_l4d2_server-1.0.0a2.dist-info/RECORD +96 -0
- {nonebot_plugin_l4d2_server-0.6.6.dist-info → nonebot_plugin_l4d2_server-1.0.0a2.dist-info}/WHEEL +1 -1
- nonebot_plugin_l4d2_server/data/L4D2/image/template/help.html +0 -263
- nonebot_plugin_l4d2_server/data/L4D2/image/template/help_dack.html +0 -231
- nonebot_plugin_l4d2_server/data/L4D2/image/template/m.svg +0 -1
- nonebot_plugin_l4d2_server/data/img/white.png +0 -0
- nonebot_plugin_l4d2_server/l4d2_anne/__init__.py +0 -95
- nonebot_plugin_l4d2_server/l4d2_anne/analysis.py +0 -54
- nonebot_plugin_l4d2_server/l4d2_anne/anne_telecom.py +0 -79
- nonebot_plugin_l4d2_server/l4d2_anne/server.py +0 -47
- nonebot_plugin_l4d2_server/l4d2_anne/startand.py +0 -17
- nonebot_plugin_l4d2_server/l4d2_anne/utils.py +0 -294
- nonebot_plugin_l4d2_server/l4d2_data/__init__.py +0 -105
- nonebot_plugin_l4d2_server/l4d2_data/config.py +0 -18
- nonebot_plugin_l4d2_server/l4d2_data/players.py +0 -100
- nonebot_plugin_l4d2_server/l4d2_data/serverip.py +0 -40
- nonebot_plugin_l4d2_server/l4d2_file/__init__.py +0 -222
- nonebot_plugin_l4d2_server/l4d2_file/ayromote.py +0 -64
- nonebot_plugin_l4d2_server/l4d2_file/input_json.py +0 -77
- nonebot_plugin_l4d2_server/l4d2_file/remote.py +0 -86
- nonebot_plugin_l4d2_server/l4d2_file/utils.py +0 -104
- nonebot_plugin_l4d2_server/l4d2_image/__init__.py +0 -125
- nonebot_plugin_l4d2_server/l4d2_image/htmlimg.py +0 -18
- nonebot_plugin_l4d2_server/l4d2_image/images.py +0 -92
- nonebot_plugin_l4d2_server/l4d2_image/one.py +0 -44
- nonebot_plugin_l4d2_server/l4d2_image/send_image_tool.py +0 -32
- nonebot_plugin_l4d2_server/l4d2_image/steam.py +0 -63
- nonebot_plugin_l4d2_server/l4d2_push/__init__.py +0 -225
- nonebot_plugin_l4d2_server/l4d2_queries/__init__.py +0 -326
- nonebot_plugin_l4d2_server/l4d2_queries/himi.py +0 -113
- nonebot_plugin_l4d2_server/l4d2_queries/local_ip.py +0 -41
- nonebot_plugin_l4d2_server/l4d2_queries/qqgroup.py +0 -370
- nonebot_plugin_l4d2_server/l4d2_queries/send_msg.py +0 -131
- nonebot_plugin_l4d2_server/l4d2_queries/utils.py +0 -212
- nonebot_plugin_l4d2_server/l4d2_server/__init__.py +0 -118
- nonebot_plugin_l4d2_server/l4d2_server/index.py +0 -0
- nonebot_plugin_l4d2_server/l4d2_server/rcon.py +0 -53
- nonebot_plugin_l4d2_server/l4d2_server/workshop.py +0 -82
- nonebot_plugin_l4d2_server/l4d2_update/__init__.py +0 -137
- nonebot_plugin_l4d2_server/l4d2_update/draw_update_log.py +0 -45
- nonebot_plugin_l4d2_server/l4d2_update/restart.py +0 -69
- nonebot_plugin_l4d2_server/l4d2_update/update.py +0 -53
- nonebot_plugin_l4d2_server/l4d2_utils/classcal.py +0 -53
- nonebot_plugin_l4d2_server/l4d2_utils/command.py +0 -23
- nonebot_plugin_l4d2_server/l4d2_utils/config.py +0 -201
- nonebot_plugin_l4d2_server/l4d2_utils/message.py +0 -59
- nonebot_plugin_l4d2_server/l4d2_utils/rule.py +0 -35
- nonebot_plugin_l4d2_server/l4d2_utils/seach.py +0 -43
- nonebot_plugin_l4d2_server/l4d2_utils/txt_to_img.py +0 -32
- nonebot_plugin_l4d2_server/l4d2_web/web.py +0 -277
- nonebot_plugin_l4d2_server/l4d2_web/webUI.py +0 -506
- nonebot_plugin_l4d2_server/l4d2_web/webUI_s.py +0 -94
- nonebot_plugin_l4d2_server-0.6.6.dist-info/RECORD +0 -70
- /nonebot_plugin_l4d2_server/{data/L4D2/image/template → l4_image/img/anne}/anne.html +0 -0
- /nonebot_plugin_l4d2_server/{data/L4D2/image/template → l4_image/img/anne}/group_ip.html +0 -0
- /nonebot_plugin_l4d2_server/{data/L4D2/image/template → l4_image/img/anne}/ip.html +0 -0
- /nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/template/fingerprint.svg +0 -0
- /nonebot_plugin_l4d2_server/{data/L4D2/image → l4_image/img}/template/vue.css +0 -0
- /nonebot_plugin_l4d2_server/{l4d2_data/database.py → l4_request/utils.py} +0 -0
- {nonebot_plugin_l4d2_server-0.6.6.dist-info → nonebot_plugin_l4d2_server-1.0.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -1,222 +0,0 @@
|
|
1
|
-
import re
|
2
|
-
from pathlib import Path
|
3
|
-
from typing import Tuple
|
4
|
-
|
5
|
-
from nonebot import on_command, on_regex
|
6
|
-
from nonebot.adapters.onebot.v11 import Event, Message, NoticeEvent
|
7
|
-
from nonebot.log import logger
|
8
|
-
from nonebot.matcher import Matcher
|
9
|
-
from nonebot.params import ArgPlainText, CommandArg, RegexGroup
|
10
|
-
|
11
|
-
# from nonebot.typing import T_State
|
12
|
-
from ..l4d2_utils.config import MASTER, config_manager, file_format, l4_config, vpk_path
|
13
|
-
from ..l4d2_utils.rule import wenjian
|
14
|
-
from ..l4d2_utils.txt_to_img import mode_txt_to_img
|
15
|
-
from ..l4d2_utils.utils import del_map, get_vpk, mes_list, rename_map
|
16
|
-
from .input_json import upload # noqa: F401
|
17
|
-
from .utils import updown_l4d2_vpk
|
18
|
-
|
19
|
-
up = on_command(
|
20
|
-
"l4_upload",
|
21
|
-
aliases={"l4地图上传"},
|
22
|
-
priority=20,
|
23
|
-
block=True,
|
24
|
-
)
|
25
|
-
|
26
|
-
|
27
|
-
rename_vpk = on_regex(
|
28
|
-
r"^l4地图\s*(\S+.*?)\s*(改|改名)?\s*(\S+.*?)\s*$",
|
29
|
-
flags=re.S,
|
30
|
-
block=True,
|
31
|
-
priority=20,
|
32
|
-
permission=MASTER,
|
33
|
-
)
|
34
|
-
|
35
|
-
find_vpk = on_command("l4_map", aliases={"l4地图"}, priority=25, block=True)
|
36
|
-
del_vpk = on_command(
|
37
|
-
"l4_del_map",
|
38
|
-
aliases={"l4地图删除", "地图删除"},
|
39
|
-
priority=20,
|
40
|
-
permission=MASTER,
|
41
|
-
)
|
42
|
-
|
43
|
-
|
44
|
-
check_path = on_command(
|
45
|
-
"l4_check",
|
46
|
-
aliases={"l4路径"},
|
47
|
-
priority=20,
|
48
|
-
block=True,
|
49
|
-
permission=MASTER,
|
50
|
-
)
|
51
|
-
smx_file = on_command(
|
52
|
-
"l4_smx",
|
53
|
-
aliases={"l4插件"},
|
54
|
-
priority=20,
|
55
|
-
block=True,
|
56
|
-
permission=MASTER,
|
57
|
-
)
|
58
|
-
|
59
|
-
|
60
|
-
@up.handle()
|
61
|
-
async def _(): ...
|
62
|
-
|
63
|
-
|
64
|
-
@up.got("map_url", prompt="图来")
|
65
|
-
async def _(matcher: Matcher, event: Event):
|
66
|
-
if not isinstance(event, NoticeEvent) or not wenjian(event):
|
67
|
-
await matcher.finish("未检测到地图")
|
68
|
-
return
|
69
|
-
args = event.dict()
|
70
|
-
if args["notice_type"] != "offline_file":
|
71
|
-
matcher.set_arg("txt", args) # type: ignore
|
72
|
-
return
|
73
|
-
l4_file_path = l4_config.l4_ipall[l4_config.l4_number]["location"]
|
74
|
-
map_path = Path(l4_file_path, vpk_path) # type: ignore
|
75
|
-
# 检查下载路径是否存在
|
76
|
-
if not Path(l4_file_path).exists(): # type: ignore
|
77
|
-
await matcher.finish("你填写的路径不存在辣")
|
78
|
-
if not Path(map_path).exists():
|
79
|
-
await matcher.finish("这个路径并不是求生服务器的路径,请再看看罢")
|
80
|
-
url: str = args["file"]["url"]
|
81
|
-
name: str = args["file"]["name"]
|
82
|
-
# 如果不符合格式则忽略
|
83
|
-
await up.send("已收到文件,开始下载")
|
84
|
-
vpk_files = await updown_l4d2_vpk(map_path, name, url)
|
85
|
-
if vpk_files:
|
86
|
-
mes = "解压成功,新增以下几个vpk文件"
|
87
|
-
await matcher.finish(mes_list(mes, vpk_files))
|
88
|
-
else:
|
89
|
-
await matcher.finish("你可能上传了相同的文件,或者解压失败了捏")
|
90
|
-
|
91
|
-
|
92
|
-
path_list: str = "请选择上传位置(输入阿拉伯数字)"
|
93
|
-
times = 0
|
94
|
-
for one_path in l4_config.l4_ipall:
|
95
|
-
times += 1
|
96
|
-
path_msg = one_path["location"]
|
97
|
-
path_list += f"\n {times!s} | {path_msg}"
|
98
|
-
|
99
|
-
|
100
|
-
@up.got("is_sure", prompt=path_list)
|
101
|
-
async def _(matcher: Matcher):
|
102
|
-
args = matcher.get_arg("txt")
|
103
|
-
l4_file = l4_config.l4_ipall
|
104
|
-
if args is None:
|
105
|
-
await matcher.finish("获取文件出错辣,再试一次吧")
|
106
|
-
return
|
107
|
-
|
108
|
-
is_sure = str(matcher.get_arg("is_sure")).strip()
|
109
|
-
if not is_sure.isdigit():
|
110
|
-
await matcher.finish("已取消上传")
|
111
|
-
|
112
|
-
file_path: str = ""
|
113
|
-
for one_server in l4_file:
|
114
|
-
if one_server["id_rank"] == is_sure:
|
115
|
-
file_path = one_server["location"]
|
116
|
-
if not file_path:
|
117
|
-
await matcher.finish("没有这个序号拉baka")
|
118
|
-
|
119
|
-
map_path = Path(file_path, vpk_path)
|
120
|
-
|
121
|
-
# 检查下载路径是否存在
|
122
|
-
if not Path(file_path).exists():
|
123
|
-
await matcher.finish("你填写的路径不存在辣")
|
124
|
-
if not map_path.exists():
|
125
|
-
await matcher.finish("这个路径并不是求生服务器的路径,请再看看罢")
|
126
|
-
|
127
|
-
url = args["file"]["url"]
|
128
|
-
name = args["file"]["name"]
|
129
|
-
# 如果不符合格式则忽略
|
130
|
-
if not name.endswith(file_format): # type: ignore
|
131
|
-
return
|
132
|
-
|
133
|
-
await matcher.send("已收到文件,开始下载")
|
134
|
-
vpk_files = await updown_l4d2_vpk(map_path, name, url) # type: ignore
|
135
|
-
|
136
|
-
if vpk_files:
|
137
|
-
logger.info("检查到新增文件")
|
138
|
-
mes = "解压成功,新增以下几个vpk文件"
|
139
|
-
elif vpk_files is None:
|
140
|
-
await matcher.finish("文件错误")
|
141
|
-
return
|
142
|
-
else:
|
143
|
-
mes = "你可能上传了相同的文件,或者解压失败了捏"
|
144
|
-
|
145
|
-
await matcher.finish(mes_list(mes, vpk_files))
|
146
|
-
|
147
|
-
|
148
|
-
@find_vpk.handle()
|
149
|
-
async def _():
|
150
|
-
map_path = Path(l4_config.l4_ipall[l4_config.l4_number]["location"], vpk_path)
|
151
|
-
name_vpk = get_vpk(map_path)
|
152
|
-
logger.info("获取文件列表成功")
|
153
|
-
mes = "当前服务器下有以下vpk文件"
|
154
|
-
msg = mes_list("", name_vpk).replace(" ", "")
|
155
|
-
|
156
|
-
await mode_txt_to_img(mes, msg)
|
157
|
-
|
158
|
-
|
159
|
-
@del_vpk.handle()
|
160
|
-
async def _(matcher: Matcher, args: Message = CommandArg()):
|
161
|
-
num1 = args.extract_plain_text()
|
162
|
-
if num1:
|
163
|
-
matcher.set_arg("num", args)
|
164
|
-
|
165
|
-
|
166
|
-
@del_vpk.got("num", prompt="你要删除第几个序号的地图(阿拉伯数字)")
|
167
|
-
async def _(matcher: Matcher, tag: str = ArgPlainText("num")):
|
168
|
-
map_path = Path(l4_config.l4_ipall[l4_config.l4_number]["location"], vpk_path)
|
169
|
-
vpk_name = del_map(int(tag), map_path)
|
170
|
-
await matcher.finish("已删除地图:" + vpk_name)
|
171
|
-
|
172
|
-
|
173
|
-
@rename_vpk.handle()
|
174
|
-
async def _(
|
175
|
-
matcher: Matcher,
|
176
|
-
matched: Tuple[int, str, str] = RegexGroup(),
|
177
|
-
):
|
178
|
-
num, useless, rename = matched
|
179
|
-
map_path = Path(l4_config.l4_ipall[l4_config.l4_number]["location"], vpk_path)
|
180
|
-
logger.info("检查是否名字是.vpk后缀")
|
181
|
-
if not rename.endswith(".vpk"):
|
182
|
-
rename = rename + ".vpk"
|
183
|
-
logger.info("尝试改名")
|
184
|
-
try:
|
185
|
-
map_name = rename_map(num, rename, map_path)
|
186
|
-
if map_name:
|
187
|
-
await matcher.finish("改名成功\n原名:" + map_name + "\n新名称:" + rename)
|
188
|
-
except ValueError:
|
189
|
-
await matcher.finish("参数错误,输入【求生地图】获取全部名称")
|
190
|
-
|
191
|
-
|
192
|
-
@check_path.handle()
|
193
|
-
async def _(matcher: Matcher, args: Message = CommandArg()):
|
194
|
-
msg = args.extract_plain_text()
|
195
|
-
if msg.startswith("切换"):
|
196
|
-
msg_number = int("".join(msg.replace("切换", " ").split()))
|
197
|
-
if msg_number > len(l4_config.l4_ipall) or msg_number < 0:
|
198
|
-
await matcher.send("没有这个序号的路径呐")
|
199
|
-
else:
|
200
|
-
l4_config.l4_number = msg_number - 1
|
201
|
-
now_path = l4_config.l4_ipall[l4_config.l4_number]["location"]
|
202
|
-
await matcher.send(
|
203
|
-
f"已经切换路径为\n{l4_config.l4_number+1!s}、{now_path}",
|
204
|
-
) # noqa: E501
|
205
|
-
config_manager.save()
|
206
|
-
else:
|
207
|
-
now_path = l4_config.l4_ipall[l4_config.l4_number]["location"]
|
208
|
-
await matcher.send(f"当前的路径为\n{l4_config.l4_number+1!s}、{now_path}")
|
209
|
-
|
210
|
-
|
211
|
-
@smx_file.handle()
|
212
|
-
async def _():
|
213
|
-
smx_path = Path(
|
214
|
-
l4_config.l4_ipall[l4_config.l4_number]["location"],
|
215
|
-
"left4dead2/addons/sourcemod/plugins",
|
216
|
-
)
|
217
|
-
name_smx = get_vpk(smx_path, file_=".smx")
|
218
|
-
logger.info("获取文件列表成功")
|
219
|
-
mes = "当前服务器下有以下smx文件"
|
220
|
-
msg = ""
|
221
|
-
msg = mes_list(msg, name_smx).replace(" ", "")
|
222
|
-
await mode_txt_to_img(mes, msg)
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# import asyncio
|
2
|
-
# import asyncssh
|
3
|
-
|
4
|
-
|
5
|
-
# class AsyncSSHClient:
|
6
|
-
# def __init__(self, host, port, username, password=None, private_key=None):
|
7
|
-
# self.host = host
|
8
|
-
# self.port = port
|
9
|
-
# self.username = username
|
10
|
-
# self.password = password
|
11
|
-
# self.private_key = private_key
|
12
|
-
|
13
|
-
# async def connect(self):
|
14
|
-
# if self.private_key is not None:
|
15
|
-
# try:
|
16
|
-
# key = asyncssh.read_private_key(self.private_key)
|
17
|
-
# except asyncssh.Error as exc:
|
18
|
-
# raise ValueError(f"Unable to read private key: {exc}")
|
19
|
-
# else:
|
20
|
-
# key = None
|
21
|
-
|
22
|
-
# self.conn = await asyncssh.connect(
|
23
|
-
# self.host,
|
24
|
-
# self.port,
|
25
|
-
# username=self.username,
|
26
|
-
# password=self.password,
|
27
|
-
# client_keys=key,
|
28
|
-
# )
|
29
|
-
|
30
|
-
# async def upload(self, local_path, remote_path):
|
31
|
-
# async with self.conn.sftp() as sftp:
|
32
|
-
# await sftp.put(local_path, remote_path)
|
33
|
-
|
34
|
-
# async def delete(self, remote_path):
|
35
|
-
# async with self.conn.sftp() as sftp:
|
36
|
-
# await sftp.remove(remote_path)
|
37
|
-
|
38
|
-
# async def listdir(self, remote_path):
|
39
|
-
# async with self.conn.sftp() as sftp:
|
40
|
-
# return await sftp.listdir(remote_path)
|
41
|
-
|
42
|
-
# async def close(self):
|
43
|
-
# self.conn.close()
|
44
|
-
|
45
|
-
|
46
|
-
# async def remote(
|
47
|
-
# mode: str,
|
48
|
-
# host: str,
|
49
|
-
# user: str,
|
50
|
-
# password: str,
|
51
|
-
# local_path="",
|
52
|
-
# port=22,
|
53
|
-
# remote_path="",
|
54
|
-
# ):
|
55
|
-
# """mode:upload、read、del"""
|
56
|
-
# client = AsyncSSHClient(host, port, user, password)
|
57
|
-
# await client.connect()
|
58
|
-
# if mode == "upload":
|
59
|
-
# await client.upload(local_path, remote_path)
|
60
|
-
# elif mode == "read":
|
61
|
-
# file = await client.read(remote_path)
|
62
|
-
# return file
|
63
|
-
# elif mode == "del":
|
64
|
-
# await client.delete(remote_path)
|
@@ -1,77 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
from pathlib import Path
|
3
|
-
from typing import Dict, List
|
4
|
-
|
5
|
-
from nonebot import on_notice
|
6
|
-
from nonebot.adapters.onebot.v11 import NoticeEvent
|
7
|
-
from nonebot.log import logger
|
8
|
-
from nonebot.matcher import Matcher
|
9
|
-
|
10
|
-
from ..l4d2_image.steam import url_to_msg
|
11
|
-
|
12
|
-
upload = on_notice(priority=1)
|
13
|
-
|
14
|
-
|
15
|
-
@upload.handle()
|
16
|
-
async def _(matcher: Matcher, event: NoticeEvent):
|
17
|
-
try:
|
18
|
-
arg = event.dict()
|
19
|
-
files: dict = arg["file"]
|
20
|
-
name: str = files["name"]
|
21
|
-
if arg["notice_type"] == "offline_file" and name.endswith(".json"):
|
22
|
-
try:
|
23
|
-
msg = await url_to_msg(files["url"])
|
24
|
-
if not msg:
|
25
|
-
return
|
26
|
-
jsons: Dict[str, List[Dict[str, str]]] = json.loads(msg)
|
27
|
-
except json.decoder:
|
28
|
-
logger.info("求生json格式不正确")
|
29
|
-
await matcher.finish("求生json格式不正确")
|
30
|
-
return
|
31
|
-
if not validate_json(jsons):
|
32
|
-
logger.info("求生json格式不正确")
|
33
|
-
await matcher.finish("求生json格式不正确")
|
34
|
-
print(name)
|
35
|
-
key = await up_date(jsons, name)
|
36
|
-
if key:
|
37
|
-
# logger.info(jsons)
|
38
|
-
msg = "输入成功\n"
|
39
|
-
for key, value in jsons.items():
|
40
|
-
msg += f"【{key}】指令:{len(value)}个\n"
|
41
|
-
logger.info(msg)
|
42
|
-
await matcher.send(msg)
|
43
|
-
except KeyError:
|
44
|
-
pass
|
45
|
-
|
46
|
-
|
47
|
-
async def validate_json(json_data):
|
48
|
-
try:
|
49
|
-
data = json.loads(json_data)
|
50
|
-
if not isinstance(data, dict):
|
51
|
-
return False
|
52
|
-
|
53
|
-
for key, value in data.items():
|
54
|
-
if not isinstance(value, list):
|
55
|
-
return False
|
56
|
-
for item in value:
|
57
|
-
if not isinstance(item, dict):
|
58
|
-
return False
|
59
|
-
if not all(key in item for key in ["id", "ip"]):
|
60
|
-
return False
|
61
|
-
if True:
|
62
|
-
return True
|
63
|
-
|
64
|
-
except json.JSONDecodeError:
|
65
|
-
return False
|
66
|
-
|
67
|
-
|
68
|
-
async def up_date(data: Dict[str, List[Dict[str, str]]], name: str):
|
69
|
-
print(data)
|
70
|
-
directory = Path("data/L4D2/l4d2")
|
71
|
-
directory.mkdir(parents=True, exist_ok=True)
|
72
|
-
|
73
|
-
file_path = directory / name
|
74
|
-
with file_path.open("w") as json_file:
|
75
|
-
json.dump(data, json_file)
|
76
|
-
|
77
|
-
return True
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# import asyncio
|
2
|
-
# import paramiko
|
3
|
-
|
4
|
-
|
5
|
-
# class SSHClient:
|
6
|
-
# def __init__(self, hostname, port, username, password):
|
7
|
-
# self._hostname = hostname
|
8
|
-
# self._port = port
|
9
|
-
# self._username = username
|
10
|
-
# self._password = password
|
11
|
-
# self._ssh = None
|
12
|
-
|
13
|
-
# async def connect(self):
|
14
|
-
# self._ssh = paramiko.SSHClient()
|
15
|
-
# self._ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
16
|
-
# await asyncio.get_event_loop().run_in_executor(
|
17
|
-
# None,
|
18
|
-
# self._ssh.connect,
|
19
|
-
# self._hostname,
|
20
|
-
# self._port,
|
21
|
-
# self._username,
|
22
|
-
# self._password,
|
23
|
-
# )
|
24
|
-
|
25
|
-
# async def upload(self, local_file_path, remote_file_path):
|
26
|
-
# with paramiko.Transport((self._hostname, self._port)) as transport:
|
27
|
-
# await asyncio.get_event_loop().run_in_executor(
|
28
|
-
# None, transport.connect, None, self._username, self._password
|
29
|
-
# )
|
30
|
-
# sftp = paramiko.SFTPClient.from_transport(transport)
|
31
|
-
# await asyncio.get_event_loop().run_in_executor(
|
32
|
-
# None, sftp.put, local_file_path, remote_file_path
|
33
|
-
# )
|
34
|
-
|
35
|
-
# async def delete(self, remote_file_path):
|
36
|
-
# with paramiko.Transport((self._hostname, self._port)) as transport:
|
37
|
-
# await asyncio.get_event_loop().run_in_executor(
|
38
|
-
# None, transport.connect, None, self._username, self._password
|
39
|
-
# )
|
40
|
-
# sftp = paramiko.SFTPClient.from_transport(transport)
|
41
|
-
# await asyncio.get_event_loop().run_in_executor(
|
42
|
-
# None, sftp.remove, remote_file_path
|
43
|
-
# )
|
44
|
-
|
45
|
-
# async def read(self, remote_dir_path):
|
46
|
-
# with paramiko.Transport((self._hostname, self._port)) as transport:
|
47
|
-
# await asyncio.get_event_loop().run_in_executor(
|
48
|
-
# None, transport.connect, None, self._username, self._password
|
49
|
-
# )
|
50
|
-
# sftp = paramiko.SFTPClient.from_transport(transport)
|
51
|
-
# return await asyncio.get_event_loop().run_in_executor(
|
52
|
-
# None, sftp.listdir, remote_dir_path
|
53
|
-
# )
|
54
|
-
|
55
|
-
# async def close(self):
|
56
|
-
# if self._ssh is not None:
|
57
|
-
# self._ssh.close()
|
58
|
-
|
59
|
-
|
60
|
-
# async def main():
|
61
|
-
# ssh = SSHClient("example.com", 22, "username", "password")
|
62
|
-
# await ssh.connect()
|
63
|
-
|
64
|
-
# await ssh.upload("/path/to/local/file", "/path/to/remote/file")
|
65
|
-
# await ssh.delete("/path/to/remote/file")
|
66
|
-
# files = await ssh.list("/path/to/remote/directory")
|
67
|
-
# print(files)
|
68
|
-
|
69
|
-
# await ssh.close()
|
70
|
-
|
71
|
-
# if __name__ == '__main__':
|
72
|
-
# asyncio.run(main())
|
73
|
-
|
74
|
-
|
75
|
-
# async def remote(
|
76
|
-
# mode: str, host, user, password, local_path="", port=22, remote_path=""
|
77
|
-
# ):
|
78
|
-
# """mode:upload、read、del"""
|
79
|
-
# client = SSHClient(host, port, user, password)
|
80
|
-
# if mode == "upload":
|
81
|
-
# await client.upload(local_path, remote_path)
|
82
|
-
# elif mode == "read":
|
83
|
-
# file = await client.read(remote_path)
|
84
|
-
# return file
|
85
|
-
# elif mode == "del":
|
86
|
-
# await client.delete(remote_path)
|
@@ -1,104 +0,0 @@
|
|
1
|
-
import io
|
2
|
-
import zipfile
|
3
|
-
from pathlib import Path
|
4
|
-
from typing import Callable, Dict, List
|
5
|
-
from zipfile import ZipFile
|
6
|
-
|
7
|
-
import rarfile
|
8
|
-
from nonebot.log import logger
|
9
|
-
from pyunpack import Archive
|
10
|
-
|
11
|
-
from ..l4d2_utils.config import systems
|
12
|
-
from ..l4d2_utils.utils import get_file, get_vpk
|
13
|
-
|
14
|
-
|
15
|
-
async def updown_l4d2_vpk(map_paths: Path, name: str, url: str):
|
16
|
-
"""从url下载压缩包并解压到位置"""
|
17
|
-
original_vpk_files = get_vpk(map_paths)
|
18
|
-
down_file = Path(map_paths, name)
|
19
|
-
if await get_file(url, down_file) is None:
|
20
|
-
return None
|
21
|
-
msg = open_packet(name, down_file)
|
22
|
-
logger.info(msg)
|
23
|
-
|
24
|
-
extracted_vpk_files = get_vpk(map_paths)
|
25
|
-
# 获取新增vpk文件的list
|
26
|
-
return list(set(extracted_vpk_files) - set(original_vpk_files))
|
27
|
-
|
28
|
-
|
29
|
-
SUPPORTED_EXTENSIONS = (".zip", ".7z", ".rar")
|
30
|
-
|
31
|
-
|
32
|
-
def unzip_zipfile(down_file: Path, down_path: Path):
|
33
|
-
"""解压zip文件"""
|
34
|
-
with support_gbk(zipfile.ZipFile(down_file, "r")) as z:
|
35
|
-
z.extractall(down_path)
|
36
|
-
down_file.unlink()
|
37
|
-
|
38
|
-
|
39
|
-
def unpack_7zfile(down_file: Path, down_path: Path):
|
40
|
-
"""解压7z文件"""
|
41
|
-
Archive(str(down_file)).extractall(str(down_path))
|
42
|
-
down_file.unlink()
|
43
|
-
|
44
|
-
|
45
|
-
def unpack_rarfile(down_file: Path, down_path: Path):
|
46
|
-
"""解压rar文件"""
|
47
|
-
with rarfile.RarFile(down_file, "r") as z:
|
48
|
-
z.extractall(down_path)
|
49
|
-
down_file.unlink()
|
50
|
-
|
51
|
-
|
52
|
-
def open_packet(name: str, down_file: Path) -> str:
|
53
|
-
"""解压压缩包"""
|
54
|
-
down_path = down_file.parent
|
55
|
-
logger.info("文件名为:" + name)
|
56
|
-
logger.info(f"系统为{systems}")
|
57
|
-
|
58
|
-
if name.endswith(".vpk"):
|
59
|
-
return "vpk文件已下载"
|
60
|
-
|
61
|
-
for ext in SUPPORTED_EXTENSIONS:
|
62
|
-
if name.endswith(ext):
|
63
|
-
mes = f"{ext[1:]}文件已下载,正在解压"
|
64
|
-
unpack_funcs: Dict[str, Callable] = {
|
65
|
-
".zip": unzip_zipfile,
|
66
|
-
".7z": unpack_7zfile,
|
67
|
-
".rar": unpack_rarfile,
|
68
|
-
}
|
69
|
-
unpack_func = unpack_funcs.get(ext)
|
70
|
-
if not unpack_func:
|
71
|
-
raise ValueError(f"不支持的拓展名: {ext}")
|
72
|
-
unpack_func(down_file, down_path)
|
73
|
-
return mes
|
74
|
-
|
75
|
-
raise ValueError(f"不支持的文件: {name}")
|
76
|
-
|
77
|
-
|
78
|
-
def support_gbk(zip_file: ZipFile):
|
79
|
-
"""
|
80
|
-
压缩包中文恢复
|
81
|
-
"""
|
82
|
-
if type(zip_file) == ZipFile:
|
83
|
-
name_to_info = zip_file.NameToInfo
|
84
|
-
# copy map first
|
85
|
-
for name, info in name_to_info.copy().items():
|
86
|
-
real_name = name.encode("cp437").decode("gbk")
|
87
|
-
if real_name != name:
|
88
|
-
info.filename = real_name
|
89
|
-
del name_to_info[name]
|
90
|
-
name_to_info[real_name] = info
|
91
|
-
return zip_file
|
92
|
-
|
93
|
-
|
94
|
-
async def all_zip_to_one(data_list: List[bytes]):
|
95
|
-
"""多压缩包文件合并"""
|
96
|
-
file_list = [io.BytesIO(data).getbuffer() for data in data_list]
|
97
|
-
data_file = io.BytesIO()
|
98
|
-
|
99
|
-
with ZipFile(data_file, mode="w") as zf:
|
100
|
-
for i, file in enumerate(file_list):
|
101
|
-
filename = f"file{i}.zip"
|
102
|
-
zf.writestr(filename, file)
|
103
|
-
|
104
|
-
return data_file.getbuffer()
|
@@ -1,125 +0,0 @@
|
|
1
|
-
from typing import List, Optional
|
2
|
-
|
3
|
-
import jinja2
|
4
|
-
from nonebot.log import logger
|
5
|
-
from nonebot_plugin_htmlrender import html_to_pic
|
6
|
-
|
7
|
-
from ..l4d2_utils.classcal import PlayerInfo, ServerGroup, ServerStatus
|
8
|
-
|
9
|
-
# from .htmlimg import dict_to_dict_img
|
10
|
-
# from ..l4d2_anne.anne_telecom import ANNE_API
|
11
|
-
from ..l4d2_utils.config import TEXT_PATH, l4_config
|
12
|
-
from .download import get_head_by_user_id_and_save
|
13
|
-
from .send_image_tool import convert_img
|
14
|
-
|
15
|
-
template_path = TEXT_PATH / "template"
|
16
|
-
|
17
|
-
env = jinja2.Environment(
|
18
|
-
loader=jinja2.FileSystemLoader(template_path),
|
19
|
-
enable_async=True,
|
20
|
-
)
|
21
|
-
|
22
|
-
|
23
|
-
async def out_png(usr_id, data_dict: dict):
|
24
|
-
"""使用html来生成图片"""
|
25
|
-
# content = template.render_async()
|
26
|
-
msg_dict = await dict_to_html(usr_id, data_dict)
|
27
|
-
template = env.get_template("anne.html")
|
28
|
-
html = await template.render_async(data=msg_dict)
|
29
|
-
return await html_to_pic(
|
30
|
-
html=html,
|
31
|
-
wait=0,
|
32
|
-
viewport={"width": 1100, "height": 800},
|
33
|
-
template_path=f"file://{template_path.absolute()}",
|
34
|
-
)
|
35
|
-
|
36
|
-
|
37
|
-
async def dict_to_html(usr_id, detail_map: dict):
|
38
|
-
"""输入qq、字典,获取新的msg替换html"""
|
39
|
-
detail_right = {}
|
40
|
-
detail_right["name"] = detail_map["Steam 名字:"]
|
41
|
-
detail_right["Steam_ID"] = detail_map["Steam ID:"]
|
42
|
-
detail_right["play_time"] = detail_map["游玩时间:"]
|
43
|
-
detail_right["last_online"] = detail_map["最后上线:"]
|
44
|
-
detail_right["rank"] = detail_map["排行:"]
|
45
|
-
detail_right["points"] = detail_map["分数:"]
|
46
|
-
detail_right["point_min"] = detail_map["每分钟获取分数:"]
|
47
|
-
detail_right["killed"] = detail_map["感染者消灭:"]
|
48
|
-
detail_right["shut"] = detail_map["爆头:"]
|
49
|
-
detail_right["out"] = detail_map["爆头率:"]
|
50
|
-
detail_right["playtimes"] = detail_map["游玩地图数量:"]
|
51
|
-
detail_right["url"] = detail_map["个人资料"]
|
52
|
-
detail_right["one_msg"] = detail_map["一言"]
|
53
|
-
detail_right["last_one"] = detail_map["救援关"]
|
54
|
-
|
55
|
-
# html_text = soup.prettify()
|
56
|
-
# for key, value in detail_right.items():
|
57
|
-
# html_text = html_text.replace(key,value)
|
58
|
-
# 头像
|
59
|
-
temp = await get_head_by_user_id_and_save(usr_id)
|
60
|
-
# temp = await get_head_steam_and_save(usr_id,detail_right['url'])
|
61
|
-
if not temp:
|
62
|
-
return None
|
63
|
-
res = await convert_img(temp, is_base64=True)
|
64
|
-
detail_right["header"] = f"data:image/png;base64,{res}"
|
65
|
-
data_list: List[dict] = [detail_right]
|
66
|
-
return data_list
|
67
|
-
|
68
|
-
|
69
|
-
async def server_ip_pic(msg_list: List[ServerStatus]):
|
70
|
-
"""
|
71
|
-
输入一个字典列表,输出图片
|
72
|
-
msg_dict:folder/name/map_/players/max_players/Players/[Name]
|
73
|
-
"""
|
74
|
-
for server_info in msg_list:
|
75
|
-
server_info.rank_players = f"{server_info.players}/{server_info.max_players}"
|
76
|
-
players_list: List[PlayerInfo] = []
|
77
|
-
# logger.info(server_info.name)
|
78
|
-
max_number = l4_config.l4_img_name
|
79
|
-
sorted_players = sorted(server_info.Players, key=lambda x: x.Score)[:max_number]
|
80
|
-
for player_info in sorted_players:
|
81
|
-
# player_str = f"{player_info.name} | {player_info.Duration}"
|
82
|
-
players_list.append(player_info)
|
83
|
-
while len(players_list) < max_number:
|
84
|
-
players_list.append(PlayerInfo())
|
85
|
-
server_info.Players = players_list
|
86
|
-
# logger.info(server_info.Players)
|
87
|
-
pic = await get_help_img(msg_list)
|
88
|
-
if pic:
|
89
|
-
logger.success("正在输出图片")
|
90
|
-
else:
|
91
|
-
logger.warning("我的图图呢")
|
92
|
-
return pic
|
93
|
-
|
94
|
-
|
95
|
-
async def get_help_img(plugins: List[ServerStatus]) -> Optional[bytes]:
|
96
|
-
try:
|
97
|
-
if l4_config.l4_style == "black":
|
98
|
-
template = env.get_template("help_dack.html")
|
99
|
-
else:
|
100
|
-
template = env.get_template("help.html")
|
101
|
-
content = await template.render_async(plugins=plugins)
|
102
|
-
return await html_to_pic(
|
103
|
-
content,
|
104
|
-
wait=0,
|
105
|
-
viewport={"width": 100, "height": 100},
|
106
|
-
template_path=f"file://{template_path.absolute()}",
|
107
|
-
)
|
108
|
-
except Exception as e:
|
109
|
-
logger.warning(f"Error in get_help_img: {e}")
|
110
|
-
return None
|
111
|
-
|
112
|
-
|
113
|
-
async def server_group_ip_pic(msg_list: List[ServerGroup]):
|
114
|
-
"""
|
115
|
-
输入一个群组字典列表,输出图片
|
116
|
-
msg_dict:folder/name/map_/players/max_players/Players/[Name]
|
117
|
-
"""
|
118
|
-
template = env.get_template("group_ip.html")
|
119
|
-
html = await template.render_async(plugins=msg_list)
|
120
|
-
return await html_to_pic(
|
121
|
-
html=html,
|
122
|
-
wait=0,
|
123
|
-
viewport={"width": 1100, "height": 800},
|
124
|
-
template_path=f"file://{template_path.absolute()}",
|
125
|
-
)
|
@@ -1,18 +0,0 @@
|
|
1
|
-
class DATAPANDS:
|
2
|
-
def __init__(self, data_dict: dict) -> None:
|
3
|
-
self.new_data = {}
|
4
|
-
self.data_dict = data_dict
|
5
|
-
for key in data_dict:
|
6
|
-
self.dict_pan(key)
|
7
|
-
|
8
|
-
def dict_pan(self, key):
|
9
|
-
"""dict转化为图像所需要的dict量化"""
|
10
|
-
# 删除不必要的数据
|
11
|
-
if key == "刷特模式":
|
12
|
-
self.data_dict.pop(key)
|
13
|
-
elif key == "游戏模式" or key == "特感数量" or key == "刷新间隔":
|
14
|
-
for item in self.data_dict[key]:
|
15
|
-
if item in self.new_data:
|
16
|
-
self.new_data[item] += 1
|
17
|
-
else:
|
18
|
-
self.new_data[item] = 1
|