diff --git a/README.md b/README.md index 30f3a474..a035c4b5 100644 --- a/README.md +++ b/README.md @@ -203,11 +203,13 @@ script: shortcuts: quic: 'network == "udp" and dst_port == 443' privacy: '"analytics" in host or "adservice" in host or "firebase" in host or "safebrowsing" in host or "doubleclick" in host' - + BilibiliUdp: | + network == "udp" and match_provider("geosite:bilibili") rules: - # rule SCRIPT + # rule SCRIPT shortcuts - SCRIPT,quic,REJECT # Disable QUIC, same as rule "DST-PORT,443,REJECT,udp" - SCRIPT,privacy,REJECT + - SCRIPT,BilibiliUdp,REJECT # same as rule "GEOSITE,bilibili,REJECT,udp" # network condition for all rules - DOMAIN-SUFFIX,example.com,DIRECT,tcp diff --git a/component/script/clash_module.c b/component/script/clash_module.c index 8a7cb580..fa25c702 100644 --- a/component/script/clash_module.c +++ b/component/script/clash_module.c @@ -683,8 +683,9 @@ int call_shortcut(PyObject *shortcut_fn, PyObject *args; PyObject *result; - args = Py_BuildValue("{s:O, s:s, s:s, s:s, s:s, s:s, s:H, s:s, s:H}", + args = Py_BuildValue("{s:O, s:s, s:s, s:s, s:s, s:s, s:s, s:H, s:s, s:H}", "ctx", clash_context, + "type", type, "network", network, "process_name", process_name, "process_path", process_path, diff --git a/config/config.go b/config/config.go index 3fef5b67..7b288237 100644 --- a/config/config.go +++ b/config/config.go @@ -881,6 +881,18 @@ class ClashTime: time = ClashTime() +class ClashRuleProvider: + def __init__(self, c, m): + self.__ctx = c + self.__metadata = m + + def match_provider(self, providerName): + try: + return self.__ctx.rule_providers[providerName].match(self.__metadata) + except Exception as err: + self.__ctx.log("[SCRIPT] shortcuts error: rule provider {0} not found".format(err)) + return False + ` content += mainCode + "\n\n" @@ -889,10 +901,29 @@ time = ClashTime() v = cleanPyKeywords(v) v = strings.TrimSpace(v) if v == "" { - return fmt.Errorf("initialized rule SCRIPT failure, shortcut [%s] code invalid syntax", k) + return nil, fmt.Errorf("initialized rule SCRIPT failure, shortcut [%s] code syntax invalid", k) } - content += "def " + strings.ToLower(k) + "(ctx, network, process_name, process_path, host, src_ip, src_port, dst_ip, dst_port):\n return " + v + "\n\n" + content += "def " + strings.ToLower(k) + "(ctx, type, network, process_name, process_path, host, src_ip, src_port, dst_ip, dst_port):" + if strings.Contains(v, "match_provider") { + content += ` + metadata = { + "type": type, + "network": network, + "process_name": process_name, + "process_path": process_path, + "host": host, + "src_ip": src_ip, + "src_port": src_port, + "dst_ip": dst_ip, + "dst_port": dst_port + } + crp = ClashRuleProvider(ctx, metadata) + match_provider = crp.match_provider` + } + content += ` + now = time.now() + return ` + v + "\n\n" } err := os.WriteFile(C.Path.Script(), []byte(content), 0o644)