toml::format() serializes string values with surrounding quotes, so
`extra = { url = "http://..." }` produced `url: '"http://..."'` in the
Clash output. Use the raw string for string values and keep
toml::format() for other types.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Clash hysteria2 proxy with `up: null` / `down: null` (or `~`) passed the
IsDefined() check, and the fallback `as<std::string>()` turned the null node
into the string "null". Surge output then got `download-bandwidth=null`,
Clash output `up: "null"`, and sing-box failed with a 500 from
std::stoi("null").
Parse the pinSHA256 query parameter from hysteria2 URIs into the node
fingerprint, emit it as the fingerprint field in Clash output, read it
back from Clash YAML and sing-box certificate_public_key_sha256 input,
and round-trip it back to pinSHA256 when exporting the URI.
Add support for an optional `format` field in external ruleset
definitions so Clash/Mihomo rule-providers can declare their source
format explicitly.
Previously, `type = "clash-domain"`, `type = "clash-ipcidr"`, and
`type = "clash-classic"` only described the provider behavior, while the
provider format was implicitly left as the Clash/Mihomo default YAML
format. This worked for YAML rule-provider files with a top-level
`payload` field, but failed for valid text-format providers such as
domainset files that contain plain domain entries without a `payload`
wrapper.
This change allows users to configure:
[[rulesets]]
group = "Apple CDN"
ruleset = "https://ruleset.skk.moe/Clash/domainset/apple_cdn.txt"
type = "clash-domain"
format = "text"
The generated rule-provider will now include:
format: text
Supported values are:
yaml
text
mrs
The new `format` option is only accepted for Clash/Mihomo native
rule-provider types:
clash-domain
clash-ipcidr
clash-classic
For compatibility, omitting `format` preserves the previous behavior and
does not emit a `format` field, allowing Clash/Mihomo to continue using
its default YAML format.
Validation is also added to reject unsupported format values and to
prevent `format = "mrs"` from being used with `clash-classic`, since MRS
rule-sets only support domain and IP-CIDR behaviors.
split(configs[i], "=") splits on ALL '=' characters, truncating
SS 2022-blake3 passwords that contain base64 padding (==) +
colon-delimited IMK. Replaced with split_first() which splits
only on the first '=', keeping the full password intact.
- Added split_first() utility to string.h/string.cpp
- Replaced all 15 key=value split() calls in subparser.cpp
- Verified with Docker build + Surge/Clash output test