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,272 +1,272 @@
1
-
2
- from nonebot.adapters.onebot.v11 import Bot,MessageEvent,GroupMessageEvent
3
- from nonebot.log import logger
4
- import struct
5
- import httpx
6
- import os
7
- from pathlib import Path
8
-
9
- from typing import List,Dict,Union
10
- from .txt_to_img import txt_to_img
11
- from .config import *
12
- from .l4d2_anne import write_player,del_player,anne_messgae
13
- from .l4d2_server.rcon import read_server_cfg_rcon,rcon_server
14
- from .l4d2_queries import queries,player_queries
15
- from .l4d2_queries.qqgroup import *
16
- from .l4d2_server.workshop import workshop_to_dict
17
- from .l4d2_image.steam import url_to_byte
18
- import tempfile
19
- import random
20
-
21
-
22
-
23
- async def get_file(url: str, down_file: Path):
24
- '''
25
- 下载指定Url到指定位置
26
- '''
27
- try:
28
- if l4_config.l4_only:
29
- maps = await url_to_byte(url)
30
- else:
31
- maps = httpx.get(url).content
32
- logger.info('已获取文件,尝试新建文件并写入')
33
- with open(down_file, 'wb') as mfile:
34
- mfile.write(maps)
35
- logger.info('下载成功')
36
- return '文件已下载,正在解压'
37
- except Exception as e:
38
- logger.info(f"文件获取不到/已损坏:原因是{e}")
39
- return None
40
-
41
-
42
- def get_vpk(vpk_list: List[str], map_path: Path, file_: str = '.vpk') -> List[str]:
43
- '''
44
- 获取路径下所有vpk文件名,并存入vpk_list列表中
45
- '''
46
- vpk_list.extend([file for file in os.listdir(str(map_path)) if file.endswith(file_)])
47
- return vpk_list
48
-
49
-
50
-
51
- def mes_list(mes: str, name_list: List[str]) -> str:
52
- if name_list:
53
- for idx, name in enumerate(name_list):
54
- mes += f'\n{idx+1}、{name}'
55
- return mes
56
-
57
-
58
-
59
-
60
- def del_map(num: int, map_path: Path) -> str:
61
- '''
62
- 删除指定的地图
63
- '''
64
- map = get_vpk(map_path)
65
- map_name = map[num - 1]
66
- del_file = map_path / map_name
67
- os.remove(del_file)
68
- return map_name
69
-
70
-
71
- def rename_map(num: int, rename: str, map_path: Path) -> str:
72
- '''
73
- 改名指定的地图
74
- '''
75
- map = get_vpk(map_path)
76
- map_name = map[num - 1]
77
- old_file = map_path / map_name
78
- new_file = map_path / rename
79
- os.rename(old_file, new_file)
80
- logger.info('改名成功')
81
- return map_name
82
-
83
-
84
- def text_to_png(msg: str) -> bytes:
85
- """文字转png"""
86
- return txt_to_img(msg)
87
-
88
-
89
-
90
- def solve(msg:str):
91
- """删除str最后一行"""
92
- lines = msg.splitlines()
93
- lines.pop()
94
- return '\n'.join(lines)
95
-
96
-
97
- async def search_anne(name:str,usr_id:str):
98
- """获取anne成绩"""
99
- return await anne_messgae(name,usr_id)
100
-
101
-
102
- async def bind_steam(id:str,msg:str,nickname:str):
103
- """绑定qq-steam"""
104
- return await write_player(id,msg,nickname)
105
-
106
- def name_exist(id:str):
107
- """删除绑定信息"""
108
- return del_player(id)
109
-
110
- async def get_message_at(data: str) -> list:
111
- data = json.loads(data)
112
- return [int(msg['data']['qq']) for msg in data['message'] if msg['type'] == 'at']
113
-
114
-
115
-
116
- def at_to_usrid(at):
117
- return at[0] if at else None
118
-
119
-
120
- async def rcon_command(rcon, cmd):
121
- return await rcon_server(rcon, cmd.strip())
122
-
123
- async def command_server(msg: str):
124
- rcon = await read_server_cfg_rcon()
125
- msg = await rcon_command(rcon, msg)
126
- if not msg:
127
- msg = '你可能发送了一个无用指令,或者换图导致服务器无响应'
128
- elif msg.startswith('Unknown command'):
129
- msg = '无效指令:' + msg.replace('Unknown command', '').strip()
130
- return msg.strip().replace('\n', '')
131
-
132
-
133
-
134
-
135
- async def queries_server(msg:list) -> str:
136
- """查询ip返回信息"""
137
- ip = msg[0]
138
- port = msg[1]
139
- msgs = ''
140
- try:
141
- msgs = await queries(ip,port)
142
- msgs += await player_queries(ip,port)
143
- except (struct.error,TimeoutError):
144
- pass
145
- # except Exception:
146
- # msgs = '有无法识别的用户名'
147
- # return msgs
148
- return msgs
149
-
150
- async def add_ip(group_id,host,port):
151
- """先查找是否存在,如果不存在则创建"""
152
- return await bind_group_ip(group_id,host,port)
153
-
154
- async def del_ip(group_id,number):
155
- """删除群ip"""
156
- return await del_group_ip(group_id,number)
157
-
158
- async def show_ip(group_id):
159
- """先查找群ip,再根据群ip返回"""
160
- data_list = await get_qqgroup_ip_msg(group_id)
161
- logger.info(data_list)
162
- if len(data_list) == 0 :
163
- return "本群没有订阅"
164
- msg = await qq_ip_queries_pic(data_list)
165
- return msg
166
-
167
- async def get_number_url(number):
168
- 'connect AGNES.DIGITAL.LINE.PM:40001'
169
- ip = await get_server_ip(number)
170
- if not ip:
171
- return '该序号不存在'
172
- url = f'connect {ip}'
173
- return url
174
-
175
- async def workshop_msg(msg:str):
176
- """url变成id,拼接post请求"""
177
- if msg.startswith('https://steamcommunity.com/sharedfiles/filedetails/?id'):
178
- try:
179
- msg = msg.split('&')[0]
180
- except:
181
- pass
182
- msg = msg.replace('https://steamcommunity.com/sharedfiles/filedetails/?id=','')
183
- if msg.isdigit():
184
- data:Union[dict,List[dict]] = await workshop_to_dict(msg)
185
- return data
186
- else:
187
- return None
188
-
189
- async def save_file(file:bytes,path_name):
190
- """保存文件"""
191
- with open(path_name,'w') as files:
192
- files.write(file)
193
-
194
- async def get_anne_server_ip(ip):
195
- """输出查询ip和ping"""
196
- host,port = split_maohao(ip)
197
- data = await queries_server([host,port])
198
- lines = data.splitlines()
199
- msg = '\n'.join(lines[1:])
200
- msg += '\nconnect ' + ip
201
- return msg
202
-
203
- async def upload_file(bot: Bot, event: MessageEvent, file_data: bytes, filename: str):
204
- """上传临时文件"""
205
- if systems == "win" or "other":
206
- with tempfile.TemporaryDirectory() as temp_dir:
207
- with open(Path(temp_dir) / filename, "wb") as f:
208
- f.write(file_data)
209
- if isinstance(event, GroupMessageEvent):
210
- await bot.call_api(
211
- "upload_group_file", group_id=event.group_id, file=f.name, name=filename
212
- )
213
- else:
214
- await bot.call_api(
215
- "upload_private_file", user_id=event.user_id, file=f.name, name=filename
216
- )
217
- os.remove(Path().joinpath(filename))
218
- elif systems == "linux":
219
- with tempfile.NamedTemporaryFile("wb+") as f:
220
- f.write(file_data)
221
- if isinstance(event, GroupMessageEvent):
222
- await bot.call_api(
223
- "upload_group_file", group_id=event.group_id, file=f.name, name=filename
224
- )
225
- else:
226
- await bot.call_api(
227
- "upload_private_file", user_id=event.user_id, file=f.name, name=filename
228
- )
229
-
230
-
231
- async def json_server_to_tag_dict(key:str,msg:str):
232
- """
233
- l4d2字典转tag的dict结果
234
- - 1、先匹配腐竹
235
- - 2、再匹配模式、没有参数则从直接匹配最上面的
236
- - 3、匹配数字(几服),没有参数则从结果里随机返回一个
237
- """
238
- data_dict = {}
239
- data_list = []
240
- msg = msg.replace(' ','')
241
- # 腐竹循环
242
- for tag,value in ALL_HOST.items():
243
- value:List[dict]
244
- if tag == key:
245
- data_dict.update({'server':tag})
246
- if not msg:
247
- # 腐竹
248
- data_dict.update(random.choice(value))
249
- elif msg.isdigit():
250
- logger.info("腐竹 + 序号")
251
- for server in value:
252
- if msg == str(server['id']):
253
- data_dict.update(server)
254
- break
255
- else:
256
- logger.info("腐竹 + 模式 + 序号")
257
- for server in value:
258
- if msg.startswith(server['version']):
259
- data_list.append(server)
260
- msg_id = msg[len(server['version']):]
261
- if msg_id == str(server['id']):
262
- data_dict.update(server)
263
- break
264
- else:
265
- # 腐竹 + 模式
266
- data_dict.update(random.choice(data_list))
267
-
268
- logger.info(data_dict)
269
- return data_dict
270
-
271
-
272
-
1
+
2
+ from nonebot.adapters.onebot.v11 import Bot,MessageEvent,GroupMessageEvent
3
+ from nonebot.log import logger
4
+ import struct
5
+ import httpx
6
+ import os
7
+ from pathlib import Path
8
+
9
+ from typing import List,Dict,Union
10
+ from .txt_to_img import txt_to_img
11
+ from .config import *
12
+ from .l4d2_anne import write_player,del_player,anne_messgae
13
+ from .l4d2_server.rcon import read_server_cfg_rcon,rcon_server
14
+ from .l4d2_queries import queries,player_queries
15
+ from .l4d2_queries.qqgroup import *
16
+ from .l4d2_server.workshop import workshop_to_dict
17
+ from .l4d2_image.steam import url_to_byte
18
+ import tempfile
19
+ import random
20
+
21
+
22
+
23
+ async def get_file(url: str, down_file: Path):
24
+ '''
25
+ 下载指定Url到指定位置
26
+ '''
27
+ try:
28
+ if l4_config.l4_only:
29
+ maps = await url_to_byte(url)
30
+ else:
31
+ maps = httpx.get(url).content
32
+ logger.info('已获取文件,尝试新建文件并写入')
33
+ with open(down_file, 'wb') as mfile:
34
+ mfile.write(maps)
35
+ logger.info('下载成功')
36
+ return '文件已下载,正在解压'
37
+ except Exception as e:
38
+ logger.info(f"文件获取不到/已损坏:原因是{e}")
39
+ return None
40
+
41
+
42
+ def get_vpk(vpk_list: List[str], map_path: Path, file_: str = '.vpk') -> List[str]:
43
+ '''
44
+ 获取路径下所有vpk文件名,并存入vpk_list列表中
45
+ '''
46
+ vpk_list.extend([file for file in os.listdir(str(map_path)) if file.endswith(file_)])
47
+ return vpk_list
48
+
49
+
50
+
51
+ def mes_list(mes: str, name_list: List[str]) -> str:
52
+ if name_list:
53
+ for idx, name in enumerate(name_list):
54
+ mes += f'\n{idx+1}、{name}'
55
+ return mes
56
+
57
+
58
+
59
+
60
+ def del_map(num: int, map_path: Path) -> str:
61
+ '''
62
+ 删除指定的地图
63
+ '''
64
+ map = get_vpk(map_path)
65
+ map_name = map[num - 1]
66
+ del_file = map_path / map_name
67
+ os.remove(del_file)
68
+ return map_name
69
+
70
+
71
+ def rename_map(num: int, rename: str, map_path: Path) -> str:
72
+ '''
73
+ 改名指定的地图
74
+ '''
75
+ map = get_vpk(map_path)
76
+ map_name = map[num - 1]
77
+ old_file = map_path / map_name
78
+ new_file = map_path / rename
79
+ os.rename(old_file, new_file)
80
+ logger.info('改名成功')
81
+ return map_name
82
+
83
+
84
+ def text_to_png(msg: str) -> bytes:
85
+ """文字转png"""
86
+ return txt_to_img(msg)
87
+
88
+
89
+
90
+ def solve(msg:str):
91
+ """删除str最后一行"""
92
+ lines = msg.splitlines()
93
+ lines.pop()
94
+ return '\n'.join(lines)
95
+
96
+
97
+ async def search_anne(name:str,usr_id:str):
98
+ """获取anne成绩"""
99
+ return await anne_messgae(name,usr_id)
100
+
101
+
102
+ async def bind_steam(id:str,msg:str,nickname:str):
103
+ """绑定qq-steam"""
104
+ return await write_player(id,msg,nickname)
105
+
106
+ def name_exist(id:str):
107
+ """删除绑定信息"""
108
+ return del_player(id)
109
+
110
+ async def get_message_at(data: str) -> list:
111
+ data = json.loads(data)
112
+ return [int(msg['data']['qq']) for msg in data['message'] if msg['type'] == 'at']
113
+
114
+
115
+
116
+ def at_to_usrid(at):
117
+ return at[0] if at else None
118
+
119
+
120
+ async def rcon_command(rcon, cmd):
121
+ return await rcon_server(rcon, cmd.strip())
122
+
123
+ async def command_server(msg: str):
124
+ rcon = await read_server_cfg_rcon()
125
+ msg = await rcon_command(rcon, msg)
126
+ if not msg:
127
+ msg = '你可能发送了一个无用指令,或者换图导致服务器无响应'
128
+ elif msg.startswith('Unknown command'):
129
+ msg = '无效指令:' + msg.replace('Unknown command', '').strip()
130
+ return msg.strip().replace('\n', '')
131
+
132
+
133
+
134
+
135
+ async def queries_server(msg:list) -> str:
136
+ """查询ip返回信息"""
137
+ ip = msg[0]
138
+ port = msg[1]
139
+ msgs = ''
140
+ try:
141
+ msgs = await queries(ip,port)
142
+ msgs += await player_queries(ip,port)
143
+ except (struct.error,TimeoutError):
144
+ pass
145
+ # except Exception:
146
+ # msgs = '有无法识别的用户名'
147
+ # return msgs
148
+ return msgs
149
+
150
+ async def add_ip(group_id,host,port):
151
+ """先查找是否存在,如果不存在则创建"""
152
+ return await bind_group_ip(group_id,host,port)
153
+
154
+ async def del_ip(group_id,number):
155
+ """删除群ip"""
156
+ return await del_group_ip(group_id,number)
157
+
158
+ async def show_ip(group_id):
159
+ """先查找群ip,再根据群ip返回"""
160
+ data_list = await get_qqgroup_ip_msg(group_id)
161
+ logger.info(data_list)
162
+ if len(data_list) == 0 :
163
+ return "本群没有订阅"
164
+ msg = await qq_ip_queries_pic(data_list)
165
+ return msg
166
+
167
+ async def get_number_url(number):
168
+ 'connect AGNES.DIGITAL.LINE.PM:40001'
169
+ ip = await get_server_ip(number)
170
+ if not ip:
171
+ return '该序号不存在'
172
+ url = f'connect {ip}'
173
+ return url
174
+
175
+ async def workshop_msg(msg:str):
176
+ """url变成id,拼接post请求"""
177
+ if msg.startswith('https://steamcommunity.com/sharedfiles/filedetails/?id'):
178
+ try:
179
+ msg = msg.split('&')[0]
180
+ except:
181
+ pass
182
+ msg = msg.replace('https://steamcommunity.com/sharedfiles/filedetails/?id=','')
183
+ if msg.isdigit():
184
+ data:Union[dict,List[dict]] = await workshop_to_dict(msg)
185
+ return data
186
+ else:
187
+ return None
188
+
189
+ async def save_file(file:bytes,path_name):
190
+ """保存文件"""
191
+ with open(path_name,'w') as files:
192
+ files.write(file)
193
+
194
+ async def get_anne_server_ip(ip):
195
+ """输出查询ip和ping"""
196
+ host,port = split_maohao(ip)
197
+ data = await queries_server([host,port])
198
+ lines = data.splitlines()
199
+ msg = '\n'.join(lines[1:])
200
+ msg += '\nconnect ' + ip
201
+ return msg
202
+
203
+ async def upload_file(bot: Bot, event: MessageEvent, file_data: bytes, filename: str):
204
+ """上传临时文件"""
205
+ if systems == "win" or "other":
206
+ with tempfile.TemporaryDirectory() as temp_dir:
207
+ with open(Path(temp_dir) / filename, "wb") as f:
208
+ f.write(file_data)
209
+ if isinstance(event, GroupMessageEvent):
210
+ await bot.call_api(
211
+ "upload_group_file", group_id=event.group_id, file=f.name, name=filename
212
+ )
213
+ else:
214
+ await bot.call_api(
215
+ "upload_private_file", user_id=event.user_id, file=f.name, name=filename
216
+ )
217
+ os.remove(Path().joinpath(filename))
218
+ elif systems == "linux":
219
+ with tempfile.NamedTemporaryFile("wb+") as f:
220
+ f.write(file_data)
221
+ if isinstance(event, GroupMessageEvent):
222
+ await bot.call_api(
223
+ "upload_group_file", group_id=event.group_id, file=f.name, name=filename
224
+ )
225
+ else:
226
+ await bot.call_api(
227
+ "upload_private_file", user_id=event.user_id, file=f.name, name=filename
228
+ )
229
+
230
+
231
+ async def json_server_to_tag_dict(key:str,msg:str):
232
+ """
233
+ l4d2字典转tag的dict结果
234
+ - 1、先匹配腐竹
235
+ - 2、再匹配模式、没有参数则从直接匹配最上面的
236
+ - 3、匹配数字(几服),没有参数则从结果里随机返回一个
237
+ """
238
+ data_dict = {}
239
+ data_list = []
240
+ msg = msg.replace(' ','')
241
+ # 腐竹循环
242
+ for tag,value in ALL_HOST.items():
243
+ value:List[dict]
244
+ if tag == key:
245
+ data_dict.update({'server':tag})
246
+ if not msg:
247
+ # 腐竹
248
+ data_dict.update(random.choice(value))
249
+ elif msg.isdigit():
250
+ logger.info("腐竹 + 序号")
251
+ for server in value:
252
+ if msg == str(server['id']):
253
+ data_dict.update(server)
254
+ break
255
+ else:
256
+ logger.info("腐竹 + 模式 + 序号")
257
+ for server in value:
258
+ if msg.startswith(server['version']):
259
+ data_list.append(server)
260
+ msg_id = msg[len(server['version']):]
261
+ if msg_id == str(server['id']):
262
+ data_dict.update(server)
263
+ break
264
+ else:
265
+ # 腐竹 + 模式
266
+ data_dict.update(random.choice(data_list))
267
+
268
+ logger.info(data_dict)
269
+ return data_dict
270
+
271
+
272
+