Auto calculate json focus

This commit is contained in:
Fangliding
2026-09-17 01:42:16 +08:00
parent d8d0e6455e
commit e42da10dbe
106 changed files with 249 additions and 259 deletions
-105
View File
@@ -1,105 +0,0 @@
# Validate that lines covered by // [!code focus:N] form valid JSONC when wrapped in {}.
import re
import sys
from pathlib import Path
FOCUS_RE = re.compile(r"//\s*\[!code focus:(\d+)\]")
CODEBLOCK_START = re.compile(r"^```json\w*")
CODEBLOCK_END = re.compile(r"^```\s*$")
def strip_jsonc_comments(text: str) -> str:
result = []
for line in text.splitlines():
stripped = line.lstrip()
if stripped.startswith("//"):
continue
if "//" in line:
in_str = False
escape = False
cut = -1
for i, ch in enumerate(line):
if escape:
escape = False
continue
if ch == "\\":
escape = True
continue
if ch == '"':
in_str = not in_str
if not in_str and line[i : i + 2] == "//":
cut = i
break
if cut >= 0:
line = line[:cut]
result.append(line)
return "\n".join(result)
def validate_jsonc(fragment: str) -> str | None:
import json
cleaned = strip_jsonc_comments(fragment)
wrapped = "{\n" + cleaned + "\n}"
try:
json.loads(wrapped)
return None
except json.JSONDecodeError as e:
return str(e)
def check_file(path: Path) -> list[str]:
errors = []
lines = path.read_text(encoding="utf-8").splitlines()
in_json_block = False
for i, line in enumerate(lines):
stripped = line.strip()
if CODEBLOCK_START.match(stripped):
in_json_block = True
continue
if CODEBLOCK_END.match(stripped):
in_json_block = False
continue
if not in_json_block:
continue
m = FOCUS_RE.search(line)
if not m:
continue
n = int(m.group(1))
start = i + 1
end = min(start + n, len(lines))
fragment = "\n".join(lines[start:end])
err = validate_jsonc(fragment)
if err:
rel = path.as_posix()
errors.append(f" {rel}:{i + 1} focus:{n} {err}")
return errors
def main() -> int:
docs_root = Path.cwd()
all_errors: list[str] = []
for md in sorted(docs_root.rglob("*.md")):
text = md.read_text(encoding="utf-8")
if "[!code focus:" not in text:
continue
errs = check_file(md)
all_errors.extend(errs)
if all_errors:
print(f"Found {len(all_errors)} invalid focus block(s):\n")
for e in all_errors:
print(e)
return 1
print("All focus blocks are valid JSONC.")
return 0
if __name__ == "__main__":
sys.exit(main())
-6
View File
@@ -3,12 +3,6 @@ name: Post Check
on: [push, pull_request]
jobs:
check-focus:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: python .github/check-scripts/check_code_focus.py
check-json:
runs-on: ubuntu-latest
steps:
+7 -4
View File
@@ -1,6 +1,7 @@
import { defineConfig } from "vitepress"
import llmstxt from "vitepress-plugin-llms"
import { MermaidMarkdown, MermaidPlugin } from "vitepress-plugin-mermaid"
import { fieldFocusPlugin } from "./plugins/field-focus.mts"
import { nav as nav } from "./menus/nav.mts"
import { nav as nav_en } from "./menus/nav.en.mts"
@@ -52,8 +53,9 @@ export default defineConfig({
attrs: { left: "{:" },
config(md) {
config(md: { use: Function }) {
md.use(MermaidMarkdown)
md.use(fieldFocusPlugin)
}
},
vite: {
@@ -80,7 +82,7 @@ export default defineConfig({
detailedView: true,
miniSearch: {
options: {
tokenize: (str) => str.split(/[\s,,。、]+/)
tokenize: (str: string) => str.split(/[\s,,。、]+/)
}
},
translations: {
@@ -163,7 +165,7 @@ export default defineConfig({
options: {
miniSearch: {
options: {
tokenize: (str) =>
tokenize: (str: string) =>
str
.split(/[\s.,;!?'"(){}[\]\-_+=&%$#@~`^<>|\\]+/)
.filter(Boolean)
@@ -235,7 +237,8 @@ export default defineConfig({
options: {
miniSearch: {
options: {
tokenize: (str) => str.match(/[\p{L}\p{N}]+/gu) ?? []
tokenize: (str: string) =>
str.match(/[\p{L}\p{N}]+/gu) ?? []
}
},
translations: {
+98
View File
@@ -0,0 +1,98 @@
// .vitepress/plugins/field-focus.mts
//
// markdown-it plugin: replaces // [!field focus] with // [!code focus:N]
// inside ```json fenced blocks. N is auto-calculated by bracket-matching
// the JSON field that starts on the very next line.
const FIELD_FOCUS = /^(\s*)\/\/\s*\[!field\s+focus\]\s*$/
export function fieldFocusPlugin(md: {
core: { ruler: { push: Function } }
}): void {
md.core.ruler.push(
"field_focus",
(state: {
tokens: { type: string; info: string; content: string }[]
}) => {
for (const token of state.tokens) {
if (token.type !== "fence") continue
if (!/^json\b/.test(token.info.trim())) continue
token.content = rewriteFieldFocus(token.content)
}
}
)
}
/** Scan a code-block string, replacing every `// [!field focus]` line. */
function rewriteFieldFocus(src: string): string {
const lines = src.split("\n")
const out: string[] = []
for (let i = 0; i < lines.length; i++) {
const m = FIELD_FOCUS.exec(lines[i])
if (!m) {
out.push(lines[i])
continue
}
const n = countFieldSpan(lines, i + 1)
out.push(`${m[1]}// [!code focus:${n}]`)
}
return out.join("\n")
}
/**
* Starting from `lines[start]`, find the first `{` or `[` (outside strings
* and // comments), then count lines until the matching `}` or `]`.
* Returns 1 when the line contains only a simple value (no bracket).
*/
function countFieldSpan(lines: string[], start: number): number {
if (start >= lines.length) return 1
let depth = 0
let started = false
for (let i = start; i < lines.length; i++) {
const line = lines[i]
let inStr = false
let skip = false
for (let j = 0; j < line.length; j++) {
if (skip) {
skip = false
continue
}
const ch = line[j]
if (inStr) {
if (ch === "\\") {
skip = true
continue
}
if (ch === '"') inStr = false
continue
}
if (ch === '"') {
inStr = true
continue
}
// JSONC line comment — skip rest of line
if (ch === "/" && j + 1 < line.length && line[j + 1] === "/") break
if (ch === "{" || ch === "[") {
depth++
started = true
} else if (ch === "}" || ch === "]") {
depth--
}
}
if (started && depth <= 0) return i - start + 1
}
// No brackets found → simple value field, 1 line
return started ? lines.length - start : 1
}
+1 -1
View File
@@ -133,7 +133,7 @@ FakeDNS 本质上是一个 [DNS 服务器](./dns.md#serverobject),能够与任
"inbounds": [
{
// ...
// [!code focus:5]
// [!field focus]
"sniffing": {
"enabled": true,
"destOverride": ["fakedns"], // 使用 "fakedns",或与其它 sniffer 搭配使用
+1 -1
View File
@@ -30,7 +30,7 @@ HTTP 协议。
{
// ...
"protocol": "http",
// [!code focus:10]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -14,7 +14,7 @@
{
// ...
"protocol": "hysteria",
// [!code focus:10]
// [!field focus]
"settings": {
"version": 2,
"users": [
+1 -1
View File
@@ -32,7 +32,7 @@ Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,
{
// ...
"protocol": "shadowsocks",
// [!code focus:13]
// [!field focus]
"settings": {
"network": "tcp,udp",
"method": "aes-256-gcm",
+1 -1
View File
@@ -18,7 +18,7 @@
{
// ...
"protocol": "socks",
// [!code focus:12]
// [!field focus]
"settings": {
"auth": "noauth",
"users": [
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "trojan",
// [!code focus:14]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@ Linux 可选使用该环境变量传入 TUN FD 以进行某些轻量化或非特
{
// ...
"protocol": "tun",
// [!code focus:10]
// [!field focus]
"settings": {
"name": "utun10",
"desc": "Wintun",
+1 -1
View File
@@ -12,7 +12,7 @@ Tunnel(隧道),旧称 dokodemo-door(任意门),可以监听数个本
{
// ...
"protocol": "tunnel",
// [!code focus:12]
// [!field focus]
"settings": {
"allowedNetwork": "tcp",
"rewriteAddress": "8.8.8.8",
+1 -1
View File
@@ -14,7 +14,7 @@ VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部
{
// ...
"protocol": "vless",
// [!code focus:18]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@ VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在
{
// ...
"protocol": "vmess",
// [!code focus:12]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "wireguard",
// [!code focus:14]
// [!field focus]
"settings": {
"secretKey": "SERVER_PRIVATE_KEY",
"peers": [
+1 -1
View File
@@ -12,7 +12,7 @@ Blackhole(黑洞)是一个出站数据协议,它会阻碍所有数据的
{
// ...
"protocol": "blackhole",
// [!code focus:5]
// [!field focus]
"settings": {
"response": {
"type": "none"
+1 -1
View File
@@ -16,7 +16,7 @@ DNS 是一个出站协议,用于接收由 routing 送入的 DNS 查询,并
{
// ...
"protocol": "dns",
// [!code focus:18]
// [!field focus]
"settings": {
"rewriteNetwork": "udp",
"rewriteAddress": "1.1.1.1",
+1 -1
View File
@@ -16,7 +16,7 @@ Freedom 是一个直连出站协议,通常也是流量的终结点:它接收
{
// ...
"protocol": "freedom",
// [!code focus:28]
// [!field focus]
"settings": {
"redirect": "127.0.0.1:3366",
"userLevel": 0,
+1 -1
View File
@@ -20,7 +20,7 @@ HTTP 协议。
{
// ...
"protocol": "http",
// [!code focus:12]
// [!field focus]
"settings": {
"address": "192.168.108.1",
"port": 3128,
+1 -1
View File
@@ -18,7 +18,7 @@ Hysteria 协议的客户端实现。
{
// ...
"protocol": "hysteria",
// [!code focus:5]
// [!field focus]
"settings": {
"version": 2,
"address": "192.168.108.1",
+1 -1
View File
@@ -27,7 +27,7 @@ Loopback 是一个环回出站,用于将流量重新送回 routing 处理,
{
// ...
"protocol": "loopback",
// [!code focus:4]
// [!field focus]
"settings": {
"inboundTag": "TagUseAsInbound",
"sniffing": {}
+1 -1
View File
@@ -32,7 +32,7 @@ Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,
{
// ...
"protocol": "shadowsocks",
// [!code focus:8]
// [!field focus]
"settings": {
"email": "love@xray.com",
"address": "127.0.0.1",
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "socks",
// [!code focus:8]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 1234,
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "trojan",
// [!code focus:7]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 1234,
+1 -1
View File
@@ -14,7 +14,7 @@ VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部
{
// ...
"protocol": "vless",
// [!code focus:9]
// [!field focus]
"settings": {
"address": "example.com",
"port": 443,
+1 -1
View File
@@ -16,7 +16,7 @@ VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在
{
// ...
"protocol": "vmess",
// [!code focus:8]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 37192,
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "wireguard",
// [!code focus:20]
// [!field focus]
"settings": {
"secretKey": "CLIENT_PRIVATE_KEY",
"address": ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"],
+1 -1
View File
@@ -24,7 +24,7 @@
"outbounds": [
{
// ...
// [!code focus:18]
// [!field focus]
"streamSettings": {
// 传输方式
"method": "raw",
+15 -15
View File
@@ -15,7 +15,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
{
// ...
"streamSettings": {
// [!code focus:33]
// [!field focus]
"finalmask": {
"tcp": [
{
@@ -62,7 +62,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"finalmask": {
// [!code focus:6]
// [!field focus]
"tcp": [
{
"type": "",
@@ -88,7 +88,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"type": "header-custom",
// [!code focus:35]
// [!field focus]
"settings": {
"clients": [
[
@@ -142,7 +142,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"type": "fragment",
// [!code focus:6]
// [!field focus]
"settings": {
"packets": "tlshello",
"lengths": ["3-5", "6-8", "10-20"],
@@ -175,7 +175,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"type": "sudoku",
// [!code focus:10]
// [!field focus]
"settings": {
"password": "",
"ascii": "",
@@ -198,7 +198,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"finalmask": {
// [!code focus:6]
// [!field focus]
"udp": [
{
"type": "",
@@ -226,7 +226,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"type": "header-custom",
// [!code focus:18]
// [!field focus]
"settings": {
"client": [
{
@@ -261,7 +261,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"type": "mkcp-legacy",
// [!code focus:4]
// [!field focus]
"settings": {
"header": "", // dns dtls srtp utp wechat wireguard
"value": "" // password domain
@@ -292,7 +292,7 @@ FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对
```json
{
"type": "noise",
// [!code focus:12]
// [!field focus]
"settings": {
"reset": "30-60",
"noise": [
@@ -327,7 +327,7 @@ Salamander 混淆。(来自 Hysteria2
```json
{
"type": "salamander",
// [!code focus:4]
// [!field focus]
"settings": {
"password": "your-password",
"packetSize": "512-1200"
@@ -348,7 +348,7 @@ Salamander 混淆。(来自 Hysteria2
```json
{
"type": "sudoku",
// [!code focus:10]
// [!field focus]
"settings": {
"password": "",
"ascii": "",
@@ -379,7 +379,7 @@ Salamander 混淆。(来自 Hysteria2
```json
{
"type": "xdns",
// [!code focus:4]
// [!field focus]
"settings": {
"domains": ["t.example.com"],
"resolvers": ["t.example.com+udp://8.8.8.8:53"]
@@ -398,7 +398,7 @@ Salamander 混淆。(来自 Hysteria2
```json
{
"type": "xicmp",
// [!code focus:4]
// [!field focus]
"settings": {
"dgram": false, // optional
"ips": [] // optional
@@ -417,7 +417,7 @@ Salamander 混淆。(来自 Hysteria2
```json
{
"type": "realm",
// [!code focus:8]
// [!field focus]
"settings": {
"url": "realm://public@xxx/your-realm-name",
"stunServers": [
@@ -442,7 +442,7 @@ Salamander 混淆。(来自 Hysteria2
```json
{
"finalmask": {
// [!code focus:19]
// [!field focus]
"quicParams": {
"congestion": "force-brutal",
"bbrProfile": "standard",
+1 -1
View File
@@ -48,7 +48,7 @@ gRPCHTTP/2)内置多路复用,不建议使用 gRPC 与 HTTP/2 时启用 m
// ...
"streamSettings": {
"method": "grpc",
// [!code focus:10]
// [!field focus]
"grpcSettings": {
"authority": "grpc.example.com",
"serviceName": "name",
+1 -1
View File
@@ -19,7 +19,7 @@
// ...
"streamSettings": {
"method": "httpupgrade",
// [!code focus:8]
// [!field focus]
"httpupgradeSettings": {
"acceptProxyProtocol": false,
"path": "/",
+1 -1
View File
@@ -14,7 +14,7 @@ Hysteria2 的底层 QUIC 传输的 Xray 实现,通常搭配 hysteria[出站](.
// ...
"streamSettings": {
"method": "hysteria",
// [!code focus:17]
// [!field focus]
"hysteriaSettings": {
"version": 2,
"auth": "password",
+1 -1
View File
@@ -20,7 +20,7 @@ mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP
// ...
"streamSettings": {
"method": "mkcp",
// [!code focus:9]
// [!field focus]
"kcpSettings": {
"mtu": 1350,
"tti": 20,
+1 -1
View File
@@ -16,7 +16,7 @@
// ...
"streamSettings": {
"method": "raw",
// [!code focus:6]
// [!field focus]
"rawSettings": {
"acceptProxyProtocol": false,
"header": {
+1 -1
View File
@@ -26,7 +26,7 @@ REALITY 只是修改了 TLS,客户端的实现只需要轻度修改完全随
// ...
"streamSettings": {
"security": "reality",
// [!code focus:30]
// [!field focus]
"realitySettings": {
// 入站(服务端)配置
"show": false,
+1 -1
View File
@@ -15,7 +15,7 @@ Sockopt 用于配置底层网络行为。
{
// ...
"streamSettings": {
// [!code focus:21]
// [!field focus]
"sockopt": {
"mark": 0,
"tcpMaxSeg": 1440,
+1 -1
View File
@@ -18,7 +18,7 @@ TLS 是常见的传输层加密方式。
// ...
"streamSettings": {
"security": "tls",
// [!code focus:20]
// [!field focus]
"tlsSettings": {
"serverName": "xray.com",
"verifyPeerCertByName": "",
+1 -1
View File
@@ -24,7 +24,7 @@ Websocket 会识别 HTTP 请求的 X-Forwarded-For 头来覆写流量的源地
// ...
"streamSettings": {
"method": "websocket",
// [!code focus:9]
// [!field focus]
"wsSettings": {
"acceptProxyProtocol": false,
"path": "/",
+1 -1
View File
@@ -133,7 +133,7 @@ Additionally, you need to enable `Sniffing` on the inbound of the **client** tha
"inbounds": [
{
// ...
// [!code focus:5]
// [!field focus]
"sniffing": {
"enabled": true,
"destOverride": ["fakedns"], // Use "fakedns", or combine with other sniffers
+1 -1
View File
@@ -30,7 +30,7 @@ Use the following environment variables in Linux to enable a global HTTP proxy f
{
// ...
"protocol": "http",
// [!code focus:10]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -14,7 +14,7 @@ The `hysteria protocol` itself has no authentication; `users` only take effect w
{
// ...
"protocol": "hysteria",
// [!code focus:10]
// [!field focus]
"settings": {
"version": 2,
"users": [
+1 -1
View File
@@ -32,7 +32,7 @@ The Shadowsocks 2022 new protocol format improves performance and includes compl
{
// ...
"protocol": "shadowsocks",
// [!code focus:13]
// [!field focus]
"settings": {
"network": "tcp,udp",
"method": "aes-256-gcm",
+1 -1
View File
@@ -18,7 +18,7 @@ A more meaningful usage of `Socks` inbound is to listen within a LAN or on the l
{
// ...
"protocol": "socks",
// [!code focus:12]
// [!field focus]
"settings": {
"auth": "noauth",
"users": [
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "trojan",
// [!code focus:14]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@ On Linux, this environment variable can optionally be used to pass in the TUN FD
{
// ...
"protocol": "tun",
// [!code focus:10]
// [!field focus]
"settings": {
"name": "utun10",
"desc": "Wintun",
+1 -1
View File
@@ -12,7 +12,7 @@ Tunnel, formerly known as dokodemo-door (Arbitrary Door), can listen on multiple
{
// ...
"protocol": "tunnel",
// [!code focus:12]
// [!field focus]
"settings": {
"allowedNetwork": "tcp",
"rewriteAddress": "8.8.8.8",
+1 -1
View File
@@ -14,7 +14,7 @@ Unlike [VMess](./vmess.md), VLESS does not depend on system time. The authentica
{
// ...
"protocol": "vless",
// [!code focus:18]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@ VMess depends on system time. Please ensure that the system UTC time of the devi
{
// ...
"protocol": "vmess",
// [!code focus:12]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@ User-space WireGuard protocol implementation for establishing a WireGuard tunnel
{
// ...
"protocol": "wireguard",
// [!code focus:14]
// [!field focus]
"settings": {
"secretKey": "SERVER_PRIVATE_KEY",
"peers": [
+1 -1
View File
@@ -12,7 +12,7 @@ Blackhole is an outbound data protocol that blocks all outbound data. When used
{
// ...
"protocol": "blackhole",
// [!code focus:5]
// [!field focus]
"settings": {
"response": {
"type": "none"
+1 -1
View File
@@ -16,7 +16,7 @@ It can allow queries to the target DNS server, `hijack` them to the built-in [DN
{
// ...
"protocol": "dns",
// [!code focus:18]
// [!field focus]
"settings": {
"rewriteNetwork": "udp",
"rewriteAddress": "1.1.1.1",
+1 -1
View File
@@ -16,7 +16,7 @@ This outbound has a default safety policy in server-side and reverse-proxy scena
{
// ...
"protocol": "freedom",
// [!code focus:28]
// [!field focus]
"settings": {
"redirect": "127.0.0.1:3366",
"userLevel": 0,
+1 -1
View File
@@ -20,7 +20,7 @@ HTTP protocol.
{
// ...
"protocol": "http",
// [!code focus:12]
// [!field focus]
"settings": {
"address": "192.168.108.1",
"port": 3128,
+1 -1
View File
@@ -18,7 +18,7 @@ The `hysteria protocol` itself has no authentication. When using with a non `hys
{
// ...
"protocol": "hysteria",
// [!code focus:5]
// [!field focus]
"settings": {
"version": 2,
"address": "192.168.108.1",
+1 -1
View File
@@ -27,7 +27,7 @@ Avoid letting rules or balancers after the loopback select the original outbound
{
// ...
"protocol": "loopback",
// [!code focus:4]
// [!field focus]
"settings": {
"inboundTag": "TagUseAsInbound",
"sniffing": {}
+1 -1
View File
@@ -32,7 +32,7 @@ The Shadowsocks 2022 new protocol format improves performance and includes compl
{
// ...
"protocol": "shadowsocks",
// [!code focus:8]
// [!field focus]
"settings": {
"email": "love@xray.com",
"address": "127.0.0.1",
+1 -1
View File
@@ -16,7 +16,7 @@ Standard Socks protocol implementation, compatible with Socks 5.
{
// ...
"protocol": "socks",
// [!code focus:8]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 1234,
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "trojan",
// [!code focus:7]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 1234,
+1 -1
View File
@@ -14,7 +14,7 @@ Unlike [VMess](./vmess.md), VLESS does not depend on system time. The authentica
{
// ...
"protocol": "vless",
// [!code focus:9]
// [!field focus]
"settings": {
"address": "example.com",
"port": 443,
+1 -1
View File
@@ -16,7 +16,7 @@ VMess depends on system time. Please ensure that the UTC time of the system runn
{
// ...
"protocol": "vmess",
// [!code focus:8]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 37192,
+1 -1
View File
@@ -16,7 +16,7 @@ User-space WireGuard protocol implementation for establishing a WireGuard tunnel
{
// ...
"protocol": "wireguard",
// [!code focus:20]
// [!field focus]
"settings": {
"secretKey": "CLIENT_PRIVATE_KEY",
"address": ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"],
+1 -1
View File
@@ -24,7 +24,7 @@ For direct outbounds such as [Freedom](./outbounds/freedom.md), the peer is usua
"outbounds": [
{
// ...
// [!code focus:18]
// [!field focus]
"streamSettings": {
// Transport methods
"method": "raw",
+15 -15
View File
@@ -15,7 +15,7 @@ It can be used for multiple kinds of TCP and UDP camouflage, as well as QUIC-rel
{
// ...
"streamSettings": {
// [!code focus:33]
// [!field focus]
"finalmask": {
"tcp": [
{
@@ -62,7 +62,7 @@ An array used to camouflage TCP traffic emitted by the core. The first item in t
```json
{
"finalmask": {
// [!code focus:6]
// [!field focus]
"tcp": [
{
"type": "",
@@ -88,7 +88,7 @@ See the fields for each type below.
```json
{
"type": "header-custom",
// [!code focus:35]
// [!field focus]
"settings": {
"clients": [
[
@@ -142,7 +142,7 @@ See the fields for each type below.
```json
{
"type": "fragment",
// [!code focus:6]
// [!field focus]
"settings": {
"packets": "tlshello",
"lengths": ["3-5", "6-8", "10-20"],
@@ -175,7 +175,7 @@ When it is `0` and `"packets": "tlshello"` is set, the fragmented Client Hello w
```json
{
"type": "sudoku",
// [!code focus:10]
// [!field focus]
"settings": {
"password": "",
"ascii": "",
@@ -198,7 +198,7 @@ An array used to camouflage UDP traffic emitted by the core. The first item in t
```json
{
"finalmask": {
// [!code focus:6]
// [!field focus]
"udp": [
{
"type": "",
@@ -226,7 +226,7 @@ Always merged into the packet header.
```json
{
"type": "header-custom",
// [!code focus:18]
// [!field focus]
"settings": {
"client": [
{
@@ -261,7 +261,7 @@ Always merged into the packet header.
```json
{
"type": "mkcp-legacy",
// [!code focus:4]
// [!field focus]
"settings": {
"header": "", // dns dtls srtp utp wechat wireguard
"value": "" // password domain
@@ -292,7 +292,7 @@ Noise sent before the actual data.
```json
{
"type": "noise",
// [!code focus:12]
// [!field focus]
"settings": {
"reset": "30-60",
"noise": [
@@ -327,7 +327,7 @@ Salamander obfuscation. From Hysteria2.
```json
{
"type": "salamander",
// [!code focus:4]
// [!field focus]
"settings": {
"password": "your-password",
"packetSize": "512-1200"
@@ -348,7 +348,7 @@ When non-empty, enables Gecko obfuscation, which applies additional fragmentatio
```json
{
"type": "sudoku",
// [!code focus:10]
// [!field focus]
"settings": {
"password": "",
"ascii": "",
@@ -379,7 +379,7 @@ For example, if you own `example.com`, set an A record like `a.example.com` to t
```json
{
"type": "xdns",
// [!code focus:4]
// [!field focus]
"settings": {
"domains": ["t.example.com"],
"resolvers": ["t.example.com+udp://8.8.8.8:53"]
@@ -398,7 +398,7 @@ At least one of `domains` and `resolvers` must be set.
```json
{
"type": "xicmp",
// [!code focus:4]
// [!field focus]
"settings": {
"dgram": false, // optional
"ips": [] // optional
@@ -417,7 +417,7 @@ Self-built https://github.com/apernet/hysteria-realm-server
```json
{
"type": "realm",
// [!code focus:8]
// [!field focus]
"settings": {
"url": "realm://public@xxx/your-realm-name",
"stunServers": [
@@ -442,7 +442,7 @@ Connection failures require debug-level logging. Possible contributing factors i
```json
{
"finalmask": {
// [!code focus:19]
// [!field focus]
"quicParams": {
"congestion": "force-brutal",
"bbrProfile": "standard",
+1 -1
View File
@@ -48,7 +48,7 @@ If you are using fallback, please note the following:
// ...
"streamSettings": {
"method": "grpc",
// [!code focus:10]
// [!field focus]
"grpcSettings": {
"authority": "grpc.example.com",
"serviceName": "name",
+1 -1
View File
@@ -19,7 +19,7 @@ Its design is not recommended for standalone use; instead, it is intended to wor
// ...
"streamSettings": {
"method": "httpupgrade",
// [!code focus:8]
// [!field focus]
"httpupgradeSettings": {
"acceptProxyProtocol": false,
"path": "/",
+1 -1
View File
@@ -14,7 +14,7 @@ Xray implementation of the underlying QUIC transport for Hysteria2, typically us
// ...
"streamSettings": {
"method": "hysteria",
// [!code focus:17]
// [!field focus]
"hysteriaSettings": {
"version": 2,
"auth": "password",
+1 -1
View File
@@ -20,7 +20,7 @@ Please ensure that the firewall configuration on the host is correct.
// ...
"streamSettings": {
"method": "mkcp",
// [!code focus:9]
// [!field focus]
"kcpSettings": {
"mtu": 1350,
"tti": 20,
+1 -1
View File
@@ -16,7 +16,7 @@ It can be combined with various protocols in multiple modes.
// ...
"streamSettings": {
"method": "raw",
// [!code focus:6]
// [!field focus]
"rawSettings": {
"acceptProxyProtocol": false,
"header": {
+1 -1
View File
@@ -26,7 +26,7 @@ For more information, see the [REALITY project](https://github.com/XTLS/REALITY)
// ...
"streamSettings": {
"security": "reality",
// [!code focus:30]
// [!field focus]
"realitySettings": {
// Inbound (server-side) settings
"show": false,
+1 -1
View File
@@ -15,7 +15,7 @@ It can be used to tune transparent proxying, DNS resolution strategy, and many o
{
// ...
"streamSettings": {
// [!code focus:21]
// [!field focus]
"sockopt": {
"mark": 0,
"tcpMaxSeg": 1440,
+1 -1
View File
@@ -18,7 +18,7 @@ It supports use with the `RAW`, `XHTTP`, `mKCP`, `gRPC`, `WebSocket`, `HTTPUpgra
// ...
"streamSettings": {
"security": "tls",
// [!code focus:20]
// [!field focus]
"tlsSettings": {
"serverName": "xray.com",
"verifyPeerCertByName": "",
+1 -1
View File
@@ -24,7 +24,7 @@ WebSocket will recognize the `X-Forwarded-For` header in HTTP requests to overwr
// ...
"streamSettings": {
"method": "websocket",
// [!code focus:9]
// [!field focus]
"wsSettings": {
"acceptProxyProtocol": false,
"path": "/",
+1 -1
View File
@@ -136,7 +136,7 @@ FakeDNS будет использовать этот блок IP-адресов
"inbounds": [
{
// ...
// [!code focus:5]
// [!field focus]
"sniffing": {
"enabled": true,
"destOverride": ["fakedns"], // Используйте "fakedns" или в сочетании с другими снифферами.
+1 -1
View File
@@ -30,7 +30,7 @@
{
// ...
"protocol": "http",
// [!code focus:10]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -14,7 +14,7 @@
{
// ...
"protocol": "hysteria",
// [!code focus:10]
// [!field focus]
"settings": {
"version": 2,
"users": [
+1 -1
View File
@@ -32,7 +32,7 @@
{
// ...
"protocol": "shadowsocks",
// [!code focus:13]
// [!field focus]
"settings": {
"network": "tcp,udp",
"method": "aes-256-gcm",
+1 -1
View File
@@ -18,7 +18,7 @@
{
// ...
"protocol": "socks",
// [!code focus:12]
// [!field focus]
"settings": {
"auth": "noauth",
"users": [
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "trojan",
// [!code focus:14]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "tun",
// [!code focus:10]
// [!field focus]
"settings": {
"name": "utun10",
"desc": "Wintun",
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "tunnel",
// [!code focus:12]
// [!field focus]
"settings": {
"allowedNetwork": "tcp",
"rewriteAddress": "8.8.8.8",
+1 -1
View File
@@ -14,7 +14,7 @@ VLESS - это легкий транспортный протокол без с
{
// ...
"protocol": "vless",
// [!code focus:18]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@ VMess полагается на системное время. Убедитес
{
// ...
"protocol": "vmess",
// [!code focus:12]
// [!field focus]
"settings": {
"users": [
{
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "wireguard",
// [!code focus:14]
// [!field focus]
"settings": {
"secretKey": "SERVER_PRIVATE_KEY",
"peers": [
+1 -1
View File
@@ -12,7 +12,7 @@ Blackhole - это протокол исходящих данных, котор
{
// ...
"protocol": "blackhole",
// [!code focus:5]
// [!field focus]
"settings": {
"response": {
"type": "none"
+1 -1
View File
@@ -16,7 +16,7 @@ DNS — это исходящий протокол, который приним
{
// ...
"protocol": "dns",
// [!code focus:18]
// [!field focus]
"settings": {
"rewriteNetwork": "udp",
"rewriteAddress": "1.1.1.1",
+1 -1
View File
@@ -16,7 +16,7 @@ Freedom — это протокол прямого исходящего подк
{
// ...
"protocol": "freedom",
// [!code focus:28]
// [!field focus]
"settings": {
"redirect": "127.0.0.1:3366",
"userLevel": 0,
+1 -1
View File
@@ -20,7 +20,7 @@
{
// ...
"protocol": "http",
// [!code focus:12]
// [!field focus]
"settings": {
"address": "192.168.108.1",
"port": 3128,
+1 -1
View File
@@ -18,7 +18,7 @@
{
// ...
"protocol": "hysteria",
// [!code focus:5]
// [!field focus]
"settings": {
"version": 2,
"address": "192.168.108.1",
+1 -1
View File
@@ -27,7 +27,7 @@ Loopback — это outbound с возвратом трафика, которы
{
// ...
"protocol": "loopback",
// [!code focus:4]
// [!field focus]
"settings": {
"inboundTag": "TagUseAsInbound",
"sniffing": {}
+1 -1
View File
@@ -32,7 +32,7 @@
{
// ...
"protocol": "shadowsocks",
// [!code focus:8]
// [!field focus]
"settings": {
"email": "love@xray.com",
"address": "127.0.0.1",
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "socks",
// [!code focus:8]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 1234,
+1 -1
View File
@@ -12,7 +12,7 @@
{
// ...
"protocol": "trojan",
// [!code focus:7]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 1234,
+1 -1
View File
@@ -14,7 +14,7 @@ VLESS - это легкий транспортный протокол без с
{
// ...
"protocol": "vless",
// [!code focus:9]
// [!field focus]
"settings": {
"address": "example.com",
"port": 443,
+1 -1
View File
@@ -16,7 +16,7 @@ VMess полагается на системное время. Убедитес
{
// ...
"protocol": "vmess",
// [!code focus:8]
// [!field focus]
"settings": {
"address": "127.0.0.1",
"port": 37192,
+1 -1
View File
@@ -16,7 +16,7 @@
{
// ...
"protocol": "wireguard",
// [!code focus:20]
// [!field focus]
"settings": {
"secretKey": "CLIENT_PRIVATE_KEY",
"address": ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"],
+1 -1
View File
@@ -24,7 +24,7 @@
"outbounds": [
{
// ...
// [!code focus:18]
// [!field focus]
"streamSettings": {
// Способы передачи
"method": "raw",
+15 -15
View File
@@ -15,7 +15,7 @@ FinalMask добавляет последний слой маскировки п
{
// ...
"streamSettings": {
// [!code focus:33]
// [!field focus]
"finalmask": {
"tcp": [
{
@@ -62,7 +62,7 @@ FinalMask добавляет последний слой маскировки п
```json
{
"finalmask": {
// [!code focus:6]
// [!field focus]
"tcp": [
{
"type": "",
@@ -88,7 +88,7 @@ FinalMask добавляет последний слой маскировки п
```json
{
"type": "header-custom",
// [!code focus:35]
// [!field focus]
"settings": {
"clients": [
[
@@ -142,7 +142,7 @@ FinalMask добавляет последний слой маскировки п
```json
{
"type": "fragment",
// [!code focus:6]
// [!field focus]
"settings": {
"packets": "tlshello",
"lengths": ["3-5", "6-8", "10-20"],
@@ -175,7 +175,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "sudoku",
// [!code focus:10]
// [!field focus]
"settings": {
"password": "",
"ascii": "",
@@ -198,7 +198,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"finalmask": {
// [!code focus:6]
// [!field focus]
"udp": [
{
"type": "",
@@ -226,7 +226,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "header-custom",
// [!code focus:18]
// [!field focus]
"settings": {
"client": [
{
@@ -261,7 +261,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "mkcp-legacy",
// [!code focus:4]
// [!field focus]
"settings": {
"header": "", // dns dtls srtp utp wechat wireguard
"value": "" // password domain
@@ -292,7 +292,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "noise",
// [!code focus:12]
// [!field focus]
"settings": {
"reset": "30-60",
"noise": [
@@ -327,7 +327,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "salamander",
// [!code focus:4]
// [!field focus]
"settings": {
"password": "your-password",
"packetSize": "512-1200"
@@ -348,7 +348,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "sudoku",
// [!code focus:10]
// [!field focus]
"settings": {
"password": "",
"ascii": "",
@@ -379,7 +379,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "xdns",
// [!code focus:4]
// [!field focus]
"settings": {
"domains": ["t.example.com"],
"resolvers": ["t.example.com+udp://8.8.8.8:53"]
@@ -398,7 +398,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "xicmp",
// [!code focus:4]
// [!field focus]
"settings": {
"dgram": false, // optional
"ips": [] // optional
@@ -417,7 +417,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"type": "realm",
// [!code focus:8]
// [!field focus]
"settings": {
"url": "realm://public@xxx/your-realm-name",
"stunServers": [
@@ -442,7 +442,7 @@ n-й элемент массива задаёт, сколько ждать по
```json
{
"finalmask": {
// [!code focus:19]
// [!field focus]
"quicParams": {
"congestion": "force-brutal",
"bbrProfile": "standard",
+1 -1
View File
@@ -48,7 +48,7 @@ gRPC (HTTP/2) имеет встроенное мультиплексирован
// ...
"streamSettings": {
"method": "grpc",
// [!code focus:10]
// [!field focus]
"grpcSettings": {
"authority": "grpc.example.com",
"serviceName": "name",
+1 -1
View File
@@ -20,7 +20,7 @@
// ...
"streamSettings": {
"method": "httpupgrade",
// [!code focus:8]
// [!field focus]
"httpupgradeSettings": {
"acceptProxyProtocol": false,
"path": "/",
+1 -1
View File
@@ -14,7 +14,7 @@
// ...
"streamSettings": {
"method": "hysteria",
// [!code focus:17]
// [!field focus]
"hysteriaSettings": {
"version": 2,
"auth": "password",

Some files were not shown because too many files have changed in this diff Show More