pymecli 0.5.0__tar.gz → 0.5.2__tar.gz
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.
- {pymecli-0.5.0 → pymecli-0.5.2}/PKG-INFO +1 -1
- pymecli-0.5.2/cli/dst.py +292 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/util.py +4 -8
- {pymecli-0.5.0 → pymecli-0.5.2}/core/config.py +1 -1
- pymecli-0.5.2/data/template.yaml +156 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/pyproject.toml +2 -2
- pymecli-0.5.0/cli/baidu.py +0 -93
- pymecli-0.5.0/cli/dst.py +0 -222
- pymecli-0.5.0/data/template.yaml +0 -70
- {pymecli-0.5.0 → pymecli-0.5.2}/.gitignore +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/README.md +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/api/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/api/v1/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/api/v1/clash.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/api/v1/redis.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/bitget.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/example.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/fast.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/gate.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/cli/redis_csv.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/core/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/core/clash.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/core/redis_client.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/crypto/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/crypto/bitget.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/crypto/gate.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/data/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/data/dou_dict.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/data/dou_list.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/data/main.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/models/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/models/douzero_model.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/models/ocr_model.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/models/response.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/__init__.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/elapsed.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/helper.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/logger.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/mysql.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/path.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/pd.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/pyredis.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/sleep.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/text.py +0 -0
- {pymecli-0.5.0 → pymecli-0.5.2}/utils/toml.py +0 -0
pymecli-0.5.2/cli/dst.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Dict, List, Optional
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
import typer
|
|
6
|
+
from slpp import slpp as lua
|
|
7
|
+
|
|
8
|
+
app = typer.Typer()
|
|
9
|
+
|
|
10
|
+
STEAM_API_URL = (
|
|
11
|
+
"https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v0001"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_mod_versions(workshop_ids: List[str]) -> Dict[str, Dict[str, Optional[str]]]:
|
|
16
|
+
if not workshop_ids:
|
|
17
|
+
return {}
|
|
18
|
+
|
|
19
|
+
data = {"itemcount": str(len(workshop_ids))}
|
|
20
|
+
for i, wid in enumerate(workshop_ids):
|
|
21
|
+
data[f"publishedfileids[{i}]"] = wid
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
response = requests.post(STEAM_API_URL, data=data, timeout=15)
|
|
25
|
+
response.raise_for_status()
|
|
26
|
+
result = response.json()
|
|
27
|
+
except Exception as e:
|
|
28
|
+
typer.secho(f"✗ Steam API 请求失败: {e}", fg=typer.colors.RED)
|
|
29
|
+
return {}
|
|
30
|
+
|
|
31
|
+
versions: Dict[str, Dict[str, Optional[str]]] = {}
|
|
32
|
+
for detail in result["response"].get("publishedfiledetails", []):
|
|
33
|
+
publishedfileid = detail.get("publishedfileid")
|
|
34
|
+
title = detail.get("title")
|
|
35
|
+
tags = detail.get("tags", [])
|
|
36
|
+
version = None
|
|
37
|
+
for tag in tags:
|
|
38
|
+
tag_str = tag.get("tag", "")
|
|
39
|
+
if tag_str.startswith("version:"):
|
|
40
|
+
version = tag_str.replace("version:", "")
|
|
41
|
+
break
|
|
42
|
+
versions[publishedfileid] = {"version": version, "title": title}
|
|
43
|
+
|
|
44
|
+
return versions
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def extract_workshop_id(key: str) -> Optional[str]:
|
|
48
|
+
match = re.match(r"workshop-(\d+)", key)
|
|
49
|
+
return match.group(1) if match else None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def parse_lua_file(file_path: str) -> dict:
|
|
53
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
54
|
+
source = f.read()
|
|
55
|
+
source = source.strip()
|
|
56
|
+
if source.startswith("return"):
|
|
57
|
+
source = source[6:].strip()
|
|
58
|
+
result = lua.decode(source)
|
|
59
|
+
assert isinstance(result, dict)
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def write_lua_file(file_path: str, data: dict):
|
|
64
|
+
with open(file_path, "w", encoding="utf-8") as f:
|
|
65
|
+
f.write("return " + lua.encode(data) + "\n")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_client_mods(file_path: str, mod_id: str) -> Optional[tuple[dict, dict]]:
|
|
69
|
+
"""
|
|
70
|
+
解析 lua 文件,返回 (data, client_mods)。
|
|
71
|
+
失败返回 None(错误信息已由函数自行打印)。
|
|
72
|
+
"""
|
|
73
|
+
try:
|
|
74
|
+
data = parse_lua_file(file_path)
|
|
75
|
+
except FileNotFoundError:
|
|
76
|
+
typer.secho(f"✗ 文件不存在: {file_path}", fg=typer.colors.RED)
|
|
77
|
+
return None
|
|
78
|
+
except Exception as e:
|
|
79
|
+
typer.secho(f"✗ 解析 Lua 文件失败: {e}", fg=typer.colors.RED)
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
main_mod_key = f"workshop-{mod_id}"
|
|
83
|
+
main_mod = data.get(main_mod_key)
|
|
84
|
+
if not main_mod:
|
|
85
|
+
typer.secho(f"✗ 未找到 {main_mod_key}", fg=typer.colors.RED)
|
|
86
|
+
return data, {}
|
|
87
|
+
|
|
88
|
+
client_mods = main_mod.get("configuration_options", {}).get("client_mods_list", {})
|
|
89
|
+
if not client_mods:
|
|
90
|
+
typer.secho("✗ 未找到 client_mods", fg=typer.colors.RED)
|
|
91
|
+
return data, {}
|
|
92
|
+
|
|
93
|
+
return data, client_mods
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# update_client_mods
|
|
97
|
+
@app.command()
|
|
98
|
+
def convert_update(
|
|
99
|
+
file_path: str = typer.Argument(
|
|
100
|
+
"d:/github/meme2046/docker/dst/modoverrides.lua",
|
|
101
|
+
help="modoverrides.lua 文件路径",
|
|
102
|
+
),
|
|
103
|
+
mod_id: str = typer.Option(
|
|
104
|
+
"3486375086",
|
|
105
|
+
"--mod-id",
|
|
106
|
+
"-m",
|
|
107
|
+
help="模组: 客户端Mod转为服务器Mod<3486375086>的ID, 固定值",
|
|
108
|
+
),
|
|
109
|
+
output: List[str] = typer.Option(
|
|
110
|
+
None,
|
|
111
|
+
"--output",
|
|
112
|
+
"-o",
|
|
113
|
+
help="额外的输出路径,可多次指定",
|
|
114
|
+
),
|
|
115
|
+
):
|
|
116
|
+
"""
|
|
117
|
+
更新modoverrides.lua中<3486375086>的mods的版本信息
|
|
118
|
+
"""
|
|
119
|
+
result = get_client_mods(file_path, mod_id)
|
|
120
|
+
if result is None:
|
|
121
|
+
raise typer.Exit(code=1)
|
|
122
|
+
data, client_mods = result
|
|
123
|
+
|
|
124
|
+
workshop_ids = []
|
|
125
|
+
for key in client_mods.keys():
|
|
126
|
+
wid = extract_workshop_id(key)
|
|
127
|
+
if wid:
|
|
128
|
+
workshop_ids.append(wid)
|
|
129
|
+
|
|
130
|
+
if not workshop_ids:
|
|
131
|
+
typer.secho("✗ 未找到任何 client_mods", fg=typer.colors.RED)
|
|
132
|
+
raise typer.Exit(code=1)
|
|
133
|
+
|
|
134
|
+
typer.secho(
|
|
135
|
+
f"🔍 发现 {len(workshop_ids)} 个 client mods, 正在查询 Steam API...",
|
|
136
|
+
fg=typer.colors.BLUE,
|
|
137
|
+
)
|
|
138
|
+
versions = get_mod_versions(workshop_ids)
|
|
139
|
+
|
|
140
|
+
if not versions:
|
|
141
|
+
typer.secho("✗ 未能获取steam版本信息", fg=typer.colors.RED)
|
|
142
|
+
raise typer.Exit(code=1)
|
|
143
|
+
|
|
144
|
+
typer.secho("📝 正在更新版本号...", fg=typer.colors.BLUE)
|
|
145
|
+
updated_count = 0
|
|
146
|
+
for mod_key, mod_info in client_mods.items():
|
|
147
|
+
wid = extract_workshop_id(mod_key)
|
|
148
|
+
if not wid:
|
|
149
|
+
continue
|
|
150
|
+
mod_data = versions.get(wid)
|
|
151
|
+
if mod_data is None:
|
|
152
|
+
typer.secho(f"✗ {mod_key}: 未获取到版本信息", fg=typer.colors.YELLOW)
|
|
153
|
+
continue
|
|
154
|
+
new_version = mod_data.get("version")
|
|
155
|
+
title = mod_data.get("title", "")
|
|
156
|
+
if new_version is None:
|
|
157
|
+
typer.secho(
|
|
158
|
+
f"✗ {mod_key} ({title}): 未获取到版本信息", fg=typer.colors.YELLOW
|
|
159
|
+
)
|
|
160
|
+
continue
|
|
161
|
+
old_version = mod_info.get("version")
|
|
162
|
+
if old_version != new_version:
|
|
163
|
+
mod_info["version"] = new_version
|
|
164
|
+
updated_count += 1
|
|
165
|
+
typer.secho(
|
|
166
|
+
f"✓ {mod_key} ({title}): {old_version} -> {new_version}",
|
|
167
|
+
fg=typer.colors.GREEN,
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
typer.secho(
|
|
171
|
+
f"{mod_key} ({title}): 已是最新版本 {old_version}",
|
|
172
|
+
fg=typer.colors.WHITE,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
try:
|
|
176
|
+
if updated_count > 0:
|
|
177
|
+
write_lua_file(file_path, data)
|
|
178
|
+
typer.secho(f"💾 已保存到: {file_path}", fg=typer.colors.CYAN)
|
|
179
|
+
if output:
|
|
180
|
+
for p in output:
|
|
181
|
+
write_lua_file(p, data)
|
|
182
|
+
typer.secho(f"💾 已保存到: {p}", fg=typer.colors.CYAN)
|
|
183
|
+
except Exception as e:
|
|
184
|
+
typer.secho(f"✗ 写入文件失败: {e}", fg=typer.colors.RED)
|
|
185
|
+
raise typer.Exit(code=1)
|
|
186
|
+
|
|
187
|
+
if updated_count > 0:
|
|
188
|
+
typer.secho(f"🎉 成功更新 {updated_count} 个 mod 版本", fg=typer.colors.GREEN)
|
|
189
|
+
else:
|
|
190
|
+
typer.secho("✓ 所有MOD已是最新版本", fg=typer.colors.YELLOW)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@app.command()
|
|
194
|
+
def mod_setup(
|
|
195
|
+
file_path: str = typer.Argument(
|
|
196
|
+
"d:/github/meme2046/docker/dst/modoverrides.lua",
|
|
197
|
+
help="modoverrides.lua 文件路径",
|
|
198
|
+
),
|
|
199
|
+
mod_id: str = typer.Option(
|
|
200
|
+
"3486375086",
|
|
201
|
+
"--mod-id",
|
|
202
|
+
"-m",
|
|
203
|
+
help="模组: 客户端Mod转为服务器Mod<3486375086>的ID, 固定值",
|
|
204
|
+
),
|
|
205
|
+
output: List[str] = typer.Option(
|
|
206
|
+
["dedicated_server_mods_setup.lua"],
|
|
207
|
+
"--output",
|
|
208
|
+
"-o",
|
|
209
|
+
help="mods_setup输出路径,可多次指定",
|
|
210
|
+
),
|
|
211
|
+
):
|
|
212
|
+
"""
|
|
213
|
+
列出所有 mod, 并以<dedicated_server_mods_setup>格式保存到指定文件
|
|
214
|
+
"""
|
|
215
|
+
result = get_client_mods(file_path, mod_id)
|
|
216
|
+
if result is None:
|
|
217
|
+
raise typer.Exit(code=1)
|
|
218
|
+
data, client_mods = result
|
|
219
|
+
|
|
220
|
+
client_ids = []
|
|
221
|
+
for key in client_mods.keys():
|
|
222
|
+
wid = extract_workshop_id(key)
|
|
223
|
+
if wid:
|
|
224
|
+
client_ids.append(wid)
|
|
225
|
+
|
|
226
|
+
server_ids = []
|
|
227
|
+
for key in data.keys():
|
|
228
|
+
wid = extract_workshop_id(key)
|
|
229
|
+
if wid:
|
|
230
|
+
server_ids.append(wid)
|
|
231
|
+
|
|
232
|
+
versions = get_mod_versions(server_ids + client_ids)
|
|
233
|
+
|
|
234
|
+
if not versions:
|
|
235
|
+
typer.secho("✗ 未能获取steam版本信息", fg=typer.colors.RED)
|
|
236
|
+
raise typer.Exit(code=1)
|
|
237
|
+
|
|
238
|
+
setup_list = []
|
|
239
|
+
|
|
240
|
+
typer.secho(
|
|
241
|
+
f"📢 server_mods({len(server_ids)}):",
|
|
242
|
+
fg=typer.colors.GREEN,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
for item in server_ids:
|
|
246
|
+
mod_data = versions.get(item)
|
|
247
|
+
|
|
248
|
+
if mod_data is None:
|
|
249
|
+
typer.secho(f"✗ {item}: 未获取到版本信息", fg=typer.colors.YELLOW)
|
|
250
|
+
raise typer.Exit(code=1)
|
|
251
|
+
|
|
252
|
+
setup_list.append(f'ServerModSetup("{item}")')
|
|
253
|
+
|
|
254
|
+
new_version = mod_data.get("version")
|
|
255
|
+
title = mod_data.get("title", "")
|
|
256
|
+
|
|
257
|
+
typer.secho(
|
|
258
|
+
f"{item} ({title}): {new_version}",
|
|
259
|
+
fg=typer.colors.WHITE,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
typer.secho(
|
|
263
|
+
f"📢 client_mods({len(client_ids)}):",
|
|
264
|
+
fg=typer.colors.GREEN,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
for item in client_ids:
|
|
268
|
+
mod_data = versions.get(item)
|
|
269
|
+
|
|
270
|
+
if mod_data is None:
|
|
271
|
+
typer.secho(f"✗ {item}: 未获取到版本信息", fg=typer.colors.YELLOW)
|
|
272
|
+
raise typer.Exit(code=1)
|
|
273
|
+
|
|
274
|
+
setup_list.append(f'ServerModSetup("{item}")')
|
|
275
|
+
|
|
276
|
+
new_version = mod_data.get("version")
|
|
277
|
+
title = mod_data.get("title", "")
|
|
278
|
+
|
|
279
|
+
typer.secho(
|
|
280
|
+
f"{item} ({title}): {new_version}",
|
|
281
|
+
fg=typer.colors.WHITE,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
for p in output:
|
|
285
|
+
with open(p, "w", encoding="utf-8") as f:
|
|
286
|
+
f.write("\n".join(setup_list))
|
|
287
|
+
typer.secho(f"💾 <setup_list>已保存到: {p}", fg=typer.colors.CYAN)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
if __name__ == "__main__":
|
|
291
|
+
# cmu("d:/github/meme2046/docker/dst/modoverrides.lua", "3486375086")
|
|
292
|
+
convert_update("d:/github/meme2046/docker/dst/modoverrides.lua", "3486375086")
|
|
@@ -68,12 +68,8 @@ def emoji():
|
|
|
68
68
|
emoji_list = [
|
|
69
69
|
"『",
|
|
70
70
|
"』",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"❗",
|
|
74
|
-
"⭕",
|
|
75
|
-
"❓",
|
|
76
|
-
"❌",
|
|
71
|
+
"✓",
|
|
72
|
+
"✗",
|
|
77
73
|
"⤴︎",
|
|
78
74
|
"⤵︎",
|
|
79
75
|
"⇡",
|
|
@@ -147,7 +143,7 @@ def say():
|
|
|
147
143
|
@app.command()
|
|
148
144
|
def ipv6():
|
|
149
145
|
"""
|
|
150
|
-
获取本地
|
|
146
|
+
获取本地 IPv6 稳定地址
|
|
151
147
|
"""
|
|
152
148
|
ips = []
|
|
153
149
|
adapters = ifaddr.get_adapters(include_unconfigured=False)
|
|
@@ -178,7 +174,7 @@ def ipv6():
|
|
|
178
174
|
print("未找到稳定 IPV6 地址")
|
|
179
175
|
return ips
|
|
180
176
|
|
|
181
|
-
print(f"
|
|
177
|
+
print(f"IPv6 稳定地址: {ips}")
|
|
182
178
|
|
|
183
179
|
r = get_redis_client_sync()
|
|
184
180
|
r.set("local.IPv6", ips[0])
|
|
@@ -19,7 +19,7 @@ class Settings(BaseSettings):
|
|
|
19
19
|
REDIS_PASSWORD: str = ""
|
|
20
20
|
|
|
21
21
|
PROJECT_DESCRIPTION: str = (
|
|
22
|
-
f"{metadata['Summary']}, FastAPI提供: clash订阅转换、
|
|
22
|
+
f"{metadata['Summary']}, FastAPI提供: clash订阅转换、redis API"
|
|
23
23
|
)
|
|
24
24
|
PROJECT_VERSION: str = metadata["Version"]
|
|
25
25
|
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
external-controller: ""
|
|
2
|
+
ipv6: true
|
|
3
|
+
mode: rule
|
|
4
|
+
mixed-port: 7897
|
|
5
|
+
socks-port: 0
|
|
6
|
+
port: 0
|
|
7
|
+
redir-port: 0
|
|
8
|
+
tproxy-port: 0
|
|
9
|
+
allow-lan: true
|
|
10
|
+
unified-delay: true
|
|
11
|
+
tcp-concurrent: false
|
|
12
|
+
log-level: info
|
|
13
|
+
find-process-mode: strict
|
|
14
|
+
bind-address: "*"
|
|
15
|
+
lan-allowed-ips:
|
|
16
|
+
- 0.0.0.0/0
|
|
17
|
+
- ::/0
|
|
18
|
+
lan-disallowed-ips: []
|
|
19
|
+
authentication: []
|
|
20
|
+
skip-auth-prefixes:
|
|
21
|
+
- 127.0.0.1/32
|
|
22
|
+
- ::1/128
|
|
23
|
+
tun:
|
|
24
|
+
enable: false
|
|
25
|
+
stack: mixed
|
|
26
|
+
auto-route: true
|
|
27
|
+
auto-redirect: false
|
|
28
|
+
auto-detect-interface: true
|
|
29
|
+
dns-hijack:
|
|
30
|
+
- any:53
|
|
31
|
+
route-exclude-address: []
|
|
32
|
+
mtu: 1500
|
|
33
|
+
device: Mihomo
|
|
34
|
+
dns:
|
|
35
|
+
enable: true
|
|
36
|
+
ipv6: true
|
|
37
|
+
enhanced-mode: fake-ip
|
|
38
|
+
fake-ip-range: 198.18.0.1/16
|
|
39
|
+
fake-ip-filter:
|
|
40
|
+
- "*"
|
|
41
|
+
- +.lan
|
|
42
|
+
- +.local
|
|
43
|
+
- time.*.com
|
|
44
|
+
- ntp.*.com
|
|
45
|
+
- +.market.xiaomi.com
|
|
46
|
+
use-hosts: false
|
|
47
|
+
use-system-hosts: false
|
|
48
|
+
respect-rules: true
|
|
49
|
+
default-nameserver:
|
|
50
|
+
- https://223.5.5.5/dns-query
|
|
51
|
+
- https://223.6.6.6/dns-query
|
|
52
|
+
- https://8.8.8.8/dns-query
|
|
53
|
+
- https://1.1.1.1/dns-query
|
|
54
|
+
- 223.5.5.5
|
|
55
|
+
nameserver:
|
|
56
|
+
- https://dns.alidns.com/dns-query
|
|
57
|
+
- https://doh.pub/dns-query
|
|
58
|
+
proxy-server-nameserver:
|
|
59
|
+
- https://cloudflare-dns.com/dns-query
|
|
60
|
+
- https://dns.google/dns-query
|
|
61
|
+
- https://dns.alidns.com/dns-query
|
|
62
|
+
- https://doh.pub/dns-query
|
|
63
|
+
direct-nameserver:
|
|
64
|
+
- https://dns.alidns.com/dns-query
|
|
65
|
+
- https://doh.pub/dns-query
|
|
66
|
+
fallback:
|
|
67
|
+
- https://cloudflare-dns.com/dns-query
|
|
68
|
+
- https://dns.google/dns-query
|
|
69
|
+
fallback-filter:
|
|
70
|
+
geoip: true
|
|
71
|
+
geoip-code: CN
|
|
72
|
+
ipcidr:
|
|
73
|
+
- 240.0.0.0/4
|
|
74
|
+
- 0.0.0.0/32
|
|
75
|
+
- 127.0.0.0/8
|
|
76
|
+
- 10.0.0.0/8
|
|
77
|
+
- 192.168.0.0/16
|
|
78
|
+
domain:
|
|
79
|
+
- +.google.com
|
|
80
|
+
- +.facebook.com
|
|
81
|
+
- +.youtube.com
|
|
82
|
+
direct-nameserver-follow-policy: true
|
|
83
|
+
prefer-h3: false
|
|
84
|
+
nameserver-policy:
|
|
85
|
+
geosite:cn:
|
|
86
|
+
- https://dns.alidns.com/dns-query
|
|
87
|
+
- https://doh.pub/dns-query
|
|
88
|
+
geosite:geolocation-!cn:
|
|
89
|
+
- https://cloudflare-dns.com/dns-query
|
|
90
|
+
- https://dns.google/dns-query
|
|
91
|
+
+.jsdelivr.net:
|
|
92
|
+
- https://cloudflare-dns.com/dns-query
|
|
93
|
+
- https://dns.google/dns-query
|
|
94
|
+
+.github.com:
|
|
95
|
+
- https://cloudflare-dns.com/dns-query
|
|
96
|
+
- https://dns.google/dns-query
|
|
97
|
+
+.githubusercontent.com:
|
|
98
|
+
- https://cloudflare-dns.com/dns-query
|
|
99
|
+
- https://dns.google/dns-query
|
|
100
|
+
+.githubassets.com:
|
|
101
|
+
- https://cloudflare-dns.com/dns-query
|
|
102
|
+
- https://dns.google/dns-query
|
|
103
|
+
+.fastly.net:
|
|
104
|
+
- https://cloudflare-dns.com/dns-query
|
|
105
|
+
- https://dns.google/dns-query
|
|
106
|
+
sniffer:
|
|
107
|
+
enable: true
|
|
108
|
+
parse-pure-ip: true
|
|
109
|
+
force-dns-mapping: true
|
|
110
|
+
override-destination: true
|
|
111
|
+
sniff:
|
|
112
|
+
HTTP:
|
|
113
|
+
ports:
|
|
114
|
+
- "80"
|
|
115
|
+
- 8080-8880
|
|
116
|
+
override-destination: true
|
|
117
|
+
TLS:
|
|
118
|
+
ports:
|
|
119
|
+
- "443"
|
|
120
|
+
- "8443"
|
|
121
|
+
QUIC:
|
|
122
|
+
ports:
|
|
123
|
+
- "443"
|
|
124
|
+
- "8443"
|
|
125
|
+
- "4433"
|
|
126
|
+
skip-domain:
|
|
127
|
+
- +.push.apple.com
|
|
128
|
+
skip-dst-address:
|
|
129
|
+
- 91.105.192.0/23
|
|
130
|
+
- 91.108.4.0/22
|
|
131
|
+
- 91.108.8.0/21
|
|
132
|
+
- 91.108.16.0/21
|
|
133
|
+
- 91.108.56.0/22
|
|
134
|
+
- 95.161.64.0/20
|
|
135
|
+
- 149.154.160.0/20
|
|
136
|
+
- 185.76.151.0/24
|
|
137
|
+
- 2001:67c:4e8::/48
|
|
138
|
+
- 2001:b28:f23c::/47
|
|
139
|
+
- 2001:b28:f23f::/48
|
|
140
|
+
- 2a0a:f280:203::/48
|
|
141
|
+
profile:
|
|
142
|
+
store-selected: true
|
|
143
|
+
store-fake-ip: true
|
|
144
|
+
geo-auto-update: false
|
|
145
|
+
geo-update-interval: 24
|
|
146
|
+
geodata-mode: true
|
|
147
|
+
geox-url:
|
|
148
|
+
geoip: https://fastly.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip.dat
|
|
149
|
+
mmdb: https://fastly.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb
|
|
150
|
+
asn: https://fastly.jsdelivr.net/gh/Loyalsoldier/geoip@release/GeoLite2-ASN.mmdb
|
|
151
|
+
geosite: https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat
|
|
152
|
+
proxies: []
|
|
153
|
+
proxy-providers: {}
|
|
154
|
+
proxy-groups: []
|
|
155
|
+
rule-providers: {}
|
|
156
|
+
rules: []
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
name = "pymecli"
|
|
36
36
|
readme = "README.md"
|
|
37
37
|
requires-python = ">=3.10"
|
|
38
|
-
version = "0.5.
|
|
38
|
+
version = "0.5.2"
|
|
39
39
|
|
|
40
40
|
[project.urls]
|
|
41
41
|
Homepage = "https://pypi.org/project/pymecli"
|
|
42
42
|
Repository = "https://github.com/meme2046/pymecli"
|
|
43
43
|
|
|
44
44
|
[project.scripts]
|
|
45
|
-
baidu = "cli.baidu:app"
|
|
45
|
+
# baidu = "cli.baidu:app"
|
|
46
46
|
bitget = "cli.bitget:app"
|
|
47
47
|
dst = "cli.dst:app"
|
|
48
48
|
example = "cli.example:app"
|
pymecli-0.5.0/cli/baidu.py
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
|
-
import typer
|
|
4
|
-
from selenium import webdriver
|
|
5
|
-
from selenium.webdriver.chrome.options import Options
|
|
6
|
-
from selenium.webdriver.chrome.service import Service
|
|
7
|
-
from webdriver_manager.chrome import ChromeDriverManager
|
|
8
|
-
|
|
9
|
-
from utils.pyredis import get_redis_client_sync
|
|
10
|
-
|
|
11
|
-
app = typer.Typer()
|
|
12
|
-
|
|
13
|
-
r = get_redis_client_sync()
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@app.command()
|
|
17
|
-
def acsToken(
|
|
18
|
-
url: str = typer.Argument(
|
|
19
|
-
"https://finance.baidu.com/index/ab-000001?name=%25E4%25B8%258A%25E8%25AF%2581%25E6%258C%2587%25E6%2595%25B0",
|
|
20
|
-
help="request url",
|
|
21
|
-
),
|
|
22
|
-
timeout: int = typer.Option(
|
|
23
|
-
10,
|
|
24
|
-
"--timeout",
|
|
25
|
-
"-t",
|
|
26
|
-
help="timeout内如果没有请求完整,会强制中断,然后从已有的请求中获取数据",
|
|
27
|
-
),
|
|
28
|
-
):
|
|
29
|
-
"""通过selenium获取百度股事通Acs-Token
|
|
30
|
-
|
|
31
|
-
Args:
|
|
32
|
-
url (str, optional): 请求的『URL』地址. Defaults to typer.Argument( "https://finance.baidu.com/", help="request url", ).
|
|
33
|
-
timeout (int, optional): _description_. Defaults to typer.Option( 3, "--timeout", "-t", help="timeout内如果没有请求完整,会强制中断,然后从已有的请求中获取数据", ).
|
|
34
|
-
|
|
35
|
-
Returns:
|
|
36
|
-
str: 『Acs-Token』字符串
|
|
37
|
-
"""
|
|
38
|
-
# 配置 Chrome 浏览器以启用 Performance API
|
|
39
|
-
chrome_options = Options()
|
|
40
|
-
chrome_options.add_argument("--enable-logging")
|
|
41
|
-
chrome_options.add_argument("--v=1")
|
|
42
|
-
chrome_options.add_argument("--headless") # 启用无头模式
|
|
43
|
-
chrome_options.add_argument("--disable-gpu") # 禁用 GPU 加速
|
|
44
|
-
chrome_options.add_argument("--window-size=1920,1080") # 设置窗口大小
|
|
45
|
-
chrome_options.add_argument("--no-sandbox") # 禁用沙盒模式
|
|
46
|
-
chrome_options.add_argument("--disable-dev-shm-usage") # 禁用 /dev/shm 使用
|
|
47
|
-
chrome_options.set_capability("goog:loggingPrefs", {"performance": "ALL"})
|
|
48
|
-
|
|
49
|
-
driver = webdriver.Chrome(
|
|
50
|
-
service=Service(ChromeDriverManager().install()), options=chrome_options
|
|
51
|
-
)
|
|
52
|
-
driver.set_page_load_timeout(timeout)
|
|
53
|
-
|
|
54
|
-
try:
|
|
55
|
-
driver.get(url)
|
|
56
|
-
except Exception:
|
|
57
|
-
driver.execute_script("window.stop();")
|
|
58
|
-
|
|
59
|
-
# 从网络请求中提取 Acs-Token
|
|
60
|
-
acs_token = get_acs_token_from_requests(driver)
|
|
61
|
-
|
|
62
|
-
driver.quit()
|
|
63
|
-
|
|
64
|
-
if acs_token:
|
|
65
|
-
print(f"Acs-Token:『{acs_token}』")
|
|
66
|
-
r.set("baidu.Acs-Token", acs_token)
|
|
67
|
-
|
|
68
|
-
return acs_token
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def get_acs_token_from_requests(driver):
|
|
72
|
-
"""从网络请求中提取 Acs-Token"""
|
|
73
|
-
# 获取性能日志
|
|
74
|
-
|
|
75
|
-
logs = driver.get_log("performance")
|
|
76
|
-
|
|
77
|
-
for entry in logs:
|
|
78
|
-
log = json.loads(entry["message"])["message"]
|
|
79
|
-
|
|
80
|
-
# 检查是否是网络请求
|
|
81
|
-
if log["method"] == "Network.requestWillBeSent":
|
|
82
|
-
request = log["params"].get("request", {})
|
|
83
|
-
headers = request.get("headers", {})
|
|
84
|
-
|
|
85
|
-
# 检查请求头中是否包含 Acs-Token
|
|
86
|
-
if "Acs-Token" in headers:
|
|
87
|
-
return headers["Acs-Token"]
|
|
88
|
-
|
|
89
|
-
return ""
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if __name__ == "__main__":
|
|
93
|
-
app()
|
pymecli-0.5.0/cli/dst.py
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from typing import Dict, List, Optional
|
|
3
|
-
|
|
4
|
-
import requests
|
|
5
|
-
import typer
|
|
6
|
-
from slpp import slpp as lua
|
|
7
|
-
|
|
8
|
-
app = typer.Typer()
|
|
9
|
-
|
|
10
|
-
STEAM_API_URL = (
|
|
11
|
-
"https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v0001"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def get_mod_versions(workshop_ids: List[str]) -> Dict[str, Dict[str, Optional[str]]]:
|
|
16
|
-
if not workshop_ids:
|
|
17
|
-
return {}
|
|
18
|
-
|
|
19
|
-
data = {"itemcount": str(len(workshop_ids))}
|
|
20
|
-
for i, wid in enumerate(workshop_ids):
|
|
21
|
-
data[f"publishedfileids[{i}]"] = wid
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
response = requests.post(STEAM_API_URL, data=data, timeout=15)
|
|
25
|
-
response.raise_for_status()
|
|
26
|
-
result = response.json()
|
|
27
|
-
except Exception as e:
|
|
28
|
-
typer.secho(f"❌ Steam API 请求失败: {e}", fg=typer.colors.RED)
|
|
29
|
-
return {}
|
|
30
|
-
|
|
31
|
-
versions: Dict[str, Dict[str, Optional[str]]] = {}
|
|
32
|
-
for detail in result["response"].get("publishedfiledetails", []):
|
|
33
|
-
publishedfileid = detail.get("publishedfileid")
|
|
34
|
-
title = detail.get("title")
|
|
35
|
-
tags = detail.get("tags", [])
|
|
36
|
-
version = None
|
|
37
|
-
for tag in tags:
|
|
38
|
-
tag_str = tag.get("tag", "")
|
|
39
|
-
if tag_str.startswith("version:"):
|
|
40
|
-
version = tag_str.replace("version:", "")
|
|
41
|
-
break
|
|
42
|
-
versions[publishedfileid] = {"version": version, "title": title}
|
|
43
|
-
|
|
44
|
-
return versions
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def extract_workshop_id(key: str) -> Optional[str]:
|
|
48
|
-
match = re.match(r"workshop-(\d+)", key)
|
|
49
|
-
return match.group(1) if match else None
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def parse_lua_file(file_path: str) -> dict:
|
|
53
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
|
54
|
-
source = f.read()
|
|
55
|
-
source = source.strip()
|
|
56
|
-
if source.startswith("return"):
|
|
57
|
-
source = source[6:].strip()
|
|
58
|
-
result = lua.decode(source)
|
|
59
|
-
assert isinstance(result, dict)
|
|
60
|
-
return result
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def write_lua_file(file_path: str, data: dict):
|
|
64
|
-
with open(file_path, "w", encoding="utf-8") as f:
|
|
65
|
-
f.write("return " + lua.encode(data) + "\n")
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def get_client_mods_list(file_path: str, mod_id: str) -> Optional[tuple[dict, dict]]:
|
|
69
|
-
"""
|
|
70
|
-
解析 lua 文件,返回 (data, client_mods_list)。
|
|
71
|
-
失败返回 None(错误信息已由函数自行打印)。
|
|
72
|
-
"""
|
|
73
|
-
try:
|
|
74
|
-
data = parse_lua_file(file_path)
|
|
75
|
-
except FileNotFoundError:
|
|
76
|
-
typer.secho(f"❌ 文件不存在: {file_path}", fg=typer.colors.RED)
|
|
77
|
-
return None
|
|
78
|
-
except Exception as e:
|
|
79
|
-
typer.secho(f"❌ 解析 Lua 文件失败: {e}", fg=typer.colors.RED)
|
|
80
|
-
return None
|
|
81
|
-
|
|
82
|
-
main_mod_key = f"workshop-{mod_id}"
|
|
83
|
-
main_mod = data.get(main_mod_key)
|
|
84
|
-
if not main_mod:
|
|
85
|
-
typer.secho(f"❌ 未找到 {main_mod_key}", fg=typer.colors.RED)
|
|
86
|
-
return None
|
|
87
|
-
|
|
88
|
-
client_mods_list = main_mod.get("configuration_options", {}).get(
|
|
89
|
-
"client_mods_list", {}
|
|
90
|
-
)
|
|
91
|
-
if not client_mods_list:
|
|
92
|
-
typer.secho("❌ 未找到 client_mods_list", fg=typer.colors.RED)
|
|
93
|
-
return None
|
|
94
|
-
|
|
95
|
-
return data, client_mods_list
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# update_client_mods
|
|
99
|
-
@app.command()
|
|
100
|
-
def cmu(
|
|
101
|
-
file_path: str = typer.Argument(
|
|
102
|
-
"d:/.backups/dontstarvetogether/modoverrides.lua",
|
|
103
|
-
help="modoverrides.lua 文件路径",
|
|
104
|
-
),
|
|
105
|
-
mod_id: str = typer.Option(
|
|
106
|
-
"3486375086",
|
|
107
|
-
"--mod-id",
|
|
108
|
-
"-m",
|
|
109
|
-
help="主 mod 的 workshop ID",
|
|
110
|
-
),
|
|
111
|
-
output: List[str] = typer.Option(
|
|
112
|
-
None,
|
|
113
|
-
"--output",
|
|
114
|
-
"-o",
|
|
115
|
-
help="额外的输出路径,可多次指定",
|
|
116
|
-
),
|
|
117
|
-
):
|
|
118
|
-
result = get_client_mods_list(file_path, mod_id)
|
|
119
|
-
if result is None:
|
|
120
|
-
raise typer.Exit(code=1)
|
|
121
|
-
data, client_mods_list = result
|
|
122
|
-
|
|
123
|
-
workshop_ids = []
|
|
124
|
-
for key in client_mods_list.keys():
|
|
125
|
-
wid = extract_workshop_id(key)
|
|
126
|
-
if wid:
|
|
127
|
-
workshop_ids.append(wid)
|
|
128
|
-
|
|
129
|
-
if not workshop_ids:
|
|
130
|
-
typer.secho("❌ 未找到任何 client_mods", fg=typer.colors.RED)
|
|
131
|
-
raise typer.Exit(code=1)
|
|
132
|
-
|
|
133
|
-
typer.secho(
|
|
134
|
-
f"🔍 发现 {len(workshop_ids)} 个 client mods,正在查询 Steam API...",
|
|
135
|
-
fg=typer.colors.BLUE,
|
|
136
|
-
)
|
|
137
|
-
versions = get_mod_versions(workshop_ids)
|
|
138
|
-
|
|
139
|
-
if not versions:
|
|
140
|
-
typer.secho("❌ 未能获取版本信息", fg=typer.colors.RED)
|
|
141
|
-
raise typer.Exit(code=1)
|
|
142
|
-
|
|
143
|
-
typer.secho("📝 正在更新版本号...", fg=typer.colors.BLUE)
|
|
144
|
-
updated_count = 0
|
|
145
|
-
for mod_key, mod_info in client_mods_list.items():
|
|
146
|
-
wid = extract_workshop_id(mod_key)
|
|
147
|
-
if not wid:
|
|
148
|
-
continue
|
|
149
|
-
mod_data = versions.get(wid)
|
|
150
|
-
if mod_data is None:
|
|
151
|
-
typer.secho(f"⚠️ {mod_key}: 未获取到版本信息", fg=typer.colors.YELLOW)
|
|
152
|
-
continue
|
|
153
|
-
new_version = mod_data.get("version")
|
|
154
|
-
title = mod_data.get("title", "")
|
|
155
|
-
if new_version is None:
|
|
156
|
-
typer.secho(
|
|
157
|
-
f"⚠️ {mod_key} ({title}): 未获取到版本信息", fg=typer.colors.YELLOW
|
|
158
|
-
)
|
|
159
|
-
continue
|
|
160
|
-
old_version = mod_info.get("version")
|
|
161
|
-
if old_version != new_version:
|
|
162
|
-
mod_info["version"] = new_version
|
|
163
|
-
updated_count += 1
|
|
164
|
-
typer.secho(
|
|
165
|
-
f"✅ {mod_key} ({title}): {old_version} -> {new_version}",
|
|
166
|
-
fg=typer.colors.GREEN,
|
|
167
|
-
)
|
|
168
|
-
else:
|
|
169
|
-
typer.secho(
|
|
170
|
-
f"ℹ️ {mod_key} ({title}): 已是最新版本 {old_version}",
|
|
171
|
-
fg=typer.colors.WHITE,
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
try:
|
|
175
|
-
if updated_count > 0:
|
|
176
|
-
write_lua_file(file_path, data)
|
|
177
|
-
typer.secho(f"💾 已保存到: {file_path}", fg=typer.colors.CYAN)
|
|
178
|
-
if output:
|
|
179
|
-
for p in output:
|
|
180
|
-
write_lua_file(p, data)
|
|
181
|
-
typer.secho(f"💾 已保存到: {p}", fg=typer.colors.CYAN)
|
|
182
|
-
except Exception as e:
|
|
183
|
-
typer.secho(f"❌ 写入文件失败: {e}", fg=typer.colors.RED)
|
|
184
|
-
raise typer.Exit(code=1)
|
|
185
|
-
|
|
186
|
-
if updated_count > 0:
|
|
187
|
-
typer.secho(f"\n🎉 成功更新 {updated_count} 个 mod 版本", fg=typer.colors.GREEN)
|
|
188
|
-
else:
|
|
189
|
-
typer.secho("\nℹ️ 所有 mod 已是最新版本", fg=typer.colors.YELLOW)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
# list_client_mods
|
|
193
|
-
@app.command()
|
|
194
|
-
def cml(
|
|
195
|
-
file_path: str = typer.Argument(
|
|
196
|
-
"d:/.backups/dontstarvetogether/modoverrides.lua",
|
|
197
|
-
help="modoverrides.lua 文件路径",
|
|
198
|
-
),
|
|
199
|
-
mod_id: str = typer.Option(
|
|
200
|
-
"3486375086",
|
|
201
|
-
"--mod-id",
|
|
202
|
-
"-m",
|
|
203
|
-
help="主 mod 的 workshop ID",
|
|
204
|
-
),
|
|
205
|
-
):
|
|
206
|
-
"""
|
|
207
|
-
列出 client_mods_list 中所有 mod 的当前版本
|
|
208
|
-
"""
|
|
209
|
-
result = get_client_mods_list(file_path, mod_id)
|
|
210
|
-
if result is None:
|
|
211
|
-
raise typer.Exit(code=1)
|
|
212
|
-
_, client_mods_list = result
|
|
213
|
-
|
|
214
|
-
typer.secho("\n📋 client_mods_list 中的 mod 列表:", fg=typer.colors.BLUE)
|
|
215
|
-
for i, (mod_key, mod_info) in enumerate(client_mods_list.items(), 1):
|
|
216
|
-
version = mod_info.get("version", "unknown")
|
|
217
|
-
typer.secho(f"{i}. {mod_key}: {version}", fg=typer.colors.WHITE)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if __name__ == "__main__":
|
|
221
|
-
# cmu("d:/.backups/dontstarvetogether/modoverrides.lua", "3486375086")
|
|
222
|
-
cml("d:/.backups/dontstarvetogether/modoverrides.lua", "3486375086")
|
pymecli-0.5.0/data/template.yaml
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
mixed-port: 7897
|
|
2
|
-
allow-lan: true
|
|
3
|
-
mode: rule
|
|
4
|
-
log-level: warning
|
|
5
|
-
external-controller: "127.0.0.1:9097"
|
|
6
|
-
client-fingerprint: chrome
|
|
7
|
-
unified-delay: true
|
|
8
|
-
ipv6: true
|
|
9
|
-
profile:
|
|
10
|
-
store-selected: true
|
|
11
|
-
tun:
|
|
12
|
-
mtu: 1500
|
|
13
|
-
dns:
|
|
14
|
-
enable: true
|
|
15
|
-
listen: ":53"
|
|
16
|
-
enhanced-mode: "fake-ip"
|
|
17
|
-
fake-ip-range: "198.18.0.1/16"
|
|
18
|
-
fake-ip-filter-mode: "blacklist"
|
|
19
|
-
prefer-h3: false
|
|
20
|
-
respect-rules: false
|
|
21
|
-
use-hosts: false
|
|
22
|
-
use-system-hosts: false
|
|
23
|
-
ipv6: true
|
|
24
|
-
fake-ip-filter:
|
|
25
|
-
- "*.lan"
|
|
26
|
-
- "*.local"
|
|
27
|
-
- "*.arpa"
|
|
28
|
-
- "time.*.com"
|
|
29
|
-
- "ntp.*.com"
|
|
30
|
-
- "time.*.com"
|
|
31
|
-
- "+.market.xiaomi.com"
|
|
32
|
-
- "localhost.ptlogin2.qq.com"
|
|
33
|
-
- "*.msftncsi.com"
|
|
34
|
-
- "www.msftconnecttest.com"
|
|
35
|
-
default-nameserver:
|
|
36
|
-
- "system"
|
|
37
|
-
- "223.6.6.6"
|
|
38
|
-
- "8.8.8.8"
|
|
39
|
-
- "2400:3200::1"
|
|
40
|
-
- "2001:4860:4860::8888"
|
|
41
|
-
nameserver:
|
|
42
|
-
- "8.8.8.8"
|
|
43
|
-
- "https://doh.pub/dns-query"
|
|
44
|
-
- "https://dns.alidns.com/dns-query"
|
|
45
|
-
direct-nameserver-follow-policy: false
|
|
46
|
-
fallback-filter:
|
|
47
|
-
geoip: true
|
|
48
|
-
geoip-code: "CN"
|
|
49
|
-
ipcidr:
|
|
50
|
-
- "240.0.0.0/4"
|
|
51
|
-
- "0.0.0.0/32"
|
|
52
|
-
domain:
|
|
53
|
-
- "+.google.com"
|
|
54
|
-
- "+.facebook.com"
|
|
55
|
-
- "+.youtube.com"
|
|
56
|
-
fallback: []
|
|
57
|
-
proxy-server-nameserver:
|
|
58
|
-
- "https://doh.pub/dns-query"
|
|
59
|
-
- "https://dns.alidns.com/dns-query"
|
|
60
|
-
- "tls://223.5.5.5"
|
|
61
|
-
direct-nameserver: []
|
|
62
|
-
external-controller-cors:
|
|
63
|
-
allow-private-network: true
|
|
64
|
-
allow-origins:
|
|
65
|
-
- "*"
|
|
66
|
-
proxies: []
|
|
67
|
-
proxy-providers: {}
|
|
68
|
-
proxy-groups: []
|
|
69
|
-
rule-providers: {}
|
|
70
|
-
rules: []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|