From 167154481cda86b45554fdb055dc8b6373de6d29 Mon Sep 17 00:00:00 2001 From: riglen Date: Wed, 1 Apr 2026 16:19:08 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + app/config.py | 2 + app/main.py | 47 ++- app/services/bundle_cache.py | 54 +++ output/bundle-mihomo.yaml | 796 +++++++++++++++++++++++++++++++++++ 5 files changed, 897 insertions(+), 4 deletions(-) create mode 100644 app/services/bundle_cache.py create mode 100644 output/bundle-mihomo.yaml diff --git a/README.md b/README.md index 7b07bd4..053ca85 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,8 @@ HEAD //bundle/stash.yaml?sources=airport-a,airport-b - 服务端把节点、策略组、规则全部展开到一个 YAML 里 - 适合想直接给 Mihomo Party / Clash Party / Stash 一个最终链接的场景 - 响应头同样只取第一个源的 `Subscription-Userinfo` +- 生成后的完整 YAML 会缓存到 `output/bundle-cache/`,默认 600 秒内直接返回缓存 +- 可用 `force_refresh=true` 强制跳过缓存并覆盖旧缓存文件 --- diff --git a/app/config.py b/app/config.py index 1fe6163..dd7182b 100644 --- a/app/config.py +++ b/app/config.py @@ -23,11 +23,13 @@ class Settings(BaseSettings): public_base_url: str | None = None request_timeout_seconds: float = 20.0 cache_ttl_seconds: int = 900 + bundle_cache_ttl_seconds: int = 600 max_proxy_name_length: int = 80 default_user_agent: str = "sub-provider/0.2" sources_file: Path = CONFIG_DIR / "sources.yaml" rules_dir: Path = CONFIG_DIR / "rules" + bundle_cache_dir: Path = ROOT_DIR / "output" / "bundle-cache" model_config = SettingsConfigDict( env_file=ROOT_DIR / ".env", diff --git a/app/main.py b/app/main.py index d58cba9..e78e350 100644 --- a/app/main.py +++ b/app/main.py @@ -4,7 +4,8 @@ from fastapi import FastAPI, HTTPException, Query, Request from fastapi.responses import Response 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.profiles import build_bundle_profile, build_thin_profile, dump_yaml 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 +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: final_headers = { "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"]) -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) if client is None: raise HTTPException(status_code=404, detail="client config not found") 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: snapshots = await build_source_snapshots(source_items) except Exception as exc: # noqa: BLE001 @@ -164,6 +194,15 @@ async def bundle_profile(client_type: str, request: Request, sources: str | None snapshots=snapshots, ) ) - headers = {"profile-update-interval": str(client.provider_interval)} - headers.update(await _build_quota_headers(source_items)) + headers = { + "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") diff --git a/app/services/bundle_cache.py b/app/services/bundle_cache.py new file mode 100644 index 0000000..0b3224a --- /dev/null +++ b/app/services/bundle_cache.py @@ -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 diff --git a/output/bundle-mihomo.yaml b/output/bundle-mihomo.yaml new file mode 100644 index 0000000..1eb72bd --- /dev/null +++ b/output/bundle-mihomo.yaml @@ -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,🚀 节点选择