配置文件预处理#

版本要求#

0.10.1 版本更新后,支持使用 JavaScript 对下载后的配置文件进行预处理

0.11.10 版本更新后,支持使用 YAML 对下载后配置文件进行简单预处理

简便方法(YAML)#

如果需要对下载地址为`https://example.com/profile.yaml`的配置文件进行预处理,操作如下:

  1. 进入 Settings 界面

  2. 滚动至 Profiles 栏

  3. 点击 Parsers 右侧 Edit 打开编辑器,填入以下内容:

parsers:
  - url: https://example.com/profile.yaml
    yaml:
      prepend-rules:
        - DOMAIN,test.com,DIRECT # rules最前面增加一个规则
      append-proxies:
        - name: test # proxies最后面增加一个服务
          type: http
          server: 123.123.123.123
          port: 456
  1. 点击编辑器右下角保存按钮

当配置文件触发刷新(含自动更新)时,CFW 会读取 yaml 字段并插入/合并到原配置。

参数说明#

值类型

操作

append-rules

数组

prepend-rules

数组

append-proxies

数组

prepend-proxies

数组

append-proxy-groups

数组

prepend-proxy-groups

数组

mix-proxy-providers

对象

mix-rule-providers

对象

mix-object

对象

commands

数组

Commands 使用方法(beta)#

commands 是一组简单的命令,作为上面操作的补充

例子:

commands:
  - dns.enable=false # 命令1
  - proxy-groups.0.proxies.2+DIRECT # 命令2

每个命令可以被分为三个部分,分别是:定位+操作+设定值

命令 1 中,定位为 dns.enable,操作为 =,设定值为 false

命令 2 中,定位为 proxy-groups.0.proxies.2,操作为 +,设定值为 DIRECT

定位#

定位中每个层级以 . 分割,数组下标从 0 开始。命令 2 中 proxy-groups.0 表示第 1 个策略组,.proxies 表示其 proxies 属性,.proxies.2 表示该属性的第 3 个位置。

若用名称定位,可使用 nameproxiesproxy-groups 中每项均有 name。例如已定义名为 debug 的节点,则其 udp 的定位为 proxies.(debug).udp。名称两侧 () 用于识别;若节点名不含 +.= 可省略。

操作#

目前支持三种操作:

  • =:覆盖

  • +:插入

  • -:删除

命令 1 中,=`表示将`dns`下`enable`的值覆盖为`false

命令 2 中,+`表示在定位的策略组中的`proxies`数组中添加一个名为`DIRECT`的值,原本其他值被向后移动 1 位。如果此处改成`=,则会覆盖原来第一个值

设定值#

设定值是用于插入或覆盖的值,如果操作是`-`,则此值可有可无,例如:

commands:
  - proxies.0- # 命令3

此处可以将配置文件`proxies`的第 1 个节点删除

如果设定值为纯数字,则会被识别为整数,为`true|false`则识别为布尔类型,如果 JSON 编码通过则识别为对象

v0.13.7 版本更新后,支持 3 个内置值用于设置策略组节点:[]proxyNames[]groupNames[]shuffledProxyNames,并支持用正则过滤节点。示例:

yaml:
  prepend-proxy-groups:
    - name: myGroup # 建立新策略组
      type: fallback
      url: "http://www.gstatic.com/generate_204"
      interval: 300
      proxies:
        - DIRECT

  commands:
    - proxy-groups.myGroup.proxies=[]proxyNames|HK # 向策略组添加所有定义的节点名,并按“HK”正则表达式过滤

进阶方法(JavaScript)#

如果需要对下载地址为`https://example.com/profile.yaml`的配置文件进行预处理,操作如下:

  1. 进入 Settings 界面

  2. 滚动至 Profiles 栏

  3. 点击 Parsers 右侧 Edit 打开编辑器,填入以下内容:

parsers:
  - url: https://example.com/profile.yaml
    code: |
      module.exports.parse = async (raw, { axios, yaml, notify, console }, { name, url, interval, selected }) => {
        const obj = yaml.parse(raw)
        return yaml.stringify(obj)
      }
  1. 点击编辑器右下角保存按钮

当配置文件触发刷新(包括自动更新)时,CFW 会调用此方法对下载的配置文件内容进行处理,再写入本地文件中

当然,parsers 也支持使用路径引入代码:

parsers:
  - url: https://example.com/profile.yaml
    file: "C:/Users/cfw/parser.js"

