nonebot-plugin-l4d2-server 0.5.0__py3-none-any.whl → 0.5.2__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 (49) hide show
  1. LICENSE +674 -674
  2. README.md +365 -349
  3. nonebot_plugin_l4d2_server/__init__.py +1 -1
  4. nonebot_plugin_l4d2_server/chrome.py +45 -0
  5. nonebot_plugin_l4d2_server/command.py +232 -233
  6. nonebot_plugin_l4d2_server/config.py +210 -318
  7. nonebot_plugin_l4d2_server/data/L4D2/image/template/anne.html +60 -60
  8. nonebot_plugin_l4d2_server/data/L4D2/image/template/fingerprint.svg +15 -15
  9. nonebot_plugin_l4d2_server/data/L4D2/image/template/help.html +233 -233
  10. nonebot_plugin_l4d2_server/data/L4D2/image/template/help_dack.html +231 -231
  11. nonebot_plugin_l4d2_server/data/L4D2/image/template/ip.html +48 -48
  12. nonebot_plugin_l4d2_server/data/L4D2/image/template/l.svg +9 -9
  13. nonebot_plugin_l4d2_server/data/L4D2/image/template/vue.css +530 -530
  14. nonebot_plugin_l4d2_server/l4d2_anne/__init__.py +251 -251
  15. nonebot_plugin_l4d2_server/l4d2_anne/analysis.py +51 -51
  16. nonebot_plugin_l4d2_server/l4d2_anne/anne_telecom.py +75 -75
  17. nonebot_plugin_l4d2_server/l4d2_anne/server.py +65 -65
  18. nonebot_plugin_l4d2_server/l4d2_anne/startand.py +17 -17
  19. nonebot_plugin_l4d2_server/l4d2_data/__init__.py +91 -91
  20. nonebot_plugin_l4d2_server/l4d2_data/config.py +17 -17
  21. nonebot_plugin_l4d2_server/l4d2_data/players.py +87 -87
  22. nonebot_plugin_l4d2_server/l4d2_data/serverip.py +32 -32
  23. nonebot_plugin_l4d2_server/l4d2_file/__init__.py +122 -122
  24. nonebot_plugin_l4d2_server/l4d2_file/ayromote.py +56 -56
  25. nonebot_plugin_l4d2_server/l4d2_file/remote.py +63 -66
  26. nonebot_plugin_l4d2_server/l4d2_image/__init__.py +103 -103
  27. nonebot_plugin_l4d2_server/l4d2_image/download.py +101 -101
  28. nonebot_plugin_l4d2_server/l4d2_image/htmlimg.py +32 -32
  29. nonebot_plugin_l4d2_server/l4d2_image/send_image_tool.py +32 -32
  30. nonebot_plugin_l4d2_server/l4d2_image/steam.py +83 -83
  31. nonebot_plugin_l4d2_server/l4d2_image/vtfs.py +40 -40
  32. nonebot_plugin_l4d2_server/l4d2_queries/__init__.py +114 -114
  33. nonebot_plugin_l4d2_server/l4d2_queries/api.py +43 -43
  34. nonebot_plugin_l4d2_server/l4d2_queries/ohter.py +35 -25
  35. nonebot_plugin_l4d2_server/l4d2_queries/qqgroup.py +288 -288
  36. nonebot_plugin_l4d2_server/l4d2_server/__init__.py +61 -61
  37. nonebot_plugin_l4d2_server/l4d2_server/rcon.py +28 -28
  38. nonebot_plugin_l4d2_server/l4d2_server/workshop.py +50 -50
  39. nonebot_plugin_l4d2_server/l4d2_web/web.py +234 -234
  40. nonebot_plugin_l4d2_server/l4d2_web/webUI.py +241 -241
  41. nonebot_plugin_l4d2_server/message.py +58 -58
  42. nonebot_plugin_l4d2_server/seach.py +33 -33
  43. nonebot_plugin_l4d2_server/txt_to_img.py +64 -64
  44. nonebot_plugin_l4d2_server/utils.py +272 -272
  45. {nonebot_plugin_l4d2_server-0.5.0.dist-info → nonebot_plugin_l4d2_server-0.5.2.dist-info}/LICENSE +674 -674
  46. {nonebot_plugin_l4d2_server-0.5.0.dist-info → nonebot_plugin_l4d2_server-0.5.2.dist-info}/METADATA +47 -32
  47. nonebot_plugin_l4d2_server-0.5.2.dist-info/RECORD +54 -0
  48. nonebot_plugin_l4d2_server-0.5.0.dist-info/RECORD +0 -53
  49. {nonebot_plugin_l4d2_server-0.5.0.dist-info → nonebot_plugin_l4d2_server-0.5.2.dist-info}/WHEEL +0 -0
