nonebot-plugin-l4d2-server 0.3.4a2__py3-none-any.whl → 0.3.5__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 (32) hide show
  1. README.md +23 -3
  2. nonebot_plugin_l4d2_server/__init__.py +75 -20
  3. nonebot_plugin_l4d2_server/command.py +5 -4
  4. nonebot_plugin_l4d2_server/config.py +26 -11
  5. nonebot_plugin_l4d2_server/data/L4D2/image/template/anne.html +7 -4
  6. nonebot_plugin_l4d2_server/data/L4D2/image/template/back.png +0 -0
  7. nonebot_plugin_l4d2_server/data/L4D2/image/template/help - /321/205/320/231/320/277/321/206/320/254/320/274.html" +232 -0
  8. nonebot_plugin_l4d2_server/data/L4D2/image/template/help.html +1 -1
  9. nonebot_plugin_l4d2_server/data/L4D2/image/template/help_dack.html +231 -0
  10. nonebot_plugin_l4d2_server/data/L4D2/image/template/ip.html +1 -1
  11. nonebot_plugin_l4d2_server/data/L4D2/l4d2.json +27 -139
  12. nonebot_plugin_l4d2_server/l4d2_anne/__init__.py +40 -17
  13. nonebot_plugin_l4d2_server/l4d2_anne/analysis.py +40 -0
  14. nonebot_plugin_l4d2_server/l4d2_anne/anne_telecom.py +70 -70
  15. nonebot_plugin_l4d2_server/l4d2_anne/server.py +2 -1
  16. nonebot_plugin_l4d2_server/l4d2_anne/startand.py +18 -0
  17. nonebot_plugin_l4d2_server/l4d2_file/__init__.py +28 -2
  18. nonebot_plugin_l4d2_server/l4d2_image/__init__.py +8 -11
  19. nonebot_plugin_l4d2_server/l4d2_queries/__init__.py +4 -0
  20. nonebot_plugin_l4d2_server/l4d2_queries/maps.py +27 -0
  21. nonebot_plugin_l4d2_server/l4d2_queries/qqgroup.py +12 -7
  22. nonebot_plugin_l4d2_server/l4d2_server/web.py +221 -0
  23. nonebot_plugin_l4d2_server/l4d2_server/webUI.py +353 -0
  24. nonebot_plugin_l4d2_server/l4d2_server/workshop.py +24 -5
  25. nonebot_plugin_l4d2_server/seach.py +2 -1
  26. nonebot_plugin_l4d2_server/utils.py +5 -7
  27. {nonebot_plugin_l4d2_server-0.3.4a2.dist-info → nonebot_plugin_l4d2_server-0.3.5.dist-info}/METADATA +28 -4
  28. nonebot_plugin_l4d2_server-0.3.5.dist-info/RECORD +49 -0
  29. nonebot_plugin_l4d2_server/data/L4D2/image/template/back2.jpg +0 -0
  30. nonebot_plugin_l4d2_server-0.3.4a2.dist-info/RECORD +0 -43
  31. {nonebot_plugin_l4d2_server-0.3.4a2.dist-info → nonebot_plugin_l4d2_server-0.3.5.dist-info}/LICENSE +0 -0
  32. {nonebot_plugin_l4d2_server-0.3.4a2.dist-info → nonebot_plugin_l4d2_server-0.3.5.dist-info}/WHEEL +0 -0
