nonebot-plugin-l4d2-server 0.5.2__py3-none-any.whl → 0.5.3__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.
Files changed (25) hide show
  1. README.md +11 -2
  2. nonebot_plugin_l4d2_server/__init__.py +12 -12
  3. nonebot_plugin_l4d2_server/config.py +1 -2
  4. nonebot_plugin_l4d2_server/l4d2_data/database.py +0 -0
  5. nonebot_plugin_l4d2_server/l4d2_image/image.py +292 -0
  6. nonebot_plugin_l4d2_server/l4d2_queries/api.py +39 -39
  7. nonebot_plugin_l4d2_server/l4d2_server/index.py +0 -0
  8. nonebot_plugin_l4d2_server/l4d2_update/__init__.py +143 -0
  9. nonebot_plugin_l4d2_server/l4d2_update/draw_update_log.py +41 -0
  10. nonebot_plugin_l4d2_server/l4d2_update/restart.py +67 -0
  11. nonebot_plugin_l4d2_server/l4d2_update/texture2d/art.png +0 -0
  12. nonebot_plugin_l4d2_server/l4d2_update/texture2d/bento.png +0 -0
  13. nonebot_plugin_l4d2_server/l4d2_update/texture2d/bug.png +0 -0
  14. nonebot_plugin_l4d2_server/l4d2_update/texture2d/feat.png +0 -0
  15. nonebot_plugin_l4d2_server/l4d2_update/texture2d/log_title.png +0 -0
  16. nonebot_plugin_l4d2_server/l4d2_update/texture2d/other.png +0 -0
  17. nonebot_plugin_l4d2_server/l4d2_update/texture2d/zap.png +0 -0
  18. nonebot_plugin_l4d2_server/l4d2_update/update.py +65 -0
  19. nonebot_plugin_l4d2_server/rule.py +15 -0
  20. nonebot_plugin_l4d2_server/utils.py +26 -1
  21. {nonebot_plugin_l4d2_server-0.5.2.dist-info → nonebot_plugin_l4d2_server-0.5.3.dist-info}/METADATA +14 -4
  22. {nonebot_plugin_l4d2_server-0.5.2.dist-info → nonebot_plugin_l4d2_server-0.5.3.dist-info}/RECORD +24 -10
  23. nonebot_plugin_l4d2_server/chrome.py +0 -45
  24. {nonebot_plugin_l4d2_server-0.5.2.dist-info → nonebot_plugin_l4d2_server-0.5.3.dist-info}/LICENSE +0 -0
  25. {nonebot_plugin_l4d2_server-0.5.2.dist-info → nonebot_plugin_l4d2_server-0.5.3.dist-info}/WHEEL +0 -0
README.md CHANGED
@@ -40,6 +40,8 @@ _✨Nonebot & Left 4 Dead 2 server操作✨_
40
40
 
41
41
  同时不再支持远程查询,改为只允许本地查询
42
42
 
43
+ 文档暂时没时间更新ozr
44
+
43
45
  ## 主要功能
44
46
 
45
47
  - 求生服务器-本地多路径操作(传地图)
@@ -114,7 +116,14 @@ bot所在文件夹下
114
116
  <details>
115
117
  <summary>展开/收起</summary>
116
118
 
117
- ### 0.5.1--2022.5.01
119
+
120
+ ### 0.5.3--2022.5.07
121
+
122
+ - 新增`l4更新`和`l4重启`
123
+ - 注释无效项(三方图查询)
124
+ - 可以通过git clone 直接加载插件
125
+
126
+ ### 0.5.2--2022.5.01
118
127
 
