This commit is contained in:
riglen
2026-04-01 16:19:08 +08:00
parent caa3aa49f2
commit 167154481c
5 changed files with 897 additions and 4 deletions

View File

@@ -143,6 +143,8 @@ HEAD /<PUBLIC_PATH>/bundle/stash.yaml?sources=airport-a,airport-b
- 服务端把节点、策略组、规则全部展开到一个 YAML 里 - 服务端把节点、策略组、规则全部展开到一个 YAML 里
- 适合想直接给 Mihomo Party / Clash Party / Stash 一个最终链接的场景 - 适合想直接给 Mihomo Party / Clash Party / Stash 一个最终链接的场景
- 响应头同样只取第一个源的 `Subscription-Userinfo` - 响应头同样只取第一个源的 `Subscription-Userinfo`
- 生成后的完整 YAML 会缓存到 `output/bundle-cache/`,默认 600 秒内直接返回缓存
- 可用 `force_refresh=true` 强制跳过缓存并覆盖旧缓存文件
--- ---

View File

@@ -23,11 +23,13 @@ class Settings(BaseSettings):
public_base_url: str | None = None public_base_url: str | None = None
request_timeout_seconds: float = 20.0 request_timeout_seconds: float = 20.0
cache_ttl_seconds: int = 900 cache_ttl_seconds: int = 900
bundle_cache_ttl_seconds: int = 600
max_proxy_name_length: int = 80 max_proxy_name_length: int = 80
default_user_agent: str = "sub-provider/0.2" default_user_agent: str = "sub-provider/0.2"
sources_file: Path = CONFIG_DIR / "sources.yaml" sources_file: Path = CONFIG_DIR / "sources.yaml"
rules_dir: Path = CONFIG_DIR / "rules" rules_dir: Path = CONFIG_DIR / "rules"
bundle_cache_dir: Path = ROOT_DIR / "output" / "bundle-cache"
model_config = SettingsConfigDict( model_config = SettingsConfigDict(
env_file=ROOT_DIR / ".env", env_file=ROOT_DIR / ".env",

View File

@@ -4,7 +4,8 @@ from fastapi import FastAPI, HTTPException, Query, Request
from fastapi.responses import Response from fastapi.responses import Response
from app.config import get_settings from app.config import get_settings
from app.models import RuleConfig, SourceConfig from app.models import RuleConfig, SourceConfig, SourceSnapshot
from app.services.bundle_cache import build_bundle_cache_key, load_bundle_cache, save_bundle_cache
from app.services.loader import load_app_config from app.services.loader import load_app_config
from app.services.profiles import build_bundle_profile, build_thin_profile, dump_yaml from app.services.profiles import build_bundle_profile, build_thin_profile, dump_yaml
from app.services.rules import load_rule_text from app.services.rules import load_rule_text
@@ -71,6 +72,15 @@ async def _build_quota_headers(source_items: list[tuple[str, SourceConfig]]) ->
return headers return headers
def _quota_headers_from_snapshots(snapshots: list[SourceSnapshot]) -> dict[str, str]:
if not snapshots:
return {}
quota = snapshots[0].quota
if quota and not quota.is_empty():
return {"Subscription-Userinfo": quota.to_header_value()}
return {}
def _yaml_response(content: str, request: Request, headers: dict[str, str] | None = None, filename: str | None = None) -> Response: def _yaml_response(content: str, request: Request, headers: dict[str, str] | None = None, filename: str | None = None) -> Response:
final_headers = { final_headers = {
"Content-Type": "text/yaml; charset=utf-8", "Content-Type": "text/yaml; charset=utf-8",
@@ -145,12 +155,32 @@ async def client_profile(client_type: str, request: Request, sources: str | None
@app.api_route(PUBLIC_PREFIX + "/bundle/{client_type}.yaml", methods=["GET", "HEAD"]) @app.api_route(PUBLIC_PREFIX + "/bundle/{client_type}.yaml", methods=["GET", "HEAD"])
async def bundle_profile(client_type: str, request: Request, sources: str | None = Query(default=None)) -> Response: async def bundle_profile(
client_type: str,
request: Request,
sources: str | None = Query(default=None),
force_refresh: bool = Query(default=False),
) -> Response:
client = app_config.clients.get(client_type) client = app_config.clients.get(client_type)
if client is None: if client is None:
raise HTTPException(status_code=404, detail="client config not found") raise HTTPException(status_code=404, detail="client config not found")
source_items = _resolve_sources(sources) source_items = _resolve_sources(sources)
cache_key = build_bundle_cache_key(client_type=client_type, source_names=[name for name, _ in source_items])
if not force_refresh:
cached = load_bundle_cache(
cache_dir=settings.bundle_cache_dir,
cache_key=cache_key,
ttl_seconds=settings.bundle_cache_ttl_seconds,
)
if cached is not None:
headers = {
"profile-update-interval": str(client.provider_interval),
"X-Sub-Provider-Bundle-Cache": "HIT",
}
headers.update(cached.headers)
return _yaml_response(content=cached.content, request=request, headers=headers, filename=f"bundle-{client_type}.yaml")
try: try:
snapshots = await build_source_snapshots(source_items) snapshots = await build_source_snapshots(source_items)
except Exception as exc: # noqa: BLE001 except Exception as exc: # noqa: BLE001
@@ -164,6 +194,15 @@ async def bundle_profile(client_type: str, request: Request, sources: str | None
snapshots=snapshots, snapshots=snapshots,
) )
) )
headers = {"profile-update-interval": str(client.provider_interval)} headers = {
headers.update(await _build_quota_headers(source_items)) "profile-update-interval": str(client.provider_interval),
"X-Sub-Provider-Bundle-Cache": "BYPASS" if force_refresh else "MISS",
}
headers.update(_quota_headers_from_snapshots(snapshots))
save_bundle_cache(
cache_dir=settings.bundle_cache_dir,
cache_key=cache_key,
content=content,
headers={key: value for key, value in headers.items() if key != "X-Sub-Provider-Bundle-Cache"},
)
return _yaml_response(content, request, headers=headers, filename=f"bundle-{client_type}.yaml") return _yaml_response(content, request, headers=headers, filename=f"bundle-{client_type}.yaml")

View File

@@ -0,0 +1,54 @@
from __future__ import annotations
import hashlib
import json
import time
from pathlib import Path
from pydantic import BaseModel, Field
class BundleCacheEntry(BaseModel):
content: str
headers: dict[str, str] = Field(default_factory=dict)
def build_bundle_cache_key(*, client_type: str, source_names: list[str]) -> str:
raw = f"{client_type}|{','.join(source_names)}"
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
def load_bundle_cache(*, cache_dir: Path, cache_key: str, ttl_seconds: int) -> BundleCacheEntry | None:
yaml_path = cache_dir / f"{cache_key}.yaml"
meta_path = cache_dir / f"{cache_key}.json"
if not yaml_path.is_file() or not meta_path.is_file():
return None
expires_at = meta_path.stat().st_mtime + ttl_seconds
if expires_at < time.time():
return None
try:
metadata = json.loads(meta_path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return None
content = yaml_path.read_text(encoding="utf-8")
headers = metadata.get("headers")
if not isinstance(headers, dict):
headers = {}
return BundleCacheEntry(content=content, headers={str(k): str(v) for k, v in headers.items()})
def save_bundle_cache(
*,
cache_dir: Path,
cache_key: str,
content: str,
headers: dict[str, str],
) -> Path:
cache_dir.mkdir(parents=True, exist_ok=True)
yaml_path = cache_dir / f"{cache_key}.yaml"
meta_path = cache_dir / f"{cache_key}.json"
yaml_path.write_text(content, encoding="utf-8")
meta_path.write_text(json.dumps({"headers": headers}, ensure_ascii=False, indent=2), encoding="utf-8")
return yaml_path

796
output/bundle-mihomo.yaml Normal file
View File

@@ -0,0 +1,796 @@
mode: rule
ipv6: true
log-level: info
mixed-port: 7890
socks-port: 7891
allow-lan: true
proxies:
- name: '[A] 剩余流量9.26 GB'
type: anytls
server: old1.hobbyx.cn
port: 33400
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 距离下次重置剩余18 天'
type: anytls
server: old1.hobbyx.cn
port: 33400
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 套餐到期2026-06-18'
type: anytls
server: old1.hobbyx.cn
port: 33400
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 666.beibei.cloud节点离线到官网重新导入订阅'
type: anytls
server: old1.hobbyx.cn
port: 33400
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港1'
type: anytls
server: old1.hobbyx.cn
port: 33401
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港2'
type: anytls
server: old1.hobbyx.cn
port: 33402
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港3'
type: anytls
server: old1.hobbyx.cn
port: 33403
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港4'
type: anytls
server: old1.hobbyx.cn
port: 33404
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港5'
type: anytls
server: old1.hobbyx.cn
port: 33405
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港6'
type: anytls
server: old1.hobbyx.cn
port: 33406
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港7'
type: anytls
server: old1.hobbyx.cn
port: 33407
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港8'
type: anytls
server: old1.hobbyx.cn
port: 33408
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 香港9'
type: anytls
server: old1.hobbyx.cn
port: 33409
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 新加坡1'
type: anytls
server: old1.hobbyx.cn
port: 33411
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 新加坡2'
type: anytls
server: old1.hobbyx.cn
port: 33412
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 新加坡3'
type: anytls
server: old1.hobbyx.cn
port: 33413
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 新加坡4'
type: anytls
server: old1.hobbyx.cn
port: 33414
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 新加坡5'
type: anytls
server: old1.hobbyx.cn
port: 33415
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 新加坡6'
type: anytls
server: old1.hobbyx.cn
port: 33416
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 台湾1-GPT'
type: anytls
server: old1.hobbyx.cn
port: 33421
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 台湾2-GPT'
type: anytls
server: old1.hobbyx.cn
port: 33422
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 台湾3-GPT'
type: anytls
server: old1.hobbyx.cn
port: 33423
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 台湾4-GPT'
type: anytls
server: old1.hobbyx.cn
port: 33424
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 日本1-GPT'
type: anytls
server: old2.hobbyx.cn
port: 33431
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 日本2-GPT'
type: anytls
server: old2.hobbyx.cn
port: 33432
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 日本3-GPT'
type: anytls
server: old2.hobbyx.cn
port: 33433
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 日本4-GPT'
type: anytls
server: old2.hobbyx.cn
port: 33434
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 美国1'
type: anytls
server: old2.hobbyx.cn
port: 33441
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 美国2'
type: anytls
server: old2.hobbyx.cn
port: 33442
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 美国3'
type: anytls
server: old2.hobbyx.cn
port: 33443
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 美国4'
type: anytls
server: old2.hobbyx.cn
port: 33444
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 马来西亚-3倍率'
type: anytls
server: old1.hobbyx.cn
port: 33452
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 英国-3倍率'
type: anytls
server: old1.hobbyx.cn
port: 33451
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 澳洲-3倍率'
type: anytls
server: old1.hobbyx.cn
port: 33455
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 土耳其-5倍率'
type: anytls
server: old1.hobbyx.cn
port: 33453
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
- name: '[A] 阿根廷-5倍率'
type: anytls
server: old2.hobbyx.cn
port: 33454
password: 8df6c5ba-b03e-459d-8c84-84acf9b689a9
udp: true
sni: s.hobbyx.cn
skip-cert-verify: false
proxy-groups:
- name: A 自动
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
proxies:
- '[A] 剩余流量9.26 GB'
- '[A] 距离下次重置剩余18 天'
- '[A] 套餐到期2026-06-18'
- '[A] 666.beibei.cloud节点离线到官网重新导入订阅'
- '[A] 香港1'
- '[A] 香港2'
- '[A] 香港3'
- '[A] 香港4'
- '[A] 香港5'
- '[A] 香港6'
- '[A] 香港7'
- '[A] 香港8'
- '[A] 香港9'
- '[A] 新加坡1'
- '[A] 新加坡2'
- '[A] 新加坡3'
- '[A] 新加坡4'
- '[A] 新加坡5'
- '[A] 新加坡6'
- '[A] 台湾1-GPT'
- '[A] 台湾2-GPT'
- '[A] 台湾3-GPT'
- '[A] 台湾4-GPT'
- '[A] 日本1-GPT'
- '[A] 日本2-GPT'
- '[A] 日本3-GPT'
- '[A] 日本4-GPT'
- '[A] 美国1'
- '[A] 美国2'
- '[A] 美国3'
- '[A] 美国4'
- '[A] 马来西亚-3倍率'
- '[A] 英国-3倍率'
- '[A] 澳洲-3倍率'
- '[A] 土耳其-5倍率'
- '[A] 阿根廷-5倍率'
- name: ♻️ 自动选择
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
proxies:
- '[A] 剩余流量9.26 GB'
- '[A] 距离下次重置剩余18 天'
- '[A] 套餐到期2026-06-18'
- '[A] 666.beibei.cloud节点离线到官网重新导入订阅'
- '[A] 香港1'
- '[A] 香港2'
- '[A] 香港3'
- '[A] 香港4'
- '[A] 香港5'
- '[A] 香港6'
- '[A] 香港7'
- '[A] 香港8'
- '[A] 香港9'
- '[A] 新加坡1'
- '[A] 新加坡2'
- '[A] 新加坡3'
- '[A] 新加坡4'
- '[A] 新加坡5'
- '[A] 新加坡6'
- '[A] 台湾1-GPT'
- '[A] 台湾2-GPT'
- '[A] 台湾3-GPT'
- '[A] 台湾4-GPT'
- '[A] 日本1-GPT'
- '[A] 日本2-GPT'
- '[A] 日本3-GPT'
- '[A] 日本4-GPT'
- '[A] 美国1'
- '[A] 美国2'
- '[A] 美国3'
- '[A] 美国4'
- '[A] 马来西亚-3倍率'
- '[A] 英国-3倍率'
- '[A] 澳洲-3倍率'
- '[A] 土耳其-5倍率'
- '[A] 阿根廷-5倍率'
- name: 🇭🇰 香港节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
proxies:
- '[A] 香港1'
- '[A] 香港2'
- '[A] 香港3'
- '[A] 香港4'
- '[A] 香港5'
- '[A] 香港6'
- '[A] 香港7'
- '[A] 香港8'
- '[A] 香港9'
- name: 🇨🇳 台湾节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
proxies:
- '[A] 台湾1-GPT'
- '[A] 台湾2-GPT'
- '[A] 台湾3-GPT'
- '[A] 台湾4-GPT'
- name: 🇸🇬 狮城节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
proxies:
- '[A] 新加坡1'
- '[A] 新加坡2'
- '[A] 新加坡3'
- '[A] 新加坡4'
- '[A] 新加坡5'
- '[A] 新加坡6'
- name: 🇯🇵 日本节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
proxies:
- '[A] 日本1-GPT'
- '[A] 日本2-GPT'
- '[A] 日本3-GPT'
- '[A] 日本4-GPT'
- name: 🇺🇲 美国节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 150
proxies:
- '[A] 美国1'
- '[A] 美国2'
- '[A] 美国3'
- '[A] 美国4'
- name: 🇰🇷 韩国节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
proxies:
- DIRECT
- name: 🎥 奈飞节点
type: select
proxies:
- DIRECT
- name: ☁️ 机场选择
type: select
proxies:
- ♻️ 自动选择
- A 自动
- DIRECT
- name: 🚀 手动切换
type: select
proxies:
- '[A] 剩余流量9.26 GB'
- '[A] 距离下次重置剩余18 天'
- '[A] 套餐到期2026-06-18'
- '[A] 666.beibei.cloud节点离线到官网重新导入订阅'
- '[A] 香港1'
- '[A] 香港2'
- '[A] 香港3'
- '[A] 香港4'
- '[A] 香港5'
- '[A] 香港6'
- '[A] 香港7'
- '[A] 香港8'
- '[A] 香港9'
- '[A] 新加坡1'
- '[A] 新加坡2'
- '[A] 新加坡3'
- '[A] 新加坡4'
- '[A] 新加坡5'
- '[A] 新加坡6'
- '[A] 台湾1-GPT'
- '[A] 台湾2-GPT'
- '[A] 台湾3-GPT'
- '[A] 台湾4-GPT'
- '[A] 日本1-GPT'
- '[A] 日本2-GPT'
- '[A] 日本3-GPT'
- '[A] 日本4-GPT'
- '[A] 美国1'
- '[A] 美国2'
- '[A] 美国3'
- '[A] 美国4'
- '[A] 马来西亚-3倍率'
- '[A] 英国-3倍率'
- '[A] 澳洲-3倍率'
- '[A] 土耳其-5倍率'
- '[A] 阿根廷-5倍率'
- DIRECT
- name: 📲 电报消息
type: select
proxies:
- 🚀 节点选择
- ♻️ 自动选择
- 🇸🇬 狮城节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- DIRECT
- name: 💬 Ai平台
type: select
proxies:
- 🚀 节点选择
- ♻️ 自动选择
- 🇺🇲 美国节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- DIRECT
- name: 📹 油管视频
type: select
proxies:
- 🚀 节点选择
- ♻️ 自动选择
- 🇸🇬 狮城节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- DIRECT
- name: 🎥 奈飞视频
type: select
proxies:
- 🎥 奈飞节点
- 🚀 节点选择
- ♻️ 自动选择
- 🇸🇬 狮城节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- DIRECT
- name: 🌍 国外媒体
type: select
proxies:
- 🚀 节点选择
- ♻️ 自动选择
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- DIRECT
- name: 📢 谷歌
type: select
proxies:
- 🚀 节点选择
- DIRECT
- 🇺🇲 美国节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: Ⓜ️ 微软Bing
type: select
proxies:
- DIRECT
- 🚀 节点选择
- 🇺🇲 美国节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: Ⓜ️ 微软云盘
type: select
proxies:
- DIRECT
- 🚀 节点选择
- 🇺🇲 美国节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: Ⓜ️ 微软服务
type: select
proxies:
- DIRECT
- 🚀 节点选择
- 🇺🇲 美国节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: 🍎 苹果服务
type: select
proxies:
- DIRECT
- 🚀 节点选择
- 🇺🇲 美国节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: 🎮 游戏平台
type: select
proxies:
- 🚀 节点选择
- DIRECT
- 🇺🇲 美国节点
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: 🎮 PT平台
type: select
proxies:
- 🚀 节点选择
- DIRECT
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🚀 手动切换
- name: 🎯 全球直连
type: select
proxies:
- DIRECT
- 🚀 节点选择
- ♻️ 自动选择
- name: 🛑 广告拦截
type: select
proxies:
- REJECT
- DIRECT
- name: 🍃 应用净化
type: select
proxies:
- REJECT
- DIRECT
- name: 🐟 漏网之鱼
type: select
proxies:
- DIRECT
- 🚀 节点选择
- ♻️ 自动选择
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🎥 奈飞节点
- 🚀 手动切换
- name: 🚀 节点选择
type: select
proxies:
- ☁️ 机场选择
- ♻️ 自动选择
- 🇭🇰 香港节点
- 🇨🇳 台湾节点
- 🇸🇬 狮城节点
- 🇯🇵 日本节点
- 🇺🇲 美国节点
- 🇰🇷 韩国节点
- 🎥 奈飞节点
- 🚀 手动切换
- DIRECT
rules:
- DOMAIN-KEYWORD,cloudflare,🚀 节点选择
- DOMAIN-KEYWORD,hetzner,🚀 节点选择
- DOMAIN-KEYWORD,github,🚀 节点选择
- DOMAIN-KEYWORD,google,🚀 节点选择
- DOMAIN-KEYWORD,vscode,🚀 节点选择
- DOMAIN-KEYWORD,telegram,🚀 节点选择
- DOMAIN-KEYWORD,youtube,🚀 节点选择
- DOMAIN-KEYWORD,whatsapp,🚀 节点选择
- DOMAIN-KEYWORD,dropbox,🚀 节点选择
- DOMAIN-KEYWORD,facebook,🚀 节点选择
- DOMAIN-KEYWORD,twitter,🚀 节点选择
- DOMAIN-KEYWORD,instagram,🚀 节点选择
- DOMAIN-KEYWORD,spotify,🚀 节点选择
- DOMAIN-KEYWORD,sci-hub,🚀 节点选择
- DOMAIN-KEYWORD,1e100,🚀 节点选择
- DOMAIN-SUFFIX,doubleclick.net,REJECT
- DOMAIN-SUFFIX,googlesyndication.com,REJECT
- DOMAIN-SUFFIX,adservice.google.com,REJECT
- DOMAIN-KEYWORD,omgmtaw,🍃 应用净化
- DOMAIN-SUFFIX,lan,🎯 全球直连
- DOMAIN-SUFFIX,local,🎯 全球直连
- DOMAIN-SUFFIX,localdomain,🎯 全球直连
- DOMAIN-SUFFIX,home.arpa,🎯 全球直连
- DOMAIN-SUFFIX,msftconnecttest.com,🎯 全球直连
- DOMAIN-SUFFIX,msftncsi.com,🎯 全球直连
- IP-CIDR,10.0.0.0/8,🎯 全球直连,no-resolve
- IP-CIDR,172.16.0.0/12,🎯 全球直连,no-resolve
- IP-CIDR,192.168.0.0/16,🎯 全球直连,no-resolve
- DOMAIN-KEYWORD,gmail,📢 谷歌
- DOMAIN-KEYWORD,google,📢 谷歌
- DOMAIN-SUFFIX,googleapis.com,📢 谷歌
- DOMAIN-SUFFIX,gstatic.com,📢 谷歌
- DOMAIN-SUFFIX,googlevideo.com,📢 谷歌
- DOMAIN-KEYWORD,bing,Ⓜ️ 微软Bing
- DOMAIN-KEYWORD,1drv,Ⓜ️ 微软云盘
- DOMAIN-KEYWORD,onedrive,Ⓜ️ 微软云盘
- DOMAIN-KEYWORD,skydrive,Ⓜ️ 微软云盘
- DOMAIN-KEYWORD,microsoft,Ⓜ️ 微软服务
- DOMAIN-SUFFIX,live.com,Ⓜ️ 微软服务
- DOMAIN-SUFFIX,windows.com,Ⓜ️ 微软服务
- DOMAIN-SUFFIX,microsoftonline.com,Ⓜ️ 微软服务
- DOMAIN-KEYWORD,apple,🍎 苹果服务
- DOMAIN-SUFFIX,icloud.com,🍎 苹果服务
- DOMAIN-SUFFIX,apple.com,🍎 苹果服务
- DOMAIN-KEYWORD,telegram,📲 电报消息,no-resolve
- DOMAIN-SUFFIX,t.me,📲 电报消息,no-resolve
- DOMAIN-SUFFIX,telegram.me,📲 电报消息,no-resolve
- DOMAIN-SUFFIX,telegram.org,📲 电报消息,no-resolve
- IP-CIDR,91.108.4.0/22,📲 电报消息,no-resolve
- IP-CIDR,91.108.8.0/21,📲 电报消息,no-resolve
- IP-CIDR,91.108.16.0/22,📲 电报消息,no-resolve
- IP-CIDR,91.108.56.0/22,📲 电报消息,no-resolve
- IP-CIDR,149.154.160.0/20,📲 电报消息,no-resolve
- DOMAIN-KEYWORD,openai,💬 Ai平台
- DOMAIN-KEYWORD,anthropic,💬 Ai平台
- DOMAIN-KEYWORD,claude,💬 Ai平台
- DOMAIN-SUFFIX,chatgpt.com,💬 Ai平台
- DOMAIN-SUFFIX,openai.com,💬 Ai平台
- DOMAIN-SUFFIX,oaistatic.com,💬 Ai平台
- DOMAIN-SUFFIX,oaiusercontent.com,💬 Ai平台
- DOMAIN-SUFFIX,anthropic.com,💬 Ai平台
- DOMAIN-SUFFIX,claude.ai,💬 Ai平台
- DOMAIN-KEYWORD,youtube,📹 油管视频
- DOMAIN-SUFFIX,youtu.be,📹 油管视频
- DOMAIN-SUFFIX,youtube.com,📹 油管视频
- DOMAIN-SUFFIX,ytimg.com,📹 油管视频
- DOMAIN-SUFFIX,googlevideo.com,📹 油管视频
- DOMAIN-KEYWORD,netflix,🎥 奈飞视频,no-resolve
- DOMAIN-KEYWORD,netflixdnstest,🎥 奈飞视频,no-resolve
- DOMAIN-KEYWORD,apiproxy-device-prod-nlb-,🎥 奈飞视频,no-resolve
- DOMAIN-KEYWORD,dualstack.apiproxy-,🎥 奈飞视频,no-resolve
- DOMAIN-SUFFIX,netflix.com,🎥 奈飞视频,no-resolve
- DOMAIN-SUFFIX,nflxvideo.net,🎥 奈飞视频,no-resolve
- DOMAIN-SUFFIX,nflximg.net,🎥 奈飞视频,no-resolve
- IP-CIDR,23.246.0.0/18,🎥 奈飞视频,no-resolve
- IP-CIDR,37.77.184.0/21,🎥 奈飞视频,no-resolve
- DOMAIN-KEYWORD,spotify,🌍 国外媒体
- DOMAIN-KEYWORD,tiktokcdn,🌍 国外媒体
- DOMAIN-KEYWORD,ttvnw,🌍 国外媒体
- DOMAIN-KEYWORD,jooxweb-api,🌍 国外媒体
- DOMAIN-KEYWORD,hbogoasia,🌍 国外媒体
- DOMAIN-KEYWORD,nowtv100,🌍 国外媒体
- DOMAIN-KEYWORD,rthklive,🌍 国外媒体
- DOMAIN-KEYWORD,bbc,🌍 国外媒体
- DOMAIN-KEYWORD,youtube,🌍 国外媒体
- DOMAIN-SUFFIX,open.spotify.com,🌍 国外媒体
- DOMAIN-KEYWORD,epicgames,🎮 游戏平台
- DOMAIN-KEYWORD,origin,🎮 游戏平台
- DOMAIN-KEYWORD,steam,🎮 游戏平台
- DOMAIN-KEYWORD,nintendo,🎮 游戏平台
- DOMAIN-SUFFIX,steampowered.com,🎮 游戏平台
- DOMAIN-SUFFIX,steamcontent.com,🎮 游戏平台
- DOMAIN-SUFFIX,steamusercontent.com,🎮 游戏平台
- DOMAIN-KEYWORD,btschool,🎮 PT平台
- DOMAIN-KEYWORD,hdkylin,🎮 PT平台
- DOMAIN-KEYWORD,cloudflare,🎮 PT平台
- DOMAIN-KEYWORD,hetzner,🎮 PT平台
- DOMAIN-KEYWORD,360buy,🎯 全球直连
- DOMAIN-KEYWORD,alicdn,🎯 全球直连
- DOMAIN-KEYWORD,alipay,🎯 全球直连
- DOMAIN-KEYWORD,baidu,🎯 全球直连
- DOMAIN-KEYWORD,bilibili,🎯 全球直连
- DOMAIN-KEYWORD,jd,🎯 全球直连
- DOMAIN-KEYWORD,qhimg,🎯 全球直连
- DOMAIN-KEYWORD,xiaomi,🎯 全球直连
- 10.0.0.0/8,🎯 全球直连,no-resolve
- 172.16.0.0/12,🎯 全球直连,no-resolve
- 192.168.0.0/16,🎯 全球直连,no-resolve
- MATCH,🚀 节点选择