@@ -0,0 +1,231 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ body {
5
+ margin: 0px;
6
+ zoom: 150%;
7
+ background-color: #0D1117;
8
+ }
9
+ .image {
10
+ display: flex;
11
+ flex-direction: column;
12
+ overflow: scroll;
13
+ width: max-content;
14
+ padding: 20px;
15
+ }
16
+ .head {
17
+ display: flex;
18
+ flex-direction: row;
19
+ align-items: center;
20
+ justify-content: space-between;
21
+ background-color: #161B22;
22
+ padding-left: 20px;
23
+ padding-right: 20px;
24
+ padding-top: 10px;
25
+ padding-bottom: 10px;
26
+ border: 2px solid;
27
+ border-radius: 50px;
28
+ border-color: #1a1a1a;
29
+ font-size: 16px;
30
+ margin-bottom: 20px;
31
+ }
32
+
33
+ .plugins {
34
+ display: grid;
35
+ grid-template-columns: auto auto auto;
36
+ row-gap: 20px;
37
+ column-gap: 20px;
38
+ margin-bottom: 20px;
39
+ }
40
+ .plugin {
41
+ display: flex;
42
+ padding: 5px;
43
+ border: 1px solid;
44
+ border-radius: 5px;
45
+ border-color: #161B22;
46
+ box-shadow: 0px 2px 6px 1px rgba(0, 0, 0, 0.2);
47
+ background-color: #1a1a1a;
48
+ }
49
+ .plugin_meta {
50
+ display: flex;
51
+ flex-direction: column;
52
+ padding: 5px;
53
+ width: 250px;
54
+ justify-content: space-between;
55
+ }
56
+ .plugin_name {
57
+ font-size: 20px;
58
+ }
59
+ .plugin_description {
60
+ font-size: 15px;
61
+ color: gray;
62
+ margin-top: 5px;
63
+ margin-bottom: 5px;
64
+ }
65
+ .plugin_meta_line1 {
66
+ display: flex;
67
+ flex-direction: row;
68
+ align-items: center;
69
+ justify-content: space-between;
70
+ }
71
+ .plugin_meta_line3 {
72
+ display: flex;
73
+ flex-direction: row;
74
+ align-items: center;
75
+ }
76
+ .package_name_label {
77
+ background-image: url(./fingerprint.svg);
78
+ width: 13px;
79
+ height: 13px;
80
+ margin-right: 8px;
81
+ }
82
+ .package_name {
83
+ font-size: 13px;
84
+ color: gray;
85
+ }
86
+ .switch {
87
+ position: relative;
88
+ display: inline-block;
89
+ width: 40px;
90
+ height: 24px;
91
+ }
92
+ .slider {
93
+ position: absolute;
94
+ cursor: pointer;
95
+ top: 0;
96
+ left: 0;
97
+ right: 0;
98
+ bottom: 0;
99
+ background-color: #ccc;
100
+ }
101
+ .slider:before {
102
+ position: absolute;
103
+ content: "";
104
+ height: 16px;
105
+ width: 16px;
106
+ left: 4px;
107
+ bottom: 4px;
108
+ background-color: white;
109
+ }
110
+ .switch input {
111
+ display: none;
112
+ }
113
+ .switch input:checked + .slider {
114
+ background-color: rgba(46, 160, 67);
115
+ }
116
+ .switch input:checked + .slider:before {
117
+ -webkit-transform: translateX(16px);
118
+ -ms-transform: translateX(16px);
119
+ transform: translateX(16px);
120
+ }
121
+ .slider.round {
122
+ border-radius: 24px;
123
+ }
124
+ .slider.round:before {
125
+ border-radius: 50%;
126
+ }
127
+ .checkbox {
128
+ visibility: hidden;
129
+ }
130
+ .slider.locked {
131
+ opacity: 0.5;
132
+ }
133
+ .switch input + span .lock {
134
+ width: 8px;
135
+ height: 7px;
136
+ background: #99a3ba;
137
+ position: absolute;
138
+ left: 8px;
139
+ bottom: 7px;
140
+ border-radius: 2px;
141
+ display: block;
142
+ z-index: 1;
143
+ transition: all 0.45s ease;
144
+ }
145
+ .switch input + span .lock:before {
146
+ content: "";
147
+ width: 2px;
148
+ height: 2px;
149
+ border-radius: 1px;
150
+ background: #fff;
151
+ position: absolute;
152
+ display: block;
153
+ left: 50%;
154
+ top: 50%;
155
+ margin: -1px 0 0 -1px;
156
+ }
157
+ .switch input + span .lock:after {
158
+ content: "";
159
+ border-top-left-radius: 4px;
160
+ border-top-right-radius: 4px;
161
+ border: 1px solid #99a3ba;
162
+ border-bottom: 0;
163
+ width: 4px;
164
+ height: 4px;
165
+ left: 1px;
166
+ bottom: 6px;
167
+ position: absolute;
168
+ z-index: 1;
169
+ -webkit-transform-origin: 0 100%;
170
+ transform-origin: 0 100%;
171
+ transition: all 0.45s ease;
172
+ }
173
+ .switch input:checked + span .lock {
174
+ background: #5628ee;
175
+ -webkit-transform: translateX(16px);
176
+ -ms-transform: translateX(16px);
177
+ transform: translateX(16px);
178
+ }
179
+ .lock {
180
+ visibility: hidden;
181
+ }
182
+ .lock.locked {
183
+ visibility: inherit;
184
+ }
185
+ </style>
186
+ </head>
187
+ <body>
188
+ <div class="image">
189
+ <div class="head">
190
+ <span><b><font color="Silver">已加载服务器</font></b></span>
191
+ <span><font color="Silver">发送“<b>服务器昵称/序号</b>”查看详情</font></span>
192
+ </div>
193
+ <div class="plugins">
194
+ {% for plugin in plugins %}
195
+ <div class="plugin">
196
+ <div class="plugin_meta">
197
+ <div class="plugin_meta_line1">
198
+ <div class="plugin_name"><font color="DeepSkyBlue">{{ plugin.number }}:{{ plugin.name }}</font></div>
199
+ <div class="plugin_status">
200
+ <label class="switch">
201
+ <input class="checkbox" type="checkbox" {% if plugin.enabled %} checked {% endif %} />
202
+ <span class="slider round {% if plugin.locked %} locked {% endif %}">
203
+ <span class="lock {% if plugin.locked %} locked {% endif %}"></span>
204
+ </span>
205
+ </label>
206
+ </div>
207
+ </div>
208
+ <div class="plugin_meta_line2">
209
+ <font color="LightSkyBlue">{{ plugin.map_ }}</font><br>
210
+ {% for Player in plugin.Players %}
211
+ <font color="LightGray">{{ Player }}</font><br>
212
+ {% endfor %}
213
+ </div>
214
+ <div class="plugin_meta_line3">
215
+ <div class="package_name_label"></div>
216
+ <div class="package_name"><font color="LightGray">{{ plugin.max_players }}</font></div>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ {% endfor %}
221
+ </div>
222
+ <div class="head">
223
+ <span><b><font color="Silver">©爱丽数码</font></b></span>
224
+ <span><font color="Silver">github*Umamusume-Agnes-Digital</font></span>
225
+ </div>
226
+ </div>
227
+ </body>
228
+ </html>
229
+
230
+
231
+ /*暗黑风格-ArcPav*/
@@ -33,7 +33,7 @@
33
33
  {% for Player in data[j].Players %}
