nonebot-plugin-l4d2-server 0.5.1__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.
- LICENSE +674 -674
- README.md +364 -359
- nonebot_plugin_l4d2_server/__init__.py +1 -1
- nonebot_plugin_l4d2_server/chrome.py +44 -44
- nonebot_plugin_l4d2_server/command.py +232 -232
- nonebot_plugin_l4d2_server/config.py +210 -210
- nonebot_plugin_l4d2_server/data/L4D2/image/template/anne.html +60 -60
- nonebot_plugin_l4d2_server/data/L4D2/image/template/fingerprint.svg +15 -15
- nonebot_plugin_l4d2_server/data/L4D2/image/template/help.html +233 -233
- nonebot_plugin_l4d2_server/data/L4D2/image/template/help_dack.html +231 -231
- nonebot_plugin_l4d2_server/data/L4D2/image/template/ip.html +48 -48
- nonebot_plugin_l4d2_server/data/L4D2/image/template/l.svg +9 -9
- nonebot_plugin_l4d2_server/l4d2_anne/__init__.py +251 -251
- nonebot_plugin_l4d2_server/l4d2_anne/analysis.py +51 -51
- nonebot_plugin_l4d2_server/l4d2_anne/anne_telecom.py +75 -75
- nonebot_plugin_l4d2_server/l4d2_anne/server.py +65 -65
- nonebot_plugin_l4d2_server/l4d2_anne/startand.py +17 -17
- nonebot_plugin_l4d2_server/l4d2_data/__init__.py +91 -91
- nonebot_plugin_l4d2_server/l4d2_data/config.py +17 -17
- nonebot_plugin_l4d2_server/l4d2_data/players.py +87 -87
- nonebot_plugin_l4d2_server/l4d2_data/serverip.py +32 -32
- nonebot_plugin_l4d2_server/l4d2_file/__init__.py +122 -122
- nonebot_plugin_l4d2_server/l4d2_file/ayromote.py +56 -56
- nonebot_plugin_l4d2_server/l4d2_file/remote.py +63 -63
- nonebot_plugin_l4d2_server/l4d2_image/__init__.py +103 -103
- nonebot_plugin_l4d2_server/l4d2_image/download.py +101 -101
- nonebot_plugin_l4d2_server/l4d2_image/htmlimg.py +32 -32
- nonebot_plugin_l4d2_server/l4d2_image/send_image_tool.py +32 -32
- nonebot_plugin_l4d2_server/l4d2_image/steam.py +83 -83
- nonebot_plugin_l4d2_server/l4d2_image/vtfs.py +40 -40
- nonebot_plugin_l4d2_server/l4d2_queries/__init__.py +114 -114
- nonebot_plugin_l4d2_server/l4d2_queries/api.py +43 -43
- nonebot_plugin_l4d2_server/l4d2_queries/ohter.py +35 -35
- nonebot_plugin_l4d2_server/l4d2_queries/qqgroup.py +288 -288
- nonebot_plugin_l4d2_server/l4d2_server/__init__.py +61 -61
- nonebot_plugin_l4d2_server/l4d2_server/rcon.py +28 -28
- nonebot_plugin_l4d2_server/l4d2_server/workshop.py +50 -50
- nonebot_plugin_l4d2_server/l4d2_web/web.py +234 -252
- nonebot_plugin_l4d2_server/l4d2_web/webUI.py +241 -245
- nonebot_plugin_l4d2_server/message.py +58 -58
- nonebot_plugin_l4d2_server/seach.py +33 -33
- nonebot_plugin_l4d2_server/txt_to_img.py +64 -64
- nonebot_plugin_l4d2_server/utils.py +272 -272
- {nonebot_plugin_l4d2_server-0.5.1.dist-info → nonebot_plugin_l4d2_server-0.5.2.dist-info}/LICENSE +674 -674
- {nonebot_plugin_l4d2_server-0.5.1.dist-info → nonebot_plugin_l4d2_server-0.5.2.dist-info}/METADATA +6 -1
- nonebot_plugin_l4d2_server-0.5.2.dist-info/RECORD +54 -0
- {nonebot_plugin_l4d2_server-0.5.1.dist-info → nonebot_plugin_l4d2_server-0.5.2.dist-info}/WHEEL +1 -1
- nonebot_plugin_l4d2_server-0.5.1.dist-info/RECORD +0 -54
@@ -1,76 +1,76 @@
|
|
1
|
-
# from ..l4d2_image.steam import url_to_byte
|
2
|
-
# from bs4 import BeautifulSoup
|
3
|
-
# from typing import List
|
4
|
-
|
5
|
-
# 暂时废弃
|
6
|
-
# class ANNE_API:
|
7
|
-
|
8
|
-
# async def __init__(
|
9
|
-
# self,
|
10
|
-
# STEAMID:str,
|
11
|
-
# tag:str
|
12
|
-
# ):
|
13
|
-
# self.STEAMID = STEAMID
|
14
|
-
# if tag == '中':
|
15
|
-
# msg1 = await self.anne_msg()
|
16
|
-
# elif tag == '长':
|
17
|
-
# msg1 = await self.anne_msg()
|
18
|
-
# msg1.update(await self.anne_map())
|
19
|
-
|
20
|
-
|
21
|
-
# async def anne_msg(self):
|
22
|
-
# """个人资料表"""
|
23
|
-
# data_bytes = await url_to_byte('https://sb.trygek.com/l4d_stats/ranking/player.php?steamid={self.STEAMID}')
|
24
|
-
# data_bs = BeautifulSoup(data_bytes, 'html.parser')
|
25
|
-
# data_fom = data_bs.find_all('table')
|
26
|
-
# n = 0
|
27
|
-
# data_dict = {}
|
28
|
-
# while n < 2:
|
29
|
-
# data_list:List[dict] = []
|
30
|
-
# detail2 = data_fom[n]
|
31
|
-
# tr = detail2.find_all('tr')
|
32
|
-
# for i in tr:
|
33
|
-
# title = i.find('td', {'class': 'w-50'})
|
34
|
-
# value = title.find_next_sibling('td')
|
35
|
-
# new_dict = {title.text:value.text}
|
36
|
-
# data_dict.update(new_dict)
|
37
|
-
# data_list.append(data_dict)
|
38
|
-
# n += 1
|
39
|
-
# # 获取头像
|
40
|
-
# element:str = data_fom.find_all(attrs={"style": "cursor:pointer"})[0].get("onclick")
|
41
|
-
# player_url = element.split("'")[1]
|
42
|
-
# data_list[0].update({"个人资料":player_url})
|
43
|
-
# # 获取一言
|
44
|
-
# message = data_fom.select("html body div.content.text-center.text-md-left div.container.text-left div.col-md-12.h-100 div.card-body.worldmap.d-flex.flex-column.justify-content-center.text-center span")
|
45
|
-
# msg_list = []
|
46
|
-
# for i in message:
|
47
|
-
# msg_list.append(i.text)
|
48
|
-
# data_list[0].update({"一言":msg_list})
|
49
|
-
# return data_list
|
50
|
-
|
51
|
-
# async def anne_map(self):
|
52
|
-
# """个人地图表"""
|
53
|
-
# data_dict = {}
|
54
|
-
# data_bytes = await url_to_byte('https://sb.trygek.com/l4d_stats/ranking/timedmaps.php?steamid={self.STEAMID}')
|
55
|
-
# data_bs = BeautifulSoup(data_bytes, 'html.parser')
|
56
|
-
# tbody = data_bs.select('tbody')
|
57
|
-
# for tr in tbody:
|
58
|
-
# tds = tr.select('td')
|
59
|
-
# n = 0
|
60
|
-
# for td in tds:
|
61
|
-
# n += 1
|
62
|
-
# title:str = td['data-title'][:-1]
|
63
|
-
# data_text = td.text
|
64
|
-
# if title == '特感数量':
|
65
|
-
# special_amount = data_text
|
66
|
-
# elif title == '刷新间隔':
|
67
|
-
# refresh_interval = data_text
|
68
|
-
# else:
|
69
|
-
# if title in data_dict:
|
70
|
-
# data_dict[title].append(data_text)
|
71
|
-
# else:
|
72
|
-
# data_dict[title] = [data_text]
|
73
|
-
# if special_amount and refresh_interval:
|
74
|
-
# data_dict['刷特时间'] = special_amount + refresh_interval
|
75
|
-
|
1
|
+
# from ..l4d2_image.steam import url_to_byte
|
2
|
+
# from bs4 import BeautifulSoup
|
3
|
+
# from typing import List
|
4
|
+
|
5
|
+
# 暂时废弃
|
6
|
+
# class ANNE_API:
|
7
|
+
|
8
|
+
# async def __init__(
|
9
|
+
# self,
|
10
|
+
# STEAMID:str,
|
11
|
+
# tag:str
|
12
|
+
# ):
|
13
|
+
# self.STEAMID = STEAMID
|
14
|
+
# if tag == '中':
|
15
|
+
# msg1 = await self.anne_msg()
|
16
|
+
# elif tag == '长':
|
17
|
+
# msg1 = await self.anne_msg()
|
18
|
+
# msg1.update(await self.anne_map())
|
19
|
+
|
20
|
+
|
21
|
+
# async def anne_msg(self):
|
22
|
+
# """个人资料表"""
|
23
|
+
# data_bytes = await url_to_byte('https://sb.trygek.com/l4d_stats/ranking/player.php?steamid={self.STEAMID}')
|
24
|
+
# data_bs = BeautifulSoup(data_bytes, 'html.parser')
|
25
|
+
# data_fom = data_bs.find_all('table')
|
26
|
+
# n = 0
|
27
|
+
# data_dict = {}
|
28
|
+
# while n < 2:
|
29
|
+
# data_list:List[dict] = []
|
30
|
+
# detail2 = data_fom[n]
|
31
|
+
# tr = detail2.find_all('tr')
|
32
|
+
# for i in tr:
|
33
|
+
# title = i.find('td', {'class': 'w-50'})
|
34
|
+
# value = title.find_next_sibling('td')
|
35
|
+
# new_dict = {title.text:value.text}
|
36
|
+
# data_dict.update(new_dict)
|
37
|
+
# data_list.append(data_dict)
|
38
|
+
# n += 1
|
39
|
+
# # 获取头像
|
40
|
+
# element:str = data_fom.find_all(attrs={"style": "cursor:pointer"})[0].get("onclick")
|
41
|
+
# player_url = element.split("'")[1]
|
42
|
+
# data_list[0].update({"个人资料":player_url})
|
43
|
+
# # 获取一言
|
44
|
+
# message = data_fom.select("html body div.content.text-center.text-md-left div.container.text-left div.col-md-12.h-100 div.card-body.worldmap.d-flex.flex-column.justify-content-center.text-center span")
|
45
|
+
# msg_list = []
|
46
|
+
# for i in message:
|
47
|
+
# msg_list.append(i.text)
|
48
|
+
# data_list[0].update({"一言":msg_list})
|
49
|
+
# return data_list
|
50
|
+
|
51
|
+
# async def anne_map(self):
|
52
|
+
# """个人地图表"""
|
53
|
+
# data_dict = {}
|
54
|
+
# data_bytes = await url_to_byte('https://sb.trygek.com/l4d_stats/ranking/timedmaps.php?steamid={self.STEAMID}')
|
55
|
+
# data_bs = BeautifulSoup(data_bytes, 'html.parser')
|
56
|
+
# tbody = data_bs.select('tbody')
|
57
|
+
# for tr in tbody:
|
58
|
+
# tds = tr.select('td')
|
59
|
+
# n = 0
|
60
|
+
# for td in tds:
|
61
|
+
# n += 1
|
62
|
+
# title:str = td['data-title'][:-1]
|
63
|
+
# data_text = td.text
|
64
|
+
# if title == '特感数量':
|
65
|
+
# special_amount = data_text
|
66
|
+
# elif title == '刷新间隔':
|
67
|
+
# refresh_interval = data_text
|
68
|
+
# else:
|
69
|
+
# if title in data_dict:
|
70
|
+
# data_dict[title].append(data_text)
|
71
|
+
# else:
|
72
|
+
# data_dict[title] = [data_text]
|
73
|
+
# if special_amount and refresh_interval:
|
74
|
+
# data_dict['刷特时间'] = special_amount + refresh_interval
|
75
|
+
|
76
76
|
# return data_dict
|
@@ -1,65 +1,65 @@
|
|
1
|
-
import httpx
|
2
|
-
from bs4 import BeautifulSoup
|
3
|
-
import json
|
4
|
-
from pathlib import Path
|
5
|
-
from ..config import TEXT_PATH,anne_url,ANNE_IP,gamemode_list
|
6
|
-
from ..l4d2_queries.ohter import ALL_HOST
|
7
|
-
|
8
|
-
# 储存anne服务器ip
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
async def updata_anne_server():
|
14
|
-
"""更新anne服务器列表"""
|
15
|
-
data = httpx.get(anne_url).content
|
16
|
-
soup = BeautifulSoup(data, 'html.parser')
|
17
|
-
tbody = soup.find('tbody')
|
18
|
-
n = 0
|
19
|
-
ip_list=[]
|
20
|
-
while n < 50:
|
21
|
-
n += 1
|
22
|
-
tr = tbody.find(id = f'server_{n}')
|
23
|
-
if tr:
|
24
|
-
td = tr.select_one("td:nth-of-type(5)").get_text()
|
25
|
-
else:
|
26
|
-
continue
|
27
|
-
if td:
|
28
|
-
ip_list.append(td)
|
29
|
-
if not ip_list:
|
30
|
-
return None
|
31
|
-
ip_dict = {}
|
32
|
-
n = 0
|
33
|
-
for i in ip_list:
|
34
|
-
n += 1
|
35
|
-
ip_dict.update({f'云{n}':ip_list[n-1]})
|
36
|
-
ANNE_IP.update(ip_dict)
|
37
|
-
with open(Path(TEXT_PATH.parent/'server.json'),'w',encoding='utf-8') as f:
|
38
|
-
json.dump(ANNE_IP, f, indent=4, ensure_ascii=False)
|
39
|
-
return ANNE_IP
|
40
|
-
|
41
|
-
async def read_anne_ip():
|
42
|
-
"""获取缓存ip"""
|
43
|
-
with open(TEXT_PATH.parent/'server.json','r','utf-8') as f:
|
44
|
-
data = json.load(f)
|
45
|
-
return data
|
46
|
-
|
47
|
-
async def get_anne_ip(text: str) -> str:
|
48
|
-
"""从字典里返还消息, 抄(借鉴)的zhenxun-bot"""
|
49
|
-
keys = ANNE_IP.keys()
|
50
|
-
for key in keys:
|
51
|
-
if text == key:
|
52
|
-
return ANNE_IP[key]
|
53
|
-
|
54
|
-
def server_key():
|
55
|
-
"""响应的服务器开头"""
|
56
|
-
a = set()
|
57
|
-
try:
|
58
|
-
for tag1,value in ALL_HOST.items():
|
59
|
-
a.add(tag1)
|
60
|
-
a.update(gamemode_list)
|
61
|
-
except AttributeError:
|
62
|
-
a.add('希腊那我从来没有想过这个事情')
|
63
|
-
return a
|
64
|
-
|
65
|
-
|
1
|
+
import httpx
|
2
|
+
from bs4 import BeautifulSoup
|
3
|
+
import json
|
4
|
+
from pathlib import Path
|
5
|
+
from ..config import TEXT_PATH,anne_url,ANNE_IP,gamemode_list
|
6
|
+
from ..l4d2_queries.ohter import ALL_HOST
|
7
|
+
|
8
|
+
# 储存anne服务器ip
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
async def updata_anne_server():
|
14
|
+
"""更新anne服务器列表"""
|
15
|
+
data = httpx.get(anne_url).content
|
16
|
+
soup = BeautifulSoup(data, 'html.parser')
|
17
|
+
tbody = soup.find('tbody')
|
18
|
+
n = 0
|
19
|
+
ip_list=[]
|
20
|
+
while n < 50:
|
21
|
+
n += 1
|
22
|
+
tr = tbody.find(id = f'server_{n}')
|
23
|
+
if tr:
|
24
|
+
td = tr.select_one("td:nth-of-type(5)").get_text()
|
25
|
+
else:
|
26
|
+
continue
|
27
|
+
if td:
|
28
|
+
ip_list.append(td)
|
29
|
+
if not ip_list:
|
30
|
+
return None
|
31
|
+
ip_dict = {}
|
32
|
+
n = 0
|
33
|
+
for i in ip_list:
|
34
|
+
n += 1
|
35
|
+
ip_dict.update({f'云{n}':ip_list[n-1]})
|
36
|
+
ANNE_IP.update(ip_dict)
|
37
|
+
with open(Path(TEXT_PATH.parent/'server.json'),'w',encoding='utf-8') as f:
|
38
|
+
json.dump(ANNE_IP, f, indent=4, ensure_ascii=False)
|
39
|
+
return ANNE_IP
|
40
|
+
|
41
|
+
async def read_anne_ip():
|
42
|
+
"""获取缓存ip"""
|
43
|
+
with open(TEXT_PATH.parent/'server.json','r','utf-8') as f:
|
44
|
+
data = json.load(f)
|
45
|
+
return data
|
46
|
+
|
47
|
+
async def get_anne_ip(text: str) -> str:
|
48
|
+
"""从字典里返还消息, 抄(借鉴)的zhenxun-bot"""
|
49
|
+
keys = ANNE_IP.keys()
|
50
|
+
for key in keys:
|
51
|
+
if text == key:
|
52
|
+
return ANNE_IP[key]
|
53
|
+
|
54
|
+
def server_key():
|
55
|
+
"""响应的服务器开头"""
|
56
|
+
a = set()
|
57
|
+
try:
|
58
|
+
for tag1,value in ALL_HOST.items():
|
59
|
+
a.add(tag1)
|
60
|
+
a.update(gamemode_list)
|
61
|
+
except AttributeError:
|
62
|
+
a.add('希腊那我从来没有想过这个事情')
|
63
|
+
return a
|
64
|
+
|
65
|
+
|
@@ -1,18 +1,18 @@
|
|
1
|
-
|
2
|
-
NUMBER_MAP = [4,5,4,5,5,3,3,5,2,5,5,5,4,2]
|
3
|
-
SAVE_MAP = [
|
4
|
-
"c1m4_atrium",
|
5
|
-
"c2m5_concert",
|
6
|
-
"c3m4_plantation",
|
7
|
-
"c4m5_milltown_escape",
|
8
|
-
"c5m5_bridge",
|
9
|
-
"c6m3_port",
|
10
|
-
"c7m3_port",
|
11
|
-
"c8m5_rooftop",
|
12
|
-
"c9m2_lots",
|
13
|
-
"c10m5_houseboat",
|
14
|
-
"c11m5_runway",
|
15
|
-
"c12m5_cornfield",
|
16
|
-
"c13m4_cutthroatcreek",
|
17
|
-
"c14m2_lighthouse"
|
1
|
+
|
2
|
+
NUMBER_MAP = [4,5,4,5,5,3,3,5,2,5,5,5,4,2]
|
3
|
+
SAVE_MAP = [
|
4
|
+
"c1m4_atrium",
|
5
|
+
"c2m5_concert",
|
6
|
+
"c3m4_plantation",
|
7
|
+
"c4m5_milltown_escape",
|
8
|
+
"c5m5_bridge",
|
9
|
+
"c6m3_port",
|
10
|
+
"c7m3_port",
|
11
|
+
"c8m5_rooftop",
|
12
|
+
"c9m2_lots",
|
13
|
+
"c10m5_houseboat",
|
14
|
+
"c11m5_runway",
|
15
|
+
"c12m5_cornfield",
|
16
|
+
"c13m4_cutthroatcreek",
|
17
|
+
"c14m2_lighthouse"
|
18
18
|
]
|
@@ -1,92 +1,92 @@
|
|
1
|
-
from ..config import (
|
2
|
-
DATASQLITE,
|
3
|
-
table_data,
|
4
|
-
L4d2_players_tag,
|
5
|
-
L4d2_server_tag,
|
6
|
-
L4d2_INTEGER,
|
7
|
-
L4d2_TEXT,
|
8
|
-
L4d2_BOOLEAN,
|
9
|
-
tables_columns
|
10
|
-
)
|
11
|
-
import sqlite3
|
12
|
-
from nonebot.log import logger
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
class L4D2DataSqlite:
|
18
|
-
"""连接数据库和断开数据库,以及一些检查函数"""
|
19
|
-
def __init__(self):
|
20
|
-
"""连接数据库"""
|
21
|
-
self.datasqlite_path = DATASQLITE
|
22
|
-
self.datasqlite_path.mkdir(parents=True, exist_ok=True)
|
23
|
-
self.conn = sqlite3.connect(self.datasqlite_path / 'L4D2.db')
|
24
|
-
self._check_tables_exist()
|
25
|
-
self._check_data_existence()
|
26
|
-
self._check_data_validity()
|
27
|
-
logger.info("已连接求生数据库")
|
28
|
-
|
29
|
-
def _base_conn(self):
|
30
|
-
return self.conn
|
31
|
-
|
32
|
-
def _check_tables_exist(self) -> None:
|
33
|
-
"""
|
34
|
-
检查表是否存在
|
35
|
-
"""
|
36
|
-
c = self.conn.cursor()
|
37
|
-
for table in table_data:
|
38
|
-
c.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'")
|
39
|
-
if c.fetchone() is None:
|
40
|
-
if table == "L4d2_players":
|
41
|
-
c.execute(f"CREATE TABLE {table} (qq INTEGER PRIMARY KEY)")
|
42
|
-
elif table == "L4D2_server":
|
43
|
-
c.execute(f"CREATE TABLE {table} (number INTEGER PRIMARY KEY)")
|
44
|
-
self.conn.commit()
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def _check_data_existence(self) -> None:
|
49
|
-
"""
|
50
|
-
检查表头是否存在,如果不存在则新建并填充默认值
|
51
|
-
"""
|
52
|
-
c = self.conn.cursor()
|
53
|
-
for table, tag in tables_columns.items():
|
54
|
-
for column in tag:
|
55
|
-
c.execute(f"PRAGMA table_info({table})")
|
56
|
-
if not any(col[1] == column for col in c.fetchall()):
|
57
|
-
if column in L4d2_BOOLEAN:
|
58
|
-
c.execute(f'ALTER TABLE {table} ADD COLUMN {column} BOOLEAN DEFAULT 0')
|
59
|
-
elif column in L4d2_INTEGER:
|
60
|
-
c.execute(f'ALTER TABLE {table} ADD COLUMN {column} INTEGER DEFAULT NULL')
|
61
|
-
else:
|
62
|
-
c.execute(f'ALTER TABLE {table} ADD COLUMN {column} TEXT DEFAULT NULL')
|
63
|
-
self.conn.commit()
|
64
|
-
|
65
|
-
|
66
|
-
def _check_data_validity(self) -> None:
|
67
|
-
"""
|
68
|
-
检查数据库数据的合法性
|
69
|
-
错误数据默认填充NULL或者False
|
70
|
-
"""
|
71
|
-
c = self.conn.cursor()
|
72
|
-
for table in table_data:
|
73
|
-
if table == "L4d2_players":
|
74
|
-
columns = L4d2_players_tag
|
75
|
-
elif table == "L4D2_server":
|
76
|
-
columns = L4d2_server_tag
|
77
|
-
for column in columns:
|
78
|
-
if column in L4d2_INTEGER:
|
79
|
-
c.execute(f"UPDATE {table} SET {column} = NULL WHERE typeof({column}) != 'integer'")
|
80
|
-
elif column in L4d2_TEXT:
|
81
|
-
c.execute(f"UPDATE {table} SET {column} = NULL WHERE typeof({column}) != 'text'")
|
82
|
-
elif column in L4d2_BOOLEAN:
|
83
|
-
c.execute(f"UPDATE {table} SET {column} = 'False' WHERE typeof({column}) != 'boolean'")
|
84
|
-
self.conn.commit()
|
85
|
-
|
86
|
-
def _close(self):
|
87
|
-
"""断开连接到数据库"""
|
88
|
-
self.conn.close()
|
89
|
-
logger.info("已断开求生数据库")
|
90
|
-
|
91
|
-
|
1
|
+
from ..config import (
|
2
|
+
DATASQLITE,
|
3
|
+
table_data,
|
4
|
+
L4d2_players_tag,
|
5
|
+
L4d2_server_tag,
|
6
|
+
L4d2_INTEGER,
|
7
|
+
L4d2_TEXT,
|
8
|
+
L4d2_BOOLEAN,
|
9
|
+
tables_columns
|
10
|
+
)
|
11
|
+
import sqlite3
|
12
|
+
from nonebot.log import logger
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
class L4D2DataSqlite:
|
18
|
+
"""连接数据库和断开数据库,以及一些检查函数"""
|
19
|
+
def __init__(self):
|
20
|
+
"""连接数据库"""
|
21
|
+
self.datasqlite_path = DATASQLITE
|
22
|
+
self.datasqlite_path.mkdir(parents=True, exist_ok=True)
|
23
|
+
self.conn = sqlite3.connect(self.datasqlite_path / 'L4D2.db')
|
24
|
+
self._check_tables_exist()
|
25
|
+
self._check_data_existence()
|
26
|
+
self._check_data_validity()
|
27
|
+
logger.info("已连接求生数据库")
|
28
|
+
|
29
|
+
def _base_conn(self):
|
30
|
+
return self.conn
|
31
|
+
|
32
|
+
def _check_tables_exist(self) -> None:
|
33
|
+
"""
|
34
|
+
检查表是否存在
|
35
|
+
"""
|
36
|
+
c = self.conn.cursor()
|
37
|
+
for table in table_data:
|
38
|
+
c.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'")
|
39
|
+
if c.fetchone() is None:
|
40
|
+
if table == "L4d2_players":
|
41
|
+
c.execute(f"CREATE TABLE {table} (qq INTEGER PRIMARY KEY)")
|
42
|
+
elif table == "L4D2_server":
|
43
|
+
c.execute(f"CREATE TABLE {table} (number INTEGER PRIMARY KEY)")
|
44
|
+
self.conn.commit()
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
def _check_data_existence(self) -> None:
|
49
|
+
"""
|
50
|
+
检查表头是否存在,如果不存在则新建并填充默认值
|
51
|
+
"""
|
52
|
+
c = self.conn.cursor()
|
53
|
+
for table, tag in tables_columns.items():
|
54
|
+
for column in tag:
|
55
|
+
c.execute(f"PRAGMA table_info({table})")
|
56
|
+
if not any(col[1] == column for col in c.fetchall()):
|
57
|
+
if column in L4d2_BOOLEAN:
|
58
|
+
c.execute(f'ALTER TABLE {table} ADD COLUMN {column} BOOLEAN DEFAULT 0')
|
59
|
+
elif column in L4d2_INTEGER:
|
60
|
+
c.execute(f'ALTER TABLE {table} ADD COLUMN {column} INTEGER DEFAULT NULL')
|
61
|
+
else:
|
62
|
+
c.execute(f'ALTER TABLE {table} ADD COLUMN {column} TEXT DEFAULT NULL')
|
63
|
+
self.conn.commit()
|
64
|
+
|
65
|
+
|
66
|
+
def _check_data_validity(self) -> None:
|
67
|
+
"""
|
68
|
+
检查数据库数据的合法性
|
69
|
+
错误数据默认填充NULL或者False
|
70
|
+
"""
|
71
|
+
c = self.conn.cursor()
|
72
|
+
for table in table_data:
|
73
|
+
if table == "L4d2_players":
|
74
|
+
columns = L4d2_players_tag
|
75
|
+
elif table == "L4D2_server":
|
76
|
+
columns = L4d2_server_tag
|
77
|
+
for column in columns:
|
78
|
+
if column in L4d2_INTEGER:
|
79
|
+
c.execute(f"UPDATE {table} SET {column} = NULL WHERE typeof({column}) != 'integer'")
|
80
|
+
elif column in L4d2_TEXT:
|
81
|
+
c.execute(f"UPDATE {table} SET {column} = NULL WHERE typeof({column}) != 'text'")
|
82
|
+
elif column in L4d2_BOOLEAN:
|
83
|
+
c.execute(f"UPDATE {table} SET {column} = 'False' WHERE typeof({column}) != 'boolean'")
|
84
|
+
self.conn.commit()
|
85
|
+
|
86
|
+
def _close(self):
|
87
|
+
"""断开连接到数据库"""
|
88
|
+
self.conn.close()
|
89
|
+
logger.info("已断开求生数据库")
|
90
|
+
|
91
|
+
|
92
92
|
sq_L4D2 = L4D2DataSqlite()
|
@@ -1,18 +1,18 @@
|
|
1
|
-
# from pathlib import Path
|
2
|
-
# import yaml
|
3
|
-
|
4
|
-
# DATABASE = Path() / "data" / "L4D2"
|
5
|
-
# class L4D2Config:
|
6
|
-
|
7
|
-
# def __init__(self):
|
8
|
-
# self.config_yaml = "config.yaml"
|
9
|
-
# config_data = self._config_data()
|
10
|
-
|
11
|
-
# self
|
12
|
-
|
13
|
-
# def _config_data(self):
|
14
|
-
# """配置数据"""
|
15
|
-
# with open(self.config_yaml, 'r', encoding='utf-8') as e:
|
16
|
-
# a = e.read()
|
17
|
-
# data = yaml.safe_load(a)
|
1
|
+
# from pathlib import Path
|
2
|
+
# import yaml
|
3
|
+
|
4
|
+
# DATABASE = Path() / "data" / "L4D2"
|
5
|
+
# class L4D2Config:
|
6
|
+
|
7
|
+
# def __init__(self):
|
8
|
+
# self.config_yaml = "config.yaml"
|
9
|
+
# config_data = self._config_data()
|
10
|
+
|
11
|
+
# self
|
12
|
+
|
13
|
+
# def _config_data(self):
|
14
|
+
# """配置数据"""
|
15
|
+
# with open(self.config_yaml, 'r', encoding='utf-8') as e:
|
16
|
+
# a = e.read()
|
17
|
+
# data = yaml.safe_load(a)
|
18
18
|
# return data
|