小技巧

使用文件时,允许调用该文件目录下的 node_modules 模块。

版本 0.20.10 开始支持从远端获取。示例:

parsers:
  - url: https://example.com/profile.yaml
    remote:
      url: https://gist.githubusercontent.com/Fndroid/40e6117252f794aa629b875aa1ecadea/raw/d1ba6d230746c9d2ecfbef211c52fd9a567a781e/parser.js
      cache: true # 默认为false,指示是否对重复下载此预处理代码使用缓存

小心

注意

使用远端配置请选择可信的代码提供者;若不信任提供者,可从远端拷贝代码后使用 code 填入,勿用 remote 引入。

参数说明#

CFW 调用用户定义的 parse 方法时会传入 3 个参数:配置文件文本内容工具类对象/方法配置文件元数据

配置文件文本内容#

raw 是一个字符串,一般需要用 yaml 库解析成 JavaScript 对象

工具类对象/方法#

包括:

  • axios:网络请求框架,GitHub(opens new window)

  • yaml:yaml 框架,GitHub(opens new window)

  • notify:发出系统通知方法,签名为 function notify(title:string, message:string, silent:bool)

  • console:日志输出至文件,方便调试,在 Settings 界面中 Parser 设置下方打开

  • homeDir:Home Directory 目录

小技巧

除了以上工具类,在使用 .js 文件时,也可通过 npm 引入第三方模块。

配置文件元数据#

元数据为 JavaScript 对象,包括:

  • name:名称

  • url:下载地址

  • interval:更新周期

  • selected:策略组选择缓存,数组

  • mode:模式缓存

小技巧

元数据在配置文件首次下载时只有 url 参数。

返回说明#

parse 方法需返回一个字符串,CFW 会将返回的字符串写入对应配置文件。

多处理器及正则匹配#

正则匹配#

上面例子中,使用 url 匹配配置文件地址。若一个处理器需处理多个配置文件,可用正则匹配,使用关键字 reg。示例:

parsers:
  - reg: ^https://test\.com/.+$ # 正则匹配域名
    yaml:
      prepend-rules:
        - DOMAIN,test.com,DIRECT

多处理器#

parser 定义的数组支持多个处理器从上至下按顺序执行。示例:

parsers:
  - reg: https://test.com.+$ # 第一个执行的parser
    file: "C:/Users/cfw/parser.yaml"
  - url: https://example.com/profile.yaml # 对上一个parser执行的结果进行处理
    file: "C:/Users/cfw/parser.js"

小技巧

file 同时支持 yaml 及 js 格式的文件。

使用案例#

向本地配置文件添加订阅信息#

  1. 准备一个本地配置文件的副本,记下文件名和路径。以下用 myprofile.yml 指代此文件名,用 C:\...\myprofile.yml 指代此文件路径。

备注

配置完成后,该副本将作为 CFW 的订阅源。对配置的**非临时**修改需在此副本中编辑,修改后执行订阅更新。移动或重命名此文件后,须在 CFW 中同步修改对应配置。

小技巧

此处使用 CFW 创建的配置文件本身而非副本作为订阅源虽可实现相同功能,但无法保证运行可靠性,如无特殊情况不建议这样使用。

  1. 准备一个包含订阅信息 subscription-userinfo (规范参考)的订阅链接。以下用 https://example.com/subscription_url 指代此链接。

小技巧

可使用 curl -I 'https://example.com/subscription_url' 检查订阅链接是否包含订阅信息。

  1. 修改 CFW 中的配置文件选项,在 URL 中填写副本文件的本地映射地址 file:///C:\...\myprofile.yml。保存后执行订阅更新并确保无报错。

  2. 添加对应的预处理脚本,并确保能匹配到该配置文件。示例:

parsers: # array
  - reg: "myprofile.yml"
    code: |
      module.exports.parse = async (raw, { axios, yaml, notify, console }) => {
        raw = raw.replace(/# upload=\d*; download=\d*; total=\d*; expire=\d*;*\n/gm,'')
        const url = 'https://example.com/subscription_url'
        let { headers:{"subscription-userinfo": si = ""}={}, status } = await axios.head(url)
        si = si.replace(/;*$/g,'')
        if (status === 200 && si) {
          return `# ${si};\n${raw}`
        }
        return raw
      }
  1. 执行订阅更新,配置文件模块中出现订阅信息即说明配置成功。

小技巧

配置完成后可自行设置自动更新选项。