@@ -1,32 +1,32 @@
1
- from io import BytesIO
2
- from pathlib import Path
3
- from typing import Union
4
- from base64 import b64encode
5
-
6
- from PIL import Image
7
-
8
-
9
- async def convert_img(
10
- img: Union[Image.Image, str, Path, bytes], is_base64: bool = False
11
- ):
12
- """
13
- :说明:
14
- 将PIL.Image对象转换为bytes或者base64格式。
15
- :参数:
16
- * img (Image): 图片。
17
- * is_base64 (bool): 是否转换为base64格式, 不填默认转为bytes。
18
- :返回:
19
- * res: bytes对象或base64编码图片。
20
- """
21
- if isinstance(img, Image.Image):
22
- img = img.convert('RGBA')
23
- result_buffer = BytesIO()
24
- img.save(result_buffer, format='PNG', quality=80, subsampling=0)
25
- res = result_buffer.getvalue()
26
- if is_base64:
27
- res = b64encode(res).decode()
28
- return res
29
- elif isinstance(img, bytes):
30
- return b64encode(img).decode()
31
- else:
32
- return f'[CQ:image,file=file:///{str(img)}]'
1
+ from io import BytesIO
2
+ from pathlib import Path
3
+ from typing import Union
4
+ from base64 import b64encode
5
+
6
+ from PIL import Image
7
+
8
+
9
+ async def convert_img(
10
+ img: Union[Image.Image, str, Path, bytes], is_base64: bool = False
11
+ ):
12
+ """
13
+ :说明:
14
+ 将PIL.Image对象转换为bytes或者base64格式。
15
+ :参数:
16
+ * img (Image): 图片。
17
+ * is_base64 (bool): 是否转换为base64格式, 不填默认转为bytes。
18
+ :返回:
19
+ * res: bytes对象或base64编码图片。
20
+ """
21
+ if isinstance(img, Image.Image):
22
+ img = img.convert('RGBA')
23
+ result_buffer = BytesIO()
24
+ img.save(result_buffer, format='PNG', quality=80, subsampling=0)
25
+ res = result_buffer.getvalue()
26
+ if is_base64:
27
+ res = b64encode(res).decode()
28
+ return res
29
+ elif isinstance(img, bytes):
30
+ return b64encode(img).decode()
31
+ else:
32
+ return f'[CQ:image,file=file:///{str(img)}]'
@@ -1,83 +1,83 @@
1
- # from PIL import Image
2
- import httpx
3
- import aiohttp
4
- # from bs4 import BeautifulSoup
5
- from urllib.parse import unquote
6
-
7
-
8
- # async def web_player(url) -> Image :
9
- # """steam个人资料获取头像"""
10
- # data = BeautifulSoup(await url_for_byte(url), 'html.parser')
11
- # print(data)
12
- # head = data.find("div", class_="playerAvatarAutoSizeInner")
13
- # img_elements = head.find_all("img")
14
- # if len(img_elements)== 1:
15
- # for img_element in img_elements:
16
- # head = await url_for_byte(img_element["src"])
17
- # im = Image.open(io.BytesIO(head)).resize((225, 225)).convert("RGBA")
18
- # if len(img_elements) == 2:
19
- # head,headd = img_elements
20
- # head = await url_for_byte(img_element["src"])
21
- # head = await url_for_byte(img_element["src"])
22
- # # 下面是边框,不一定有
23
- # try:
24
- # headd = data.select("html.responsive body.flat_page.profile_page.has_profile_background.GhostTheme.responsive_page div.responsive_page_frame.with_header div.responsive_page_content div#responsive_page_template_content.responsive_page_template_content div.no_header.profile_page.has_profile_background div.profile_header_bg div.profile_header_bg_texture div.profile_header div.profile_header_content div.playerAvatar.profile_header_size.in-game div.playerAvatarAutoSizeInner div.profile_avatar_frame img")
25
- # im2 = Image.open(io.BytesIO(headd)).resize((185, 185)).convert("RGBA")
26
- # r, g, b, a2 = im2.split()
27
- # # im.paste(im2,(20,20),mask=a2)
28
- # except IndexError:
29
- # pass
30
- # return im
31
-
32
- # async def url_for_byte(url):
33
- # """所有代理_url终将绳之以法"""
34
- # if not l4_proxies:
35
- # print("代理不存在")
36
- # data = await url_to_byte(url)
37
- # headers = {
38
- # 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
39
- # }
40
- # data = httpx.get(url,headers=headers,proxies=l4_proxies,timeout=60,verify=False).content
41
- # return data
42
- async def url_to_byte(url:str,filename:str =''):
43
- """获取URL数据的字节流"""
44
- headers = {
45
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
46
- }
47
- async with aiohttp.ClientSession() as session:
48
- async with session.get(url, headers=headers, timeout=600) as response:
49
- if response.status == 200:
50
- return await response.read()
51
- else:
52
- return None
53
-
54
- async def url_to_byte_name(url:str,filename:str =''):
55
- """获取URL数据的字节流"""
56
- headers = {
57
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
58
- }
59
- if filename == "htp":
60
- response = httpx.get(url,headers=headers,timeout=600)
61
- content_disposition:str = response.headers.get("Content-Disposition")
62
- if not content_disposition:
63
- return None
64
- elif "''" in content_disposition:
65
- file_name = content_disposition.split("''")[-1]
66
- else:
67
- file_name = content_disposition
68
- file_name = unquote(file_name)
69
- return [response.read(),file_name]
70
- else:
71
- async with aiohttp.ClientSession() as session:
72
- async with session.get(url, headers=headers, timeout=600) as response:
73
- content_disposition:str = response.headers.get("Content-Disposition")
74
- if "''" in content_disposition:
75
- file_name = content_disposition.split("''")[-1]
76
- else:
77
- file_name = content_disposition
78
- file_name = unquote(file_name)
79
- if response.status == 200:
80
- return [await response.read(),file_name]
81
- else:
82
- return None
83
-
1
+ # from PIL import Image
2
+ import httpx
3
+ import aiohttp
4
+ # from bs4 import BeautifulSoup
5
+ from urllib.parse import unquote
6
+
7
+
8
+ # async def web_player(url) -> Image :
9
+ # """steam个人资料获取头像"""
10
+ # data = BeautifulSoup(await url_for_byte(url), 'html.parser')
11
+ # print(data)
12
+ # head = data.find("div", class_="playerAvatarAutoSizeInner")
13
+ # img_elements = head.find_all("img")
14
+ # if len(img_elements)== 1:
15
+ # for img_element in img_elements:
16
+ # head = await url_for_byte(img_element["src"])
17
+ # im = Image.open(io.BytesIO(head)).resize((225, 225)).convert("RGBA")
18
+ # if len(img_elements) == 2:
19
+ # head,headd = img_elements
20
+ # head = await url_for_byte(img_element["src"])
21
+ # head = await url_for_byte(img_element["src"])
22
+ # # 下面是边框,不一定有
23
+ # try:
24
+ # headd = data.select("html.responsive body.flat_page.profile_page.has_profile_background.GhostTheme.responsive_page div.responsive_page_frame.with_header div.responsive_page_content div#responsive_page_template_content.responsive_page_template_content div.no_header.profile_page.has_profile_background div.profile_header_bg div.profile_header_bg_texture div.profile_header div.profile_header_content div.playerAvatar.profile_header_size.in-game div.playerAvatarAutoSizeInner div.profile_avatar_frame img")
25
+ # im2 = Image.open(io.BytesIO(headd)).resize((185, 185)).convert("RGBA")
26
+ # r, g, b, a2 = im2.split()
27
+ # # im.paste(im2,(20,20),mask=a2)
28
+ # except IndexError:
29
+ # pass
30
+ # return im
31
+
32
+ # async def url_for_byte(url):
33
+ # """所有代理_url终将绳之以法"""
34
+ # if not l4_proxies:
35
+ # print("代理不存在")
36
+ # data = await url_to_byte(url)
37
+ # headers = {
38
+ # 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
39
+ # }
40
+ # data = httpx.get(url,headers=headers,proxies=l4_proxies,timeout=60,verify=False).content
41
+ # return data
42
+ async def url_to_byte(url:str,filename:str =''):
43
+ """获取URL数据的字节流"""
44
+ headers = {
45
+ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
46
+ }
47
+ async with aiohttp.ClientSession() as session:
48
+ async with session.get(url, headers=headers, timeout=600) as response:
49
+ if response.status == 200:
50
+ return await response.read()
51
+ else:
52
+ return None
53
+
54
+ async def url_to_byte_name(url:str,filename:str =''):
55
+ """获取URL数据的字节流"""
56
+ headers = {
57
+ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
58
+ }
59
+ if filename == "htp":
60
+ response = httpx.get(url,headers=headers,timeout=600)
61
+ content_disposition:str = response.headers.get("Content-Disposition")
62
+ if not content_disposition:
63
+ return None
64
+ elif "''" in content_disposition:
65
+ file_name = content_disposition.split("''")[-1]
66
+ else:
67
+ file_name = content_disposition
68
+ file_name = unquote(file_name)
69
+ return [response.read(),file_name]
70
+ else:
71
+ async with aiohttp.ClientSession() as session:
72
+ async with session.get(url, headers=headers, timeout=600) as response:
73
+ content_disposition:str = response.headers.get("Content-Disposition")
74
+ if "''" in content_disposition:
75
+ file_name = content_disposition.split("''")[-1]
76
+ else:
77
+ file_name = content_disposition
78
+ file_name = unquote(file_name)
79
+ if response.status == 200:
80
+ return [await response.read(),file_name]
81
+ else:
82
+ return None
83
+
@@ -1,40 +1,40 @@
1
-
2
- from PIL import Image
3
- from nonebot.log import logger
4
- from io import BytesIO
5
- # import sys
6
- # sys.modules["srctools._cy_vtf_readwrite"] = None
7
- from srctools.vtf import VTF, ImageFormats
8
-
9
- async def img_to_vtf(pic_byte:bytes,tag) -> BytesIO:
10
- pic = BytesIO(pic_byte)
11
- pic = Image.open(pic).convert('RGBA')
12
- vtf_io = BytesIO()
13
- vtf_ = VTF(1024, 1024, fmt = ImageFormats.DXT5,thumb_fmt = ImageFormats.DXT1,version=(7,2))
14
- if tag == '覆盖':
15
- logger.info(tag)
16
- img2 = Image.new('RGBA',(1024, 1024), (255, 255, 255,0))
17
- r, g, b, a = pic.split()
18
- img2.paste(pic,mask=a)
19
- pic = pic.resize((1024,1024))
20
- elif tag == '填充':
21
- w, h = pic.size
22
- if w > h:
23
- ratio = 1024/w
24
- new_width = 1024
25
- new_height = int(h * ratio)
26
- else:
27
- ratio = 1024/h
28
- new_height = 1024
29
- new_width = int(w * ratio)
30
- pic = pic.resize((new_width, new_height), Image.ANTIALIAS)
31
- background = Image.new('RGBA', (1024, 1024), (255, 255, 255, 0))
32
- background.paste(pic, ((1024-new_width)//2, (1024-new_height)//2))
33
- pic = background
34
- else:
35
- logger.info('拉伸')
36
- pic = pic.resize((1024,1024))
37
- largest_frame = vtf_.get()
38
- largest_frame.copy_from(pic.tobytes(), ImageFormats.RGBA8888)
39
- vtf_.save(vtf_io,version=(7,2))
40
- return vtf_io
1
+
2
+ from PIL import Image
3
+ from nonebot.log import logger
4
+ from io import BytesIO
5
+ # import sys
6
+ # sys.modules["srctools._cy_vtf_readwrite"] = None
7
+ from srctools.vtf import VTF, ImageFormats
8
+
9
+ async def img_to_vtf(pic_byte:bytes,tag) -> BytesIO:
10
+ pic = BytesIO(pic_byte)
11
+ pic = Image.open(pic).convert('RGBA')
12
+ vtf_io = BytesIO()
13
+ vtf_ = VTF(1024, 1024, fmt = ImageFormats.DXT5,thumb_fmt = ImageFormats.DXT1,version=(7,2))
14
+ if tag == '覆盖':
15
+ logger.info(tag)
16
+ img2 = Image.new('RGBA',(1024, 1024), (255, 255, 255,0))
17
+ r, g, b, a = pic.split()
18
+ img2.paste(pic,mask=a)
19
+ pic = pic.resize((1024,1024))
20
+ elif tag == '填充':
21
+ w, h = pic.size
22
+ if w > h:
23
+ ratio = 1024/w
24
+ new_width = 1024
25
+ new_height = int(h * ratio)
26
+ else:
27
+ ratio = 1024/h
28
+ new_height = 1024
29
+ new_width = int(w * ratio)
30
+ pic = pic.resize((new_width, new_height), Image.ANTIALIAS)
31
+ background = Image.new('RGBA', (1024, 1024), (255, 255, 255, 0))
32
+ background.paste(pic, ((1024-new_width)//2, (1024-new_height)//2))
33
+ pic = background
34
+ else:
35
+ logger.info('拉伸')
36
+ pic = pic.resize((1024,1024))
37
+ largest_frame = vtf_.get()
38
+ largest_frame.copy_from(pic.tobytes(), ImageFormats.RGBA8888)
39
+ vtf_.save(vtf_io,version=(7,2))
40
+ return vtf_io
@@ -1,114 +1,114 @@
1
- import a2s
2
- from typing import List
3
-
4
- async def queries(ip:str,port:int):
5
- port = int(port)
6
- msg_dict = await queries_dict(ip,port)
7
- message = 'ip:' + msg_dict['ip'] + '\n'
8
- message += '名称:' + msg_dict['name'] + '\n'
9
- message += f"地图:{msg_dict['map_']}\n"
10
- message += f"延迟:{msg_dict['ping']}\n"
11
- message += f"玩家:{msg_dict['players']} / {msg_dict['max_players']}\n"
12
- return message
13
-
14
- async def queries_dict(ip:str,port:int) -> dict:
15
- port = int(port)
16
- ip = str(ip)
17
- msg_dict = {}
18
- # message_dict = await l4d(ip,port)
19
- msg:a2s.SourceInfo = await a2s.ainfo((ip,port))
20
- # message_dict = await l4d2.server(ip,port,times=5)
21
- msg_dict['folder'] = msg.folder
22
- msg_dict['name'] = msg.server_name
23
- msg_dict['map_'] = msg.map_name
24
- msg_dict['players'] = msg.player_count
25
- msg_dict['max_players'] = msg.max_players
26
- msg_dict['rank_players'] = f'{msg.player_count}/{msg.max_players}'
27
- msg_dict['ip'] = str(ip) + ':' +str(port)
28
- msg_dict['ping'] = f"{msg.ping*1000:.0f}ms"
29
- msg_dict['system'] = f"{msg.platform}.svg"
30
- if msg_dict['players'] < msg_dict['max_players']:
31
- msg_dict['enabled'] = True
32
- else:
33
- msg_dict['enabled'] = False
34
- return msg_dict
35
-
36
- async def player_queries_anne_dict(ip:str,port:int):
37
- """anne算法返回玩家"""
38
- port = int(port)
39
- # message_dic = await l4d2.APlayer(ip,port,times=5)
40
- message_list:List[a2s.Player] = await a2s.aplayers((ip,port))
41
- msg_list = []
42
- if message_list != []:
43
- for i in message_list:
44
- msg_list.append({
45
- 'name':i.name,
46
- 'Score':i.score,
47
- 'Duration':await convert_duration(i.duration)
48
- })
49
- return msg_list
50
-
51
- # async def player_queries_dict(ip:str,port:int):
52
- # """一般算法返回玩家"""
53
- # port = int(port)
54
- # new_dict = {}
55
- # message_dic = await l4d2.APlayer(ip,port,times=5)
56
- # if message_dic == {}:
57
- # new_dict['header'] = 0
58
- # else:
59
- # pass
60
- # new_list = []
61
- # for i in message_dic['Players']:
62
- # new_list.append(i['Name'])
63
- # new_dict.update({'Players':new_list})
64
- # return new_dict
65
-
66
- async def player_queries(ip:str,port:int):
67
- port = int(port)
68
- message_list = await player_queries_anne_dict(ip,port)
69
- return await msg_ip_to_list(message_list)
70
-
71
- async def msg_ip_to_list(message_list:list):
72
- message = ''
73
- n = 0
74
- if message_list == []:
75
- message += '服务器里,是空空的呢\n'
76
- else:
77
- max_duration_len = max([len(str(i['Duration'])) for i in message_list])
78
- max_score_len = max([len(str(i['Score'])) for i in message_list])
79
- for i in message_list:
80
- print(i)
81
- n += 1
82
- name = i['name']
83
- Score = i['Score']
84
- if Score == '0':
85
- Score = '摸'
86
- Duration = i['Duration']
87
- soc = "[{:>{}}]".format(Score,max_score_len)
88
- dur = "{:^{}}".format(Duration, max_duration_len)
89
- message += f'{soc} | {dur} | {name} \n'
90
- return message
91
-
92
- async def convert_duration(duration: int) -> str:
93
- minutes, seconds = divmod(duration, 60)
94
- hours, minutes = divmod(minutes, 60)
95
- time_str = ""
96
- if hours > 0:
97
- time_str += f"{int(hours)}h "
98
- if minutes > 0 or hours > 0:
99
- time_str += f"{int(minutes)}m "
100
- time_str += f"{int(seconds)}s"
101
- return time_str.strip()
102
-
103
- async def server_rule_dict(ip:str,port:int):
104
- port = int(port)
105
- ip = str(ip)
106
- msg_dict = {}
107
- # message_dict = await l4d(ip,port)
108
- try:
109
- msg:dict = await a2s.arules((ip,port))
110
- msg_dict['tick'] = msg['l4d2_tickrate_enabler'] + "tick"
111
- except:
112
- msg_dict['tick'] = ''
113
- return msg_dict
114
-
1
+ import a2s
2
+ from typing import List
3
+
4
+ async def queries(ip:str,port:int):
5
+ port = int(port)
6
+ msg_dict = await queries_dict(ip,port)
7
+ message = 'ip:' + msg_dict['ip'] + '\n'
8
+ message += '名称:' + msg_dict['name'] + '\n'
9
+ message += f"地图:{msg_dict['map_']}\n"
10
+ message += f"延迟:{msg_dict['ping']}\n"
11
+ message += f"玩家:{msg_dict['players']} / {msg_dict['max_players']}\n"
12
+ return message
13
+
14
+ async def queries_dict(ip:str,port:int) -> dict:
15
+ port = int(port)
16
+ ip = str(ip)
17
+ msg_dict = {}
18
+ # message_dict = await l4d(ip,port)
19
+ msg:a2s.SourceInfo = await a2s.ainfo((ip,port))
20
+ # message_dict = await l4d2.server(ip,port,times=5)
21
+ msg_dict['folder'] = msg.folder
22
+ msg_dict['name'] = msg.server_name
23
+ msg_dict['map_'] = msg.map_name
24
+ msg_dict['players'] = msg.player_count
25
+ msg_dict['max_players'] = msg.max_players
26
+ msg_dict['rank_players'] = f'{msg.player_count}/{msg.max_players}'
27
+ msg_dict['ip'] = str(ip) + ':' +str(port)
28
+ msg_dict['ping'] = f"{msg.ping*1000:.0f}ms"
29
+ msg_dict['system'] = f"{msg.platform}.svg"
30
+ if msg_dict['players'] < msg_dict['max_players']:
31
+ msg_dict['enabled'] = True
32
+ else:
33
+ msg_dict['enabled'] = False
34
+ return msg_dict
35
+
36
+ async def player_queries_anne_dict(ip:str,port:int):
37
+ """anne算法返回玩家"""
38
+ port = int(port)
39
+ # message_dic = await l4d2.APlayer(ip,port,times=5)
40
+ message_list:List[a2s.Player] = await a2s.aplayers((ip,port))
41
+ msg_list = []
42
+ if message_list != []:
43
+ for i in message_list:
44
+ msg_list.append({
45
+ 'name':i.name,
46
+ 'Score':i.score,
47
+ 'Duration':await convert_duration(i.duration)
48
+ })
49
+ return msg_list
50
+
51
+ # async def player_queries_dict(ip:str,port:int):
52
+ # """一般算法返回玩家"""
53
+ # port = int(port)
54
+ # new_dict = {}
55
+ # message_dic = await l4d2.APlayer(ip,port,times=5)
56
+ # if message_dic == {}:
57
+ # new_dict['header'] = 0
58
+ # else:
59
+ # pass
60
+ # new_list = []
61
+ # for i in message_dic['Players']:
62
+ # new_list.append(i['Name'])
63
+ # new_dict.update({'Players':new_list})
64
+ # return new_dict
65
+
66
+ async def player_queries(ip:str,port:int):
67
+ port = int(port)
68
+ message_list = await player_queries_anne_dict(ip,port)
69
+ return await msg_ip_to_list(message_list)
70
+
71
+ async def msg_ip_to_list(message_list:list):
72
+ message = ''
73
+ n = 0
74
+ if message_list == []:
75
+ message += '服务器里,是空空的呢\n'
76
+ else:
77
+ max_duration_len = max([len(str(i['Duration'])) for i in message_list])
78
+ max_score_len = max([len(str(i['Score'])) for i in message_list])
79
+ for i in message_list:
80
+ print(i)
81
+ n += 1
82
+ name = i['name']
83
+ Score = i['Score']
84
+ if Score == '0':
85
+ Score = '摸'
86
+ Duration = i['Duration']
87
+ soc = "[{:>{}}]".format(Score,max_score_len)
88
+ dur = "{:^{}}".format(Duration, max_duration_len)
89
+ message += f'{soc} | {dur} | {name} \n'
90
+ return message
91
+
92
+ async def convert_duration(duration: int) -> str:
93
+ minutes, seconds = divmod(duration, 60)
94
+ hours, minutes = divmod(minutes, 60)
95
+ time_str = ""
96
+ if hours > 0:
97
+ time_str += f"{int(hours)}h "
98
+ if minutes > 0 or hours > 0:
99
+ time_str += f"{int(minutes)}m "
100
+ time_str += f"{int(seconds)}s"
101
+ return time_str.strip()
102
+
103
+ async def server_rule_dict(ip:str,port:int):
104
+ port = int(port)
105
+ ip = str(ip)
106
+ msg_dict = {}
107
+ # message_dict = await l4d(ip,port)
108
+ try:
109
+ msg:dict = await a2s.arules((ip,port))
110
+ msg_dict['tick'] = msg['l4d2_tickrate_enabler'] + "tick"
111
+ except:
112
+ msg_dict['tick'] = ''
113
+ return msg_dict
114
+
@@ -1,43 +1,43 @@
1
- import httpx
2
- from typing import List,Union
3
- from nonebot.log import logger
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
34
-
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
43
-
1
+ import httpx
2
+ from typing import List,Union
3
+ from nonebot.log import logger
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
34
+
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
43
+