119
128
  - 解决了main和dev分支的一个严重bug(也许没解决
120
129
  - 本地化,更好的添加,删除远程分支
@@ -360,6 +369,6 @@ bot所在文件夹下
360
369
  - [可爱小Q](https://github.com/MeetWq/mybot)- 服务器图片参考
361
370
  - [群聊学习](https://github.com/CMHopeSunshine/nonebot-plugin-learning-chat)- web控制台参考
362
371
  - [日向麻麻](https://github.com/Special-Week)- 代码优化参考
363
- - [gsuid](https://github.com/KimigaiiWuyi/GenshinUID)- readme和wiki的格式参考
372
+ - [gsuid](https://github.com/KimigaiiWuyi/GenshinUID)- readme和wiki的格式参考,以及3.1版本的更新和重启
364
373
  - 呆呆- 提供三方地图的详细数据
365
374
  - ArcPav -积极反馈bug,提供改进思路
@@ -412,18 +412,18 @@ async def _(matcher:Matcher,):
412
412
  msg = mes_list(msg,name_smx).replace(" ","")
413
413
  await matcher.finish(mode_txt_to_img(mes,msg))
414
414
 
415
- @search_api.handle()
416
- async def _(matcher:Matcher,state:T_State,event:GroupMessageEvent,args:Message = CommandArg()):
417
- msg:str = args.extract_plain_text()
418
- # if msg.startswith('代码'):
419
- # 建图代码返回三方图信息
420
- data = await seach_map(msg,l4_config.l4_master[0],l4_config.l4_key)
421
- # else:
422
- if type(data) == str:
423
- await matcher.finish(data)
424
- else:
425
- state['maps'] = data
426
- await matcher.send(await map_dict_to_str(data))
415
+ # @search_api.handle()
416
+ # async def _(matcher:Matcher,state:T_State,event:GroupMessageEvent,args:Message = CommandArg()):
417
+ # msg:str = args.extract_plain_text()
418
+ # # if msg.startswith('代码'):
419
+ # # 建图代码返回三方图信息
420
+ # data = await seach_map(msg,l4_config.l4_master[0],l4_config.l4_key)
421
+ # # else:
422
+ # if type(data) == str:
423
+ # await matcher.finish(data)
424
+ # else:
425
+ # state['maps'] = data
426
+ # await matcher.send(await map_dict_to_str(data))
427
427
 
428
428
  @search_api.got("is_sure",prompt='如果需要上传,请发送 "yes"')
429
429
  async def _(matcher:Matcher,bot:Bot,event:GroupMessageEvent,state:T_State):
@@ -19,8 +19,7 @@ from nonebot.adapters.onebot.v11.permission import (
19
19
  PRIVATE_FRIEND,
20
20
  )
21
21
 
22
- from .l4d2_queries.ohter import ALL_HOST
23
- from .l4d2_queries.api import seach_map,map_dict_to_str
22
+ from .l4d2_queries.ohter import ALL_HOST
24
23
  file_format = (".vpk",".zip",".7z",'rar')
25
24
  # 权限
26
25
 
File without changes
@@ -0,0 +1,292 @@
1
+ from io import BytesIO
2
+ from pathlib import Path
3
+ from base64 import b64encode
4
+ from typing import Union, overload
5
+ from typing import Union,Tuple,Optional
6
+ import math
7
+ import random
8
+
9
+ import aiofiles
10
+ from PIL import Image
11
+ from httpx import get
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ MAIN_PATH = Path() / 'data' / 'GenshinUID'
16
+ sys.path.append(str(MAIN_PATH))
17
+ CONFIG_PATH = MAIN_PATH / 'config.json'
18
+ RESOURCE_PATH = MAIN_PATH / 'resource'
19
+ WIKI_PATH = MAIN_PATH / 'wiki'
20
+ CU_BG_PATH = MAIN_PATH / 'bg'
21
+ CU_CHBG_PATH = MAIN_PATH / 'chbg'
22
+ WEAPON_PATH = RESOURCE_PATH / 'weapon'
23
+ GACHA_IMG_PATH = RESOURCE_PATH / 'gacha_img'
24
+ CHAR_PATH = RESOURCE_PATH / 'chars'
25
+ CHAR_STAND_PATH = RESOURCE_PATH / 'char_stand'
26
+ CHAR_SIDE_PATH = RESOURCE_PATH / 'char_side'
27
+ CHAR_NAMECARD_PATH = RESOURCE_PATH / 'char_namecard'
28
+ REL_PATH = RESOURCE_PATH / 'reliquaries'
29
+ ICON_PATH = RESOURCE_PATH / 'icon'
30
+ TEMP_PATH = RESOURCE_PATH / 'temp'
31
+ CARD_PATH = RESOURCE_PATH / 'card'
32
+ GUIDE_PATH = WIKI_PATH / 'guide'
33
+ TEXT2D_PATH = Path(__file__).parents[2] / 'resource' / 'texture2d'
34
+
35
+ PLAYER_PATH = MAIN_PATH / 'players'
36
+
37
+
38
+ TEXT2D_PATH = Path(__file__).parents[2] / 'resource' / 'texture2d'
39
+ FETTER_PATH = TEXT2D_PATH / 'fetter'
40
+ TALENT_PATH = TEXT2D_PATH / 'talent'
41
+ WEAPON_BG_PATH = TEXT2D_PATH / 'weapon'
42
+ WEAPON_AFFIX_PATH = TEXT2D_PATH / 'weapon_affix'
43
+ LEVEL_PATH = TEXT2D_PATH / 'level'
44
+
45
+ BG_PATH = Path(__file__).parent / 'bg'
46
+ TEXT_PATH = Path(__file__).parent / 'texture2d'
47
+ ring_pic = Image.open(TEXT_PATH / 'ring.png')
48
+ mask_pic = Image.open(TEXT_PATH / 'mask.png')
49
+ NM_BG_PATH = BG_PATH / 'nm_bg'
50
+ SP_BG_PATH = BG_PATH / 'sp_bg'@overload
51
+
52
+ if list(CU_BG_PATH.iterdir()) != []:
53
+ bg_path = CU_BG_PATH
54
+ else:
55
+ bg_path = NM_BG_PATH
56
+
57
+ async def convert_img(img: Image.Image, is_base64: bool = False) -> bytes:
58
+ ...
59
+
60
+
61
+ @overload
62
+ async def convert_img(img: Image.Image, is_base64: bool = True) -> str:
63
+ ...
64
+
65
+
66
+ @overload
67
+ async def convert_img(img: bytes, is_base64: bool = False) -> str:
68
+ ...
69
+
70
+
71
+ @overload
72
+ async def convert_img(img: Path, is_base64: bool = False) -> str:
73
+ ...
74
+
75
+
76
+ async def convert_img(
77
+ img: Union[Image.Image, str, Path, bytes], is_base64: bool = False
78
+ ):
79
+ """
80
+ :说明:
81
+ 将PIL.Image对象转换为bytes或者base64格式。
82
+ :参数:
83
+ * img (Image): 图片。
84
+ * is_base64 (bool): 是否转换为base64格式, 不填默认转为bytes。
85
+ :返回:
86
+ * res: bytes对象或base64编码图片。
87
+ """
88
+ if isinstance(img, Image.Image):
89
+ img = img.convert('RGB')
90
+ result_buffer = BytesIO()
91
+ img.save(result_buffer, format='PNG', quality=80, subsampling=0)
92
+ res = result_buffer.getvalue()
93
+ if is_base64:
94
+ res = 'base64://' + b64encode(res).decode()
95
+ return res
96
+ elif isinstance(img, bytes):
97
+ pass
98
+ else:
99
+ async with aiofiles.open(img, 'rb') as fp:
100
+ img = await fp.read()
101
+ return f'[CQ:image,file=base64://{b64encode(img).decode()}]'
102
+
103
+
104
+ async def get_color_bg(
105
+ based_w: int, based_h: int, bg: Optional[str] = None
106
+ ) -> Image.Image:
107
+ image = ''
108
+ if bg:
109
+ path = SP_BG_PATH / f'{bg}.jpg'
110
+ if path.exists():
111
+ image = Image.open(path)
112
+ CI_img = CustomizeImage(image, based_w, based_h)
113
+ img = CI_img.bg_img
114
+ color = CI_img.bg_color
115
+ color_mask = Image.new('RGBA', (based_w, based_h), color)
116
+ enka_mask = Image.open(TEXT2D_PATH / 'mask.png').resize((based_w, based_h))
117
+ img.paste(color_mask, (0, 0), enka_mask)
118
+ return img
119
+
120
+
121
+
122
+ class CustomizeImage:
123
+ def __init__(
124
+ self, image: Union[str, Image.Image], based_w: int, based_h: int
125
+ ) -> None:
126
+
127
+ self.bg_img = self.get_image(image, based_w, based_h)
128
+ self.bg_color = self.get_bg_color(self.bg_img, is_light=True)
129
+ self.text_color = self.get_text_color(self.bg_color)
130
+ self.highlight_color = self.get_highlight_color(self.bg_color)
131
+ self.char_color = self.get_char_color(self.bg_color)
132
+ self.bg_detail_color = self.get_bg_detail_color(self.bg_color)
133
+ self.char_high_color = self.get_char_high_color(self.bg_color)
134
+
135
+ @staticmethod
136
+ def get_image(
137
+ image: Union[str, Image.Image], based_w: int, based_h: int
138
+ ) -> Image.Image:
139
+ # 获取背景图片
140
+ if isinstance(image, Image.Image):
141
+ edit_bg = image
142
+ elif image:
143
+ edit_bg = Image.open(BytesIO(get(image).content)).convert('RGBA')
144
+ else:
145
+ path = random.choice(list(bg_path.iterdir()))
146
+ edit_bg = Image.open(path).convert('RGBA')
147
+
148
+ # 确定图片的长宽
149
+ bg_img = crop_center_img(edit_bg, based_w, based_h)
150
+ return bg_img
151
+
152
+ @staticmethod
153
+ def get_dominant_color(pil_img: Image.Image) -> Tuple[int, int, int]:
154
+ img = pil_img.copy()
155
+ img = img.convert("RGBA")
156
+ img = img.resize((1, 1), resample=0)
157
+ dominant_color = img.getpixel((0, 0))
158
+ return dominant_color
159
+
160
+ @staticmethod
161
+ def get_bg_color(
162
+ edit_bg: Image.Image, is_light: Optional[bool] = False
163
+ ) -> Tuple[int, int, int]:
164
+ # 获取背景主色
165
+ color = 8
166
+ q = edit_bg.quantize(colors=color, method=2)
167
+ bg_color = (0, 0, 0)
168
+ if is_light:
169
+ based_light = 195
170
+ else:
171
+ based_light = 120
172
+ temp = 9999
173
+ for i in range(color):
174
+ bg = tuple(
175
+ q.getpalette()[ # type:ignore
176
+ i * 3 : (i * 3) + 3 # noqa:E203
177
+ ]
178
+ )
179
+ light_value = bg[0] * 0.3 + bg[1] * 0.6 + bg[2] * 0.1
180
+ if abs(light_value - based_light) < temp:
181
+ bg_color = bg
182
+ temp = abs(light_value - based_light)
183
+ return bg_color
184
+
185
+ @staticmethod
186
+ def get_text_color(bg_color: Tuple[int, int, int]) -> Tuple[int, int, int]:
187
+ # 通过背景主色(bg_color)确定文字主色
188
+ r = 125
189
+ if max(*bg_color) > 255 - r:
190
+ r *= -1
191
+ text_color = (
192
+ math.floor(bg_color[0] + r if bg_color[0] + r <= 255 else 255),
193
+ math.floor(bg_color[1] + r if bg_color[1] + r <= 255 else 255),
194
+ math.floor(bg_color[2] + r if bg_color[2] + r <= 255 else 255),
195
+ )
196
+ return text_color
197
+
198
+ @staticmethod
199
+ def get_char_color(bg_color: Tuple[int, int, int]) -> Tuple[int, int, int]:
200
+ r = 140
201
+ if max(*bg_color) > 255 - r:
202
+ r *= -1
203
+ char_color = (
204
+ math.floor(bg_color[0] + 5 if bg_color[0] + r <= 255 else 255),
205
+ math.floor(bg_color[1] + 5 if bg_color[1] + r <= 255 else 255),
206
+ math.floor(bg_color[2] + 5 if bg_color[2] + r <= 255 else 255),
207
+ )
208
+ return char_color
209
+
210
+ @staticmethod
211
+ def get_char_high_color(
212
+ bg_color: Tuple[int, int, int]
213
+ ) -> Tuple[int, int, int]:
214
+ r = 140
215
+ d = 20
216
+ if max(*bg_color) > 255 - r:
217
+ r *= -1
218
+ char_color = (
219
+ math.floor(bg_color[0] + d if bg_color[0] + r <= 255 else 255),
220
+ math.floor(bg_color[1] + d if bg_color[1] + r <= 255 else 255),
221
+ math.floor(bg_color[2] + d if bg_color[2] + r <= 255 else 255),
222
+ )
223
+ return char_color
224
+
225
+ @staticmethod
226
+ def get_bg_detail_color(
227
+ bg_color: Tuple[int, int, int]
228
+ ) -> Tuple[int, int, int]:
229
+ r = 140
230
+ if max(*bg_color) > 255 - r:
231
+ r *= -1
232
+ bg_detail_color = (
233
+ math.floor(bg_color[0] - 20 if bg_color[0] + r <= 255 else 255),
234
+ math.floor(bg_color[1] - 20 if bg_color[1] + r <= 255 else 255),
235
+ math.floor(bg_color[2] - 20 if bg_color[2] + r <= 255 else 255),
236
+ )
237
+ return bg_detail_color
238
+
239
+ @staticmethod
240
+ def get_highlight_color(
241
+ color: Tuple[int, int, int]
242
+ ) -> Tuple[int, int, int]:
243
+ red_color = color[0]
244
+ green_color = color[1]
245
+ blue_color = color[2]
246
+
247
+ highlight_color = {
248
+ 'red': red_color - 127 if red_color > 127 else 127,
249
+ 'green': green_color - 127 if green_color > 127 else 127,
250
+ 'blue': blue_color - 127 if blue_color > 127 else 127,
251
+ }
252
+
253
+ max_color = max(highlight_color.values())
254
+
255
+ name = ''
256
+ for _highlight_color in highlight_color:
257
+ if highlight_color[_highlight_color] == max_color:
258
+ name = str(_highlight_color)
259
+
260
+ if name == 'red':
261
+ return red_color, highlight_color['green'], highlight_color['blue']
262
+ elif name == 'green':
263
+ return highlight_color['red'], green_color, highlight_color['blue']
264
+ elif name == 'blue':
265
+ return highlight_color['red'], highlight_color['green'], blue_color
266
+ else:
267
+ return 0, 0, 0 # Error
268
+
269
+
270
+ def crop_center_img(
271
+ img: Image.Image, based_w: int, based_h: int
272
+ ) -> Image.Image:
273
+ # 确定图片的长宽
274
+ based_scale = '%.3f' % (based_w / based_h)
275
+ w, h = img.size
276
+ scale_f = '%.3f' % (w / h)
277
+ new_w = math.ceil(based_h * float(scale_f))
278
+ new_h = math.ceil(based_w / float(scale_f))
279
+ if scale_f > based_scale:
280
+ resize_img = img.resize((new_w, based_h), Image.ANTIALIAS)
281
+ x1 = int(new_w / 2 - based_w / 2)
282
+ y1 = 0
283
+ x2 = int(new_w / 2 + based_w / 2)
284
+ y2 = based_h
285
+ else:
286
+ resize_img = img.resize((based_w, new_h), Image.ANTIALIAS)
287
+ x1 = 0
288
+ y1 = int(new_h / 2 - based_h / 2)
289
+ x2 = based_w
290
+ y2 = int(new_h / 2 + based_h / 2)
291
+ crop_img = resize_img.crop((x1, y1, x2, y2))
292
+ return crop_img
@@ -1,43 +1,43 @@
1
- import httpx
2
- from typing import List,Union
3
- from nonebot.log import logger
1
+ # import httpx
2
+ # from typing import List,Union
3
+ # from nonebot.log import logger
4
4
 
5
- async def seach_map(msg:Union[list,str],qq:str,key:str,mode:str = 'zh'):
6
- url = "http://106.13.207.45:4015/l4d2"
7
- json = {
8
- "mode":mode,
9
- "map_name":msg,
10
- "qq":qq,
11
- "key":key
12
- }
13
- file = httpx.post(url=url,json=json)
14
- if mode == 'zh':
15
- if file.status_code == 200:
16
- return file.json()
17
- elif file.status_code == 204:
18
- return "没有结果"
19
- elif file.status_code == 406:
20
- return "参数错误"
21
- elif file.status_code == 401:
22
- return file.json()
23
- elif mode == 'ip':
24
- rep:dict = file.json()
25
- try:
26
- logger.error(rep['error_'])
27
- except:
28
- pass
29
- print(file.json())
30
- return file.json()
31
- elif mode == 'first':
32
- ip_tag:list = file.json()
33
- return ip_tag
5
+ # async def seach_map(msg:Union[list,str],qq:str,key:str,mode:str = 'zh'):
6
+ # url = ""
7
+ # json = {
8
+ # "mode":mode,
9
+ # "map_name":msg,
10
+ # "qq":qq,
11
+ # "key":key
12
+ # }
13
+ # file = httpx.post(url=url,json=json)
14
+ # if mode == 'zh':
15
+ # if file.status_code == 200:
16
+ # return file.json()
17
+ # elif file.status_code == 204:
18
+ # return "没有结果"
19
+ # elif file.status_code == 406:
20
+ # return "参数错误"
21
+ # elif file.status_code == 401:
22
+ # return file.json()
23
+ # elif mode == 'ip':
24
+ # rep:dict = file.json()
25
+ # try:
26
+ # logger.error(rep['error_'])
27
+ # except:
28
+ # pass
29
+ # print(file.json())
30
+ # return file.json()
31
+ # elif mode == 'first':
32
+ # ip_tag:list = file.json()
33
+ # return ip_tag
34
34
 
35
35
 
36
- async def map_dict_to_str(data:List[dict]):
37
- msg = ""
38
- for key,value in data[0].items():
39
- if key == "url":
40
- continue
41
- msg += f"{key}:{value}\n"
42
- return msg
36
+ # async def map_dict_to_str(data:List[dict]):
37
+ # msg = ""
38
+ # for key,value in data[0].items():
39
+ # if key == "url":
40
+ # continue
41
+ # msg += f"{key}:{value}\n"
42
+ # return msg
43
43
 
File without changes
@@ -0,0 +1,143 @@
1
+ from typing import Any, Tuple
2
+
3
+ from nonebot.log import logger
4
+ from nonebot.matcher import Matcher
5
+ from nonebot.params import RegexGroup
6
+ from nonebot.permission import SUPERUSER
7
+ from nonebot import get_bot, on_regex, get_driver, on_command
8
+ from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
9
+
10
+ from ..utils import register_menu
11
+ from ..rule import FullCommand
12
+ from .draw_update_log import draw_update_log_img
13
+ from .restart import restart_message, restart_genshinuid
14
+
15
+ l4d_restart = on_command('l4重启', rule=FullCommand())
16
+ get_update_log = on_command('更新记录', rule=FullCommand())
17
+ l4d_update = on_regex(
18
+ r'^(l4d)(强行)?(强制)?(更新)$',
19
+ block=True,
20
+ )
21
+
22
+
23
+ driver = get_driver()
24
+
25
+
26
+ @driver.on_bot_connect
27
+ async def _():
28
+ logger.info('检查遗留信息...')
29
+ bot = get_bot()
30
+ update_log = await restart_message()
31
+ if update_log == {}:
32
+ return
33
+ if update_log['send_type'] == 'group':
34
+ await bot.call_api(
35
+ api='send_group_msg',
36
+ group_id=update_log['send_to'],
37
+ message=update_log['msg'],
38
+ )
39
+ else:
40
+ await bot.call_api(
41
+ api='send_private_msg',
42
+ user_id=update_log['send_to'],
43
+ message=update_log['msg'],
44
+ )
45
+ logger.info('遗留信息检查完毕!')
46
+
47
+
48
+ @get_update_log.handle()
49
+ @register_menu(
50
+ '更新记录',
51
+ '更新记录',
52
+ '查看插件最近的更新记录',
53
+ detail_des=(
54
+ '介绍:\n'
55
+ '查看插件最近的有效Git更新记录\n'
56
+ ' \n'
57
+ '指令:\n'
58
+ '- <ft color=(238,120,0)>更新记录</ft>'
59
+ ),
60
+ )
61
+ async def send_updatelog_msg(
62
+ matcher: Matcher,
63
+ ):
64
+ im = await draw_update_log_img(is_update=False)
65
+ logger.info('正在执行[更新记录]...')
66
+ if isinstance(im, str):
67
+ await matcher.finish(im)
68
+ elif isinstance(im, bytes):
69
+ await matcher.finish(MessageSegment.image(im))
70
+ else:
71
+ await matcher.finish('发生了未知错误,请联系管理员检查后台输出!')
72
+
73
+
74
+ @l4d_restart.handle()
75
+ @register_menu(
76
+ '重启Bot',
77
+ 'l4重启',
78
+ '重启Bot框架',
79
+ trigger_method='超级用户指令',
80
+ detail_des=(
81
+ '介绍:\n' '重启Bot框架\n' ' \n' '指令:\n' '- <ft color=(238,120,0)>l4重启</ft>'
82
+ ),
83
+ )
84
+ async def send_restart_msg(
85
+ bot: Bot,
86
+ event: MessageEvent,
87
+ matcher: Matcher,
88
+ ):
89
+ if not await SUPERUSER(bot, event):
90
+ return
91
+ logger.warning('开始执行[重启]')
92
+ qid = event.user_id
93
+ if len(event.get_session_id().split('_')) == 3:
94
+ send_id = event.get_session_id().split('_')[1]
95
+ send_type = 'group'
96
+ else:
97
+ send_id = qid
98
+ send_type = 'private'
99
+ await matcher.send('正在执行[l4重启]...')
100
+ await restart_genshinuid(send_type, str(send_id))
101
+
102
+
103
+ @l4d_update.handle()
104
+ @register_menu(
105
+ '更新插件',
106
+ 'l4更新',
107
+ '手动更新插件',
108
+ detail_des=(
109
+ '介绍:\n'
110
+ '手动更新插件(执行 git pull)\n'
111
+ '每加上一个可选参数,执行等级加1\n'
112
+ '当执行等级≥1时会还原上次更改,等级≥2时会清空暂存\n'
113
+ ' \n'
114
+ '指令:\n'
115
+ '- <ft color=(238,120,0)>l4d</ft>'
116
+ '<ft color=(125,125,125)>(强行)(强制)</ft>'
117
+ '<ft color=(238,120,0)>更新</ft>'
118
+ ),
119
+ )
120
+ async def send_update_msg(
121
+ bot: Bot,
122
+ event: MessageEvent,
123
+ matcher: Matcher,
124
+ args: Tuple[Any, ...] = RegexGroup(),
125
+ ):
126
+ if not await SUPERUSER(bot, event):
127
+ return
128
+
129
+ logger.info('[l4d更新] 正在执行 ...')
130
+ level = 2
131
+ if args[1] is None:
132
+ level -= 1
133
+ if args[2] is None:
134
+ level -= 1
135
+ logger.info(f'[l4d更新] 更新等级为{level}')
136
+ await matcher.send(f'开始执行[l4d更新], 执行等级为{level}')
137
+ im = await draw_update_log_img(level)
138
+ if isinstance(im, str):
139
+ await matcher.finish(im)
140
+ elif isinstance(im, bytes):
141
+ await matcher.finish(MessageSegment.image(im))
142
+ else:
143
+ await matcher.finish('发生了未知错误,请联系管理员检查后台输出!')
@@ -0,0 +1,41 @@
1
+ from pathlib import Path
2
+ from typing import Union
3
+
4
+ # from PIL import Image, ImageDraw
5
+
6
+ from .update import update_from_git
7
+ # from ..l4d2_image.image import convert_img
8
+ # from ..l4d2_image.image import get_color_bg
9
+ # from ..utils.genshin_fonts.genshin_fonts import genshin_font_origin
10
+
11
+ R_PATH = Path(__file__).parent
12
+ TEXT_PATH = R_PATH / 'texture2d'
13
+
14
+ # gs_font_30 = genshin_font_origin(30)
15
+ black_color = (24, 24, 24)
16
+
17
+ log_config = {
18
+ 'key': '✨🐛🎨⚡🍱♻️',
19
+ 'num': 18,
20
+ }
21
+
22
+ log_map = {'✨': 'feat', '🐛': 'bug', '🍱': 'bento', '⚡️': 'zap', '🎨': 'art'}
23
+
24
+
25
+ async def draw_update_log_img(
26
+ level: int = 0,
27
+ repo_path: Union[str, Path, None] = None,
28
+ is_update: bool = True,
29
+ ) -> Union[bytes, str]:
30
+ log_list = await update_from_git(level, repo_path, log_config, is_update)
31
+ if len(log_list) == 0:
32
+ return '更新失败!更多错误信息请查看控制台...\n' \
33
+ '>> 可以尝试使用\n' \
34
+ '>> [gs强制更新](危险)\n' \
35
+ '>> [gs强行强制更新](超级危险)!'
36
+
37
+ result = 'L4D2Bot 更新记录\n\n'
38
+ for log in log_list:
39
+ result += f'- {log[2:]}\n'
40
+
41
+ return result
@@ -0,0 +1,67 @@
1
+ import os
2
+ import sys
3
+ import json
4
+ import time
5
+ import platform
6
+ import subprocess
7
+ from pathlib import Path
8
+
9
+ # from ..utils.db_operation.db_operation import config_check
10
+
11
+ bot_start = Path().cwd() / 'bot.py'
12
+ restart_sh_path = Path().cwd() / 'gs_restart.sh'
13
+ update_log_path = Path(__file__).parent / 'update_log.json'
14
+
15
+ _restart_sh = '''#!/bin/bash
16
+ kill -9 {}
17
+ {} &'''
18
+
19
+
20
+ async def get_restart_sh(extra: str) -> str:
21
+ args = f'{extra} {str(bot_start.absolute())}'
22
+ return _restart_sh.format(str(bot_start.absolute()), args)
23
+
24
+
25
+ async def restart_genshinuid(send_type: str, send_id: str) -> None:
26
+ # extra = ''
27
+ # if await config_check('UsePoetry'):
28
+ # extra = 'poetry run '
29
+ extra = sys.executable
30
+ restart_sh = await get_restart_sh(extra)
31
+ if not restart_sh_path.exists():
32
+ with open(restart_sh_path, "w", encoding="utf8") as f:
33
+ f.write(restart_sh)
34
+ if platform.system() == 'Linux':
35
+ os.system(f'chmod +x {str(restart_sh_path)}')
36
+ os.system(f'chmod +x {str(bot_start)}')
37
+ now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
38
+ update_log = {
39
+ 'type': 'restart',
40
+ 'msg': '重启完成!',
41
+ 'send_type': send_type,
42
+ 'send_to': send_id,
43
+ 'time': now_time,
44
+ }
45
+ with open(str(update_log_path), 'w', encoding='utf-8') as f:
46
+ json.dump(update_log, f)
47
+ if platform.system() == 'Linux':
48
+ os.execl(str(restart_sh_path), ' ')
49
+ else:
50
+ pid = os.getpid()
51
+ subprocess.Popen(
52
+ f'taskkill /F /PID {pid} & {extra} {bot_start}',
53
+ shell=True,
54
+ )
55
+
56
+
57
+ async def restart_message() -> dict:
58
+ if update_log_path.exists():
59
+ with open(update_log_path, 'r', encoding='utf-8') as f:
60
+ update_log = json.load(f)
61
+ msg = f'{update_log["msg"]}\n重启时间:{update_log["time"]}'
62
+ update_log['msg'] = msg
63
+ os.remove(update_log_path)
64
+ os.remove(restart_sh_path)
65
+ return update_log
66
+ else:
67
+ return {}
@@ -0,0 +1,65 @@
1
+ from pathlib import Path
2
+ from typing import List, Union
3
+
4
+ import git
5
+ from nonebot.log import logger
6
+ from git.exc import GitCommandError
7
+
8
+
9
+ async def update_from_git(
10
+ level: int = 0,
11
+ repo_path: Union[str, Path, None] = None,
12
+ log_config: dict = {
13
+ 'key': '✨🐛',
14
+ 'num': 7,
15
+ },
16
+ is_update: bool = True,
17
+ ) -> List[str]:
18
+ if repo_path is None:
19
+ repo_path = Path(__file__).parents[2]
20
+ repo = git.Repo(repo_path) # type: ignore
21
+ o = repo.remotes.origin
22
+
23
+ if is_update:
24
+ # 清空暂存
25
+ if level >= 2:
26
+ logger.warning('[gs更新] 正在执行 git clean --xdf')
27
+ repo.git.clean('-xdf')
28
+ # 还原上次更改
29
+ if level >= 1:
30
+ logger.warning('[gs更新] 正在执行 git reset --hard')
31
+ repo.git.reset('--hard')
32
+
33
+ try:
34
+ pull_log = o.pull()
35
+ logger.info(f'[gs更新] {pull_log}')
36
+ except GitCommandError as e:
37
+ logger.warning(e)
38
+ return []
39
+
40
+ commits = list(repo.iter_commits(max_count=40))
41
+ log_list = []
42
+ for commit in commits:
43
+ if isinstance(commit.message, str):
44
+ for key in log_config['key']:
45
+ if key in commit.message:
46
+ log_list.append(commit.message.replace('\n', ''))
47
+ if len(log_list) >= log_config['num']:
48
+ break
49
+ return log_list
50
+
51
+
52
+ async def update_genshinuid(
53
+ level: int = 0, repo_path: Union[str, Path, None] = None
54
+ ) -> str:
55
+ log_list = await update_from_git(level, repo_path)
56
+ if len(log_list) == 0:
57
+ return (
58
+ '更新失败!更多错误信息请查看控制台...\n '
59
+ '>> 可以尝试使用\n '
60
+ '>> [gs强制更新](危险)\n '
61
+ '>> [gs强行强制更新](超级危险)!'
62
+ )
63
+ log = '\n'.join(log_list)
64
+ logger.info(f'[gs更新]\n{log}')
65
+ return f'更新成功!\n >> 最近有效更新为:\n{log}'
@@ -0,0 +1,15 @@
1
+ from nonebot.rule import Rule
2
+ from nonebot.params import Depends, CommandArg
3
+ from nonebot.adapters.onebot.v11 import Message
4
+
5
+
6
+ async def full_command(arg: Message = CommandArg()) -> bool:
7
+ return not bool(str(arg))
8
+
9
+
10
+ def FullCommand() -> Rule:
11
+ return Rule(full_command)
12
+
13
+
14
+ def FullCommandDepend():
15
+ return Depends(full_command)
@@ -6,7 +6,7 @@ import httpx
6
6
  import os
7
7
  from pathlib import Path
8
8
 
9
- from typing import List,Dict,Union
9
+ from typing import List,Dict,Union,Optional
10
10
  from .txt_to_img import txt_to_img
11
11
  from .config import *
12
12
  from .l4d2_anne import write_player,del_player,anne_messgae
@@ -270,3 +270,28 @@ async def json_server_to_tag_dict(key:str,msg:str):
270
270
 
271
271
 
272
272
 
273
+ sub_menus = []
274
+
275
+ def register_menu_func(
276
+ func: str,
277
+ trigger_condition: str,
278
+ brief_des: str,
279
+ trigger_method: str = '指令',
280
+ detail_des: Optional[str] = None,
281
+ ):
282
+ sub_menus.append(
283
+ {
284
+ 'func': func,
285
+ 'trigger_method': trigger_method,
286
+ 'trigger_condition': trigger_condition,
287
+ 'brief_des': brief_des,
288
+ 'detail_des': detail_des or brief_des,
289
+ }
290
+ )
291
+
292
+ def register_menu(*args, **kwargs):
293
+ def decorator(f):
294
+ register_menu_func(*args, **kwargs)
295
+ return f
296
+
297
+ return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nonebot-plugin-l4d2-server
3
- Version: 0.5.2
3
+ Version: 0.5.3
4
4
  Summary: L4D2 server related operations plugin for NoneBot2
5
5
  Home-page: https://github.com/Agnes4m/nonebot_plugin_l4d2_server
6
6
  License: GPLv3
@@ -24,7 +24,8 @@ Requires-Dist: aiohttp (>=3.8.3,<4.0.0)
24
24
  Requires-Dist: amis-python (>=1.0.6,<2.0.0)
25
25
  Requires-Dist: asyncio (>=3.4.3)
26
26
  Requires-Dist: beautifulsoup4 (>=4.8.0)
27
- Requires-Dist: h11 (>=0.14.0,<0.15.0)
27
+ Requires-Dist: gitpython (>=3.1.27)
28
+ Requires-Dist: h11 (>0.11.0)
28
29
  Requires-Dist: httpx (>=0.23.3,<0.24.0)
29
30
  Requires-Dist: jieba (>=0.42.1,<0.43.0)
30
31
  Requires-Dist: jinja2 (>=3.0.0)
@@ -88,6 +89,8 @@ _✨Nonebot & Left 4 Dead 2 server操作✨_
88
89
 
89
90
  同时不再支持远程查询,改为只允许本地查询
90
91
 
92
+ 文档暂时没时间更新ozr
93
+
91
94
  ## 主要功能
92
95
 
93
96
  - 求生服务器-本地多路径操作(传地图)
@@ -162,7 +165,14 @@ bot所在文件夹下
162
165
  <details>
163
166
  <summary>展开/收起</summary>
164
167
 
165
- ### 0.5.1--2022.5.01
168
+
169
+ ### 0.5.3--2022.5.07
170
+
171
+ - 新增`l4更新`和`l4重启`
172
+ - 注释无效项(三方图查询)
173
+ - 可以通过git clone 直接加载插件
174
+
175
+ ### 0.5.2--2022.5.01
166
176
 
167
177
  - 解决了main和dev分支的一个严重bug(也许没解决
168
178
  - 本地化,更好的添加,删除远程分支
@@ -408,6 +418,6 @@ bot所在文件夹下
408
418
  - [可爱小Q](https://github.com/MeetWq/mybot)- 服务器图片参考
409
419
  - [群聊学习](https://github.com/CMHopeSunshine/nonebot-plugin-learning-chat)- web控制台参考
410
420
  - [日向麻麻](https://github.com/Special-Week)- 代码优化参考
411
- - [gsuid](https://github.com/KimigaiiWuyi/GenshinUID)- readme和wiki的格式参考
421
+ - [gsuid](https://github.com/KimigaiiWuyi/GenshinUID)- readme和wiki的格式参考,以及3.1版本的更新和重启
412
422
  - 呆呆- 提供三方地图的详细数据
413
423
  - ArcPav -积极反馈bug,提供改进思路
@@ -1,9 +1,8 @@
1
1
  LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
- README.md,sha256=hA9y2yRdAxcKkBHTvgXAX81TxYaMpXtKNj_9YHcpoZ4,10994
3
- nonebot_plugin_l4d2_server/__init__.py,sha256=6OQnWZccjqh_uEfyTzdWbLUOt-ATGndNtWV8jQrbtKs,17425
4
- nonebot_plugin_l4d2_server/chrome.py,sha256=NTb5STKFd1fXgNJvC3oFXsRG8a7tqbN1bCqasFuZe-A,1671
2
+ README.md,sha256=jXjbsu1db4zcZcvIE34gjLCAevQoI_7zZJJtzLKRsmY,11200
3
+ nonebot_plugin_l4d2_server/__init__.py,sha256=nTX9DMygNCbm5f-VpF7R3NtwhNKmu3mqg55Ei5mIQxM,17449
5
4
  nonebot_plugin_l4d2_server/command.py,sha256=Zqzp-QjsT9Wwt1niwtPJypYJVCZkeU-3YSMorhZ3VcU,8619
6
- nonebot_plugin_l4d2_server/config.py,sha256=GG9YwgQSvQGRzuypMoQlkyg33ZCOAig0bH5CiCWIPXc,6129
5
+ nonebot_plugin_l4d2_server/config.py,sha256=nSAYebvlaoVaM_aCNkmG3Ls0LvwvZFVTYu38tJeYQiM,6069
7
6
  nonebot_plugin_l4d2_server/data/L4D2/image/head/head.png,sha256=Z72PEvp7xF1DZcLDeuWlg2_g6JAfHxtisptWn6BYGN8,158357
8
7
  nonebot_plugin_l4d2_server/data/L4D2/image/header/logo.png,sha256=1KhQNsx7zsCKGHmyIZ65dP9npkKzo7Im-Aafyi5_lhc,631630
9
8
  nonebot_plugin_l4d2_server/data/L4D2/image/header/player1.jpg,sha256=2A_llIi9YVhJs9JOMuF36by7Ewc7P7qOgQS8t5jemNw,405369
@@ -24,6 +23,7 @@ nonebot_plugin_l4d2_server/l4d2_anne/server.py,sha256=QyfksmpUKjYCLFswAo-Q-S5Ung
24
23
  nonebot_plugin_l4d2_server/l4d2_anne/startand.py,sha256=4XmghR4l4rSw34rLFT5RmzwoTu1vxFFAq8PLsicB7_M,359
25
24
  nonebot_plugin_l4d2_server/l4d2_data/__init__.py,sha256=-Gqzs0WmYT0atAmm25hYszgFi2Zp1dlVQtF_CNoNchc,3241
26
25
  nonebot_plugin_l4d2_server/l4d2_data/config.py,sha256=RTPayMBDU2f4losEwAZ9BPKbJNDpmmEeheskWVIueI8,468
26
+ nonebot_plugin_l4d2_server/l4d2_data/database.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  nonebot_plugin_l4d2_server/l4d2_data/players.py,sha256=kaXcBA8RO5eVTicb6up9pwdE-T2afkc1NykYFQ80poI,3221
28
28
  nonebot_plugin_l4d2_server/l4d2_data/serverip.py,sha256=c78UuSOMLaOBvfIayKo7xiQELYj8UMvM1A91D1E2f0s,1284
29
29
  nonebot_plugin_l4d2_server/l4d2_file/__init__.py,sha256=3gVBmEBVb7kVtjeTN7oxWbG8MxbkRtDBE9KNpoVAnhc,4075
@@ -32,23 +32,37 @@ nonebot_plugin_l4d2_server/l4d2_file/remote.py,sha256=uAcCbDAq9RIookmHl41PfQTpHy
32
32
  nonebot_plugin_l4d2_server/l4d2_image/__init__.py,sha256=fAjFLMkl7Kl4_2pE_wSi74IVzr5XsxLD3H_fPK3DgmM,4036
33
33
  nonebot_plugin_l4d2_server/l4d2_image/download.py,sha256=mdz3Q60peiq0B2oK3IOjDSe32guVH4gBM1Xwrrc4-rI,3996
34
34
  nonebot_plugin_l4d2_server/l4d2_image/htmlimg.py,sha256=DKG2ENh1HOCY7P41hIJTGGLizsTwR_nf05DR3vFWxRQ,1038
35
+ nonebot_plugin_l4d2_server/l4d2_image/image.py,sha256=L6AWkyAq-UJTlT6yvPbdkFScZg0g1E9hNwUkrTsDImE,9524
35
36
  nonebot_plugin_l4d2_server/l4d2_image/send_image_tool.py,sha256=bXZKD6NhVr4FVJd5YY9Fcg5qDeA5_kQEQvv--CAO57Y,936
36
37
  nonebot_plugin_l4d2_server/l4d2_image/steam.py,sha256=_jsz96aw0ie67gE0Y_15qsjqW4tVe4IdC-xg3H0l21c,3799
37
38
  nonebot_plugin_l4d2_server/l4d2_image/vtfs.py,sha256=MawVMrGOrFZ7b8F_XGAMJPvd-grKfbRamDZAWxFXclQ,1387
38
39
  nonebot_plugin_l4d2_server/l4d2_queries/__init__.py,sha256=fS6Kdi2M_U-epbIMyiPRdnhcnb57RydnUHkJMam0ZVc,3791
39
- nonebot_plugin_l4d2_server/l4d2_queries/api.py,sha256=wkmdxR_gojvJiA1-gyL4Bd0ukyw14CUnd7GIOfS41y4,1109
40
+ nonebot_plugin_l4d2_server/l4d2_queries/api.py,sha256=r-pnXh2ZGyR84M4k5OzYNIWcWD0lq8FmFk6hn7NoQFk,1157
40
41
  nonebot_plugin_l4d2_server/l4d2_queries/ohter.py,sha256=ssq1GKBWa5zrbytmdFwNxr9bSiRyrDTn2aoeb0tGoP0,1191
41
42
  nonebot_plugin_l4d2_server/l4d2_queries/qqgroup.py,sha256=l7gEwy_2M134Gu4U__1mwJH7mx7bQazYMPQvf_E9fJs,10826
42
43
  nonebot_plugin_l4d2_server/l4d2_server/__init__.py,sha256=AKufLXRnvzLi31aJLURqZenXjeOf0xRftBwHSugMasE,1615
44
+ nonebot_plugin_l4d2_server/l4d2_server/index.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
45
  nonebot_plugin_l4d2_server/l4d2_server/rcon.py,sha256=WmIt-hCTKC0swceO-hxeBHeKS_Srxtzfvpqay7O6RdE,1237
44
46
  nonebot_plugin_l4d2_server/l4d2_server/workshop.py,sha256=MLEGqU_m9zDDQVppExCJAKe_G340QL-VrPkJpXTkpOM,1359
47
+ nonebot_plugin_l4d2_server/l4d2_update/__init__.py,sha256=gGt7DNbaxHmSVtC37YVr__aSjLuF-Pk6dPLS_twztHg,4093
48
+ nonebot_plugin_l4d2_server/l4d2_update/draw_update_log.py,sha256=pTz1GJ6dZ8fzjheJQCWmNDvekxQKJBrx-_4wJwqHzRI,1179
49
+ nonebot_plugin_l4d2_server/l4d2_update/restart.py,sha256=4xj6awHhhzX_Jh4hWWUpWPQf0bKFXWrPg0w_lhPCNko,2024
50
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/art.png,sha256=QAvaSduHhaq1Fd43JIIHAqcjJajcVsKhIuOF3Nnajdw,3872
51
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/bento.png,sha256=OgW84QrjAsLVn5iDGPR4p9cc1cucY2L9YZa8awvKhEQ,4448
52
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/bug.png,sha256=u1OwznUVim5jitwekswgVVGRFrkBM7jFx7nGM4bfYCY,3575
53
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/feat.png,sha256=D7lUdbvyme0Wup2yZPDltuVLm7TsreLKtHljUSgAEYc,3760
54
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/log_title.png,sha256=KstYz0Ff4rcAPg0sycjvfrJIw_2uG1-QlWSYiTuFC0o,137862
55
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/other.png,sha256=BgIQtvI1pXgswQGVQkCCr5fZf2qr4uPb25AR9mWDR2g,3028
56
+ nonebot_plugin_l4d2_server/l4d2_update/texture2d/zap.png,sha256=Ydg07QYQLeCOzeH7L9Nm_qv37R-mJuawttMhhhkdkHU,2346
57
+ nonebot_plugin_l4d2_server/l4d2_update/update.py,sha256=br_K16vBYlTafF_u_aiRAbb8FBJsYLLgmV-_x9KKePo,1968
45
58
  nonebot_plugin_l4d2_server/l4d2_web/web.py,sha256=qMWySCsJCHoAZJHWhkqq6qfmNLxAUhSpnAhcArVXWv0,8542
46
59
  nonebot_plugin_l4d2_server/l4d2_web/webUI.py,sha256=9u8zhT9pocdVXpH15_vZR8qvvGbWjYv2mYso_uJYBww,14148
47
60
  nonebot_plugin_l4d2_server/message.py,sha256=vTrTyXWF4fCEH-IlmvKeGv-J7oCkbrXhFwsAHFcivtg,1620
61
+ nonebot_plugin_l4d2_server/rule.py,sha256=j1EEh9PgvFmbq5fQhOonA-3t13wnRM6R44Jkp8hCNQw,337
48
62
  nonebot_plugin_l4d2_server/seach.py,sha256=Box5QORfNfpMYDdwNeR309dP1wtivBOxcgrxdJSduSw,992
49
63
  nonebot_plugin_l4d2_server/txt_to_img.py,sha256=hzwLVGoOjLAQb3Br43vu1IWW23DuxKW6yTuxMCLhWoY,2133
50
- nonebot_plugin_l4d2_server/utils.py,sha256=zeFG7VD3aJXtXZhjw-imeTe8RSkAK4Kpx4IV1ud-rsQ,8035
51
- nonebot_plugin_l4d2_server-0.5.2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
52
- nonebot_plugin_l4d2_server-0.5.2.dist-info/METADATA,sha256=OQ6BKw-7x7R-2mVlHtlLpKtJPjoJBhJ8TFJCyH2TD5o,13030
53
- nonebot_plugin_l4d2_server-0.5.2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
54
- nonebot_plugin_l4d2_server-0.5.2.dist-info/RECORD,,
64
+ nonebot_plugin_l4d2_server/utils.py,sha256=DmL09vlLLmoWVtX9C-E32npRFHGd4Q20LU3CZfTPoN4,8624
65
+ nonebot_plugin_l4d2_server-0.5.3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
66
+ nonebot_plugin_l4d2_server-0.5.3.dist-info/METADATA,sha256=ufFA8VbxjNEEaBJ2Cmd0XGOi-YwLMdsOo-n_zfW6JVw,13263
67
+ nonebot_plugin_l4d2_server-0.5.3.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
68
+ nonebot_plugin_l4d2_server-0.5.3.dist-info/RECORD,,
@@ -1,45 +0,0 @@
1
- try:
2
- from selenium import webdriver
3
- from selenium.webdriver.chrome.options import Options
4
- from selenium.webdriver.common.by import By
5
- except:
6
- pass
7
- url = 'https://server.trygek.com/index.php'
8
-
9
-
10
- def get_anne_server():
11
- chrome_options = Options()
12
- chrome_options.add_argument('--no-sandbox') #“–no-sandbox”参数是让Chrome在root权限下跑
13
- chrome_options.add_argument('--ignore-certificate-errors')
14
- chrome_options.add_argument('--disable-dev-shm-usage')
15
- chrome_options.add_argument('-ignore-certificate-errors')
16
- chrome_options.add_argument('--headless') #“–headless”参数是不用打开图形界面
17
- driver = webdriver.Chrome(chrome_options=chrome_options)
18
- print('启动成功')
19
- # browser.get(url)
20
- # browser.add_cookie({'name':'token','value':token_value})
21
- driver.get(url)
22
- print('网页已打开,正在浏览')
23
- i = 0
24
- n = 1
25
- msg = ''
26
- while i <= 40:
27
- try:
28
- i += 1
29
- mes =''
30
- xpath1 = '//*[@id="host_{}"]'.format(i)
31
- xpath2 = '/html/body/main/div[3]/div[5]/div/div/table/tbody/tr[{}]/td[5]'.format(n)
32
- xpath3 = '//*[@id="players_{}"]'.format(i)
33
- xpath4 = '//*[@id="map_{}"]'.format(i)
34
- xpath = [xpath1,xpath2,xpath3,xpath4]
35
- names = ['服务器名称','服务器ip','玩家','地图']
36
- for x in range(5):
37
- name:str = driver.find_element(By.XPATH,xpath[x-1]).text
38
- mes += names[x-1] + '' + name + '\n'
39
- msg += mes
40
- msg += '--------------------\n'
41
- n += 2
42
- except :
43
- continue
44
- return msg
45
-