34
34
  <font color="green">{{ Player }}</font><br>
35
35
  {% endfor %}
36
- <font color="yellow">{{ data[j].max_players }}</font>
36
+ <font color="yellow">{{ data[j].max_players }}{{data[j].ping}}</font>
37
37
  </td>
38
38
  {% endif %}
39
39
  {% endfor %}
@@ -1,136 +1,4 @@
1
1
  {
2
- "云": [
3
- {
4
- "id": 1,
5
- "version": "anne",
6
- "ip": "124.221.215.53:2332"
7
- },
8
- {
9
- "id": 2,
10
- "version": "anne",
11
- "ip": "43.143.158.196:2331"
12
- },
13
- {
14
- "id": 3,
15
- "version": "anne",
16
- "ip": "106.55.6.211:2332"
17
- },
18
- {
19
- "id": 4,
20
- "version": "anne",
21
- "ip": "106.55.6.211:2333"
22
- },
23
- {
24
- "id": 5,
25
- "version": "anne",
26
- "ip": "106.13.221.250:2330"
27
- },
28
- {
29
- "id": 6,
30
- "version": "anne",
31
- "ip": "106.13.221.250:2334"
32
- },
33
- {
34
- "id": 7,
35
- "version": "anne",
36
- "ip": "119.91.25.89:2331"
37
- },
38
- {
39
- "id": 8,
40
- "version": "anne",
41
- "ip": "119.91.25.89:2332"
42
- },
43
- {
44
- "id": 9,
45
- "version": "anne",
46
- "ip": "119.91.25.89:2333"
47
- },
48
- {
49
- "id": 10,
50
- "version": "anne",
51
- "ip": "119.91.25.89:2334"
52
- },
53
- {
54
- "id": 11,
55
- "version": "anne",
56
- "ip": "82.157.142.166:2331"
57
- },
58
- {
59
- "id": 12,
60
- "version": "anne",
61
- "ip": "82.157.142.166:2332"
62
- },
63
- {
64
- "id": 13,
65
- "version": "anne",
66
- "ip": "82.157.142.166:2333"
67
- },
68
- {
69
- "id": 14,
70
- "version": "anne",
71
- "ip": "82.157.142.166:2334"
72
- },
73
- {
74
- "id": 15,
75
- "version": "anne",
76
- "ip": "47.98.100.49:2330"
77
- },
78
- {
79
- "id": 16,
80
- "version": "anne",
81
- "ip": "47.98.100.49:2334"
82
- },
83
- {
84
- "id": 17,
85
- "version": "anne",
86
- "ip": "43.143.158.196:2332"
87
- },
88
- {
89
- "id": 18,
90
- "version": "anne",
91
- "ip": "g3.kok.wang:40024"
92
- },
93
- {
94
- "id": 19,
95
- "version": "anne",
96
- "ip": "g3.kok.wang:40025"
97
- },
98
- {
99
- "id": 20,
100
- "version": "anne",
101
- "ip": "g3.kok.wang:40026"
102
- },
103
- {
104
- "id": 21,
105
- "version": "anne",
106
- "ip": "g3.kok.wang:40027"
107
- },
108
- {
109
- "id": 22,
110
- "version": "anne",
111
- "ip": "121.62.61.229:2331"
112
- },
113
- {
114
- "id": 23,
115
- "version": "anne",
116
- "ip": "121.62.61.229:2332"
117
- },
118
- {
119
- "id": 24,
120
- "version": "anne",
121
- "ip": "124.221.10.99:2334"
122
- },
123
- {
124
- "id": 25,
125
- "version": "anne",
126
- "ip": "43.248.188.11:27022"
127
- },
128
- {
129
- "id": 26,
130
- "version": "anne",
131
- "ip": "43.248.188.11:27023"
132
- }
133
- ],
134
2
  "呆呆": [
135
3
  {
136
4
  "id": 1,
@@ -190,39 +58,59 @@
190
58
  {
191
59
  "id": 12,
192
60
  "version": "anne",
193
- "ip": "43.248.188.11:27022"
61
+ "ip": "103.219.39.254:20676"
194
62
  },
195
63
  {
196
64
  "id": 13,
197
65
  "version": "对抗",
198
- "ip": "43.248.188.11:36688"
66
+ "ip": "103.219.39.254:20518"
199
67
  },
200
68
  {
201
69
  "id": 14,
202
70
  "version": "对抗",
203
- "ip": "43.248.188.11:37688"
71
+ "ip": "103.219.39.254:28349"
204
72
  },
205
73
  {
206
74
  "id": 15,
207
75
  "version": "anne",
208
- "ip": "43.248.188.11:27023"
76
+ "ip": "103.219.39.254:23649"
209
77
  }
210
78
  ],
211
79
  "橘":[
212
80
  {
213
- "id":1,
81
+ "id": 1,
214
82
  "version": "战役",
215
83
  "ip":"202.189.7.139:12203"
216
84
  },
217
85
  {
218
- "id":2,
86
+ "id": 2,
219
87
  "version": "多特",
220
88
  "ip":"202.189.7.139:12202"
221
89
  },
222
90
  {
223
- "id":3,
91
+ "id": 3,
224
92
  "version": "多特",
225
93
  "ip":"202.189.7.139:12302"
94
+ },
95
+ {
96
+ "id": 4,
97
+ "version": "anne",
98
+ "ip": "g3.kok.wang:40024"
99
+ },
100
+ {
101
+ "id": 5,
102
+ "version": "anne",
103
+ "ip": "g3.kok.wang:40025"
104
+ },
105
+ {
106
+ "id": 6,
107
+ "version": "anne",
108
+ "ip": "g3.kok.wang:40026"
109
+ },
110
+ {
111
+ "id": 7,
112
+ "version": "anne",
113
+ "ip": "g3.kok.wang:40027"
226
114
  }
227
115
  ]
228
116
  }
@@ -1,15 +1,17 @@
1
1
 
2
2
  from nonebot.log import logger
3
3
 
4
+ import pandas as pd
4
5
  from typing import List
5
6
 
7
+ from .analysis import df_to_guoguanlv
6
8
  from ..config import l4_steamid
7
9
  from ..seach import *
8
10
  from ..l4d2_data.players import L4D2Player
9
11
  from ..l4d2_image import out_png
10
- from .anne_telecom import ANNE_API
12
+ # from .anne_telecom import ANNE_API
11
13
  from ..l4d2_queries.ohter import ALL_HOST
12
-
14
+
13
15
 
14
16
  s = L4D2Player()
15
17
 
@@ -120,6 +122,7 @@ def del_player(id:str):
120
122
  async def id_to_mes(name:str):
121
123
  """根据name从数据库,返回steamid、或者空白"""
122
124
  data_tuple = await s.search_data(None,name,None)
125
+ print(data_tuple)
123
126
  if data_tuple:
124
127
  steamid = data_tuple[2]
125
128
  return steamid
@@ -133,7 +136,7 @@ def anne_rank_dict(name:str):
133
136
  headers = {
134
137
  'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
135
138
  }
136
- data = httpx.get(url,headers=headers,timeout=30).content.decode('utf-8')
139
+ data = httpx.get(url,headers=headers,timeout=5).content.decode('utf-8')
137
140
  data = BeautifulSoup(data, 'html.parser')
138
141
  detail = data.find_all('table')
139
142
  n = 0
@@ -191,6 +194,7 @@ async def anne_messgae(name:str,usr_id:str):
191
194
  name = steamid
192
195
  # steamid
193
196
  msg = anne_rank_dict(name)[0]
197
+ msg.update(await df_to_guoguanlv(await anne_map_msg(name)))
194
198
  logger.info('使用图片')
195
199
  msg = await out_png(usr_id,msg)
196
200
  return msg
@@ -206,24 +210,43 @@ async def anne_messgae(name:str,usr_id:str):
206
210
  if data_tuple== None:
207
211
  return f"没有绑定信息...请使用【求生绑定 xxx】\n"
208
212
  # 只有名字,先查询数据在判断
209
- elif not data_tuple[2]:
213
+ elif data_tuple[2]:
214
+ name = data_tuple[2]
215
+ elif data_tuple[1]:
210
216
  name = await id_to_mes(data_tuple[1])
211
217
  logger.info(name)
212
218
  if not name:
213
- a:str = '未找到该玩家...\n'
214
- return a
215
- msg = anne_html(name)
216
- logger.info('有' + str(len(msg)) + '个信息')
217
- if str(len(msg)) !=1:
218
- logger.info('使用文字')
219
- msg = anne_html_msg(msg)
220
- return msg
221
- name = msg[0]['steamid']
222
- else:
223
- name = data_tuple[2]
219
+ message = await anne_html(data_tuple[1])
220
+ usr_id = "1145149191810"
221
+ if len(message) == 0:
222
+ return '没有叫这个名字的...\n'
223
+ if len(message) > 1:
224
+ return anne_html_msg(message)
225
+ name = message[0]['steamid']
224
226
  # name是steamid
225
- msg = anne_rank_dict(name)
227
+ msg = anne_rank_dict(name)[0]
228
+ msg.update(await df_to_guoguanlv(await anne_map_msg(name)))
226
229
  logger.info('使用图片')
227
230
  msg = msg[0]
228
231
  msg = await out_png(usr_id,msg)
229
- return msg
232
+ return msg
233
+
234
+ async def anne_map_msg(steamid:str):
235
+ """steamid->地图信息"""
236
+ url = f"https://sb.trygek.com/l4d_stats/ranking/timedmaps.php?steamid={steamid}"
237
+ headers = {
238
+ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'
239
+ }
240
+ data = httpx.get(url,headers=headers,timeout=5).content.decode('utf-8')
241
+ soup = BeautifulSoup(data, 'html.parser')
242
+ data_list = []
243
+ cards = soup.select('div.card.rounded-0')
244
+ for card in cards:
245
+ tbodies = card.select('tbody')
246
+ for tbody in tbodies:
247
+ rows = [td.text.strip() for td in tbody.find_all('td')]
248
+ for i in range(0, len(rows), 9):
249
+ row = rows[i:i+9]
250
+ data_list.append(row)
251
+ df = pd.DataFrame(data_list, columns=['游戏模式', '地图', '难度', '完成时间', '特感数量', '刷新间隔', 'B数使用', '刷特模式', 'Anne版本'])
252
+ return df
@@ -0,0 +1,40 @@
1
+ from .startand import SAVE_MAP,NUMBER_MAP
2
+ import pandas as pd
3
+
4
+ async def df_to_guoguanlv(df:pd.DataFrame):
5
+ """分析救援关过图率"""
6
+ data = df
7
+ all_map = len(data['地图'])
8
+ resen = 0
9
+ last_maps = {}
10
+ for m in SAVE_MAP:
11
+ prefix = m.split('m')[0]
12
+ if prefix in last_maps:
13
+ last_maps[prefix] = max(last_maps[prefix], m)
14
+ else:
15
+ last_maps[prefix] = m
16
+
17
+ map_counts = {}
18
+
19
+ n = 0
20
+ for key in last_maps:
21
+ count = len(data[data['地图'].str.startswith(key)])
22
+ if count == 0:
23
+ continue
24
+ last_map = last_maps[key]
25
+ map_count = len(data[data['地图'] == last_map])
26
+ map_counts[key] = map_count*NUMBER_MAP[n] / count
27
+ quan = count/all_map
28
+ resen += quan * map_counts[key]
29
+ n += 1
30
+
31
+ # result = []
32
+ # for i in range(1, 15):
33
+ # key = 'c{}'.format(i)
34
+ # if key in map_counts:
35
+ # result.append('{}:{}%'.format(key, round(map_counts[key] * 100)))
36
+
37
+ # print(result)
38
+ # result = '救援图过关率: {:.2%}'.format(resen)
39
+ result = {"救援关":str('{:.2%}'.format(resen))}
40
+ return result