From b6c859f5b9a5a7620e7f16352d7ef2985c672b11 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 11 Oct 2026 15:37:20 +0200 Subject: [PATCH] feat(xray): edit Lua DNS and routing scripts xray-core 26.10.10 can hand DNS and routing to Lua: dns.script and routing.script name a .lua file (absolute, or found next to the Xray binary) that defines HandleDNSQuery / HandleRoute, and a DNS server's id is how a DNS script picks it. The keys round-tripped through the JSON template but had no field. - DNS: a Lua Script field, and an ID field in the server modal; - Basics: a Routing Script field beside the routing strategy; - Routing: a warning above the rules while a script is set, since the core then routes only through the script and skips every rule, the panel's api rule included. The descriptions say the script must still send the api inbound to the api outbound, and that Xray will not start if the file is missing. An empty field drops the key, because the core rejects an empty path. --- .../docs/en/operations/outbounds-routing.mdx | 14 ++++ .../docs/fa/operations/outbounds-routing.mdx | 14 ++++ .../docs/ru/operations/outbounds-routing.mdx | 14 ++++ .../docs/zh/operations/outbounds-routing.mdx | 12 +++ frontend/src/pages/xray/basics/BasicsTab.tsx | 20 +++++ .../src/pages/xray/dns/DnsServerModal.tsx | 7 ++ frontend/src/pages/xray/dns/DnsTab.tsx | 12 +++ .../src/pages/xray/routing/RoutingTab.tsx | 11 ++- frontend/src/schemas/xray.ts | 1 + frontend/src/test/dns-server-modal.test.tsx | 17 ++++- frontend/src/test/dns-tab.test.tsx | 28 ++++++- frontend/src/test/routing-script.test.tsx | 75 +++++++++++++++++++ internal/web/translation/ar-EG.json | 11 ++- internal/web/translation/en-US.json | 11 ++- internal/web/translation/es-ES.json | 11 ++- internal/web/translation/fa-IR.json | 11 ++- internal/web/translation/id-ID.json | 11 ++- internal/web/translation/ja-JP.json | 11 ++- internal/web/translation/pt-BR.json | 11 ++- internal/web/translation/ru-RU.json | 11 ++- internal/web/translation/tr-TR.json | 11 ++- internal/web/translation/uk-UA.json | 11 ++- internal/web/translation/vi-VN.json | 11 ++- internal/web/translation/zh-CN.json | 11 ++- internal/web/translation/zh-TW.json | 11 ++- 25 files changed, 338 insertions(+), 30 deletions(-) create mode 100644 frontend/src/test/routing-script.test.tsx diff --git a/docs/content/docs/en/operations/outbounds-routing.mdx b/docs/content/docs/en/operations/outbounds-routing.mdx index 41961abae..d25256ef9 100644 --- a/docs/content/docs/en/operations/outbounds-routing.mdx +++ b/docs/content/docs/en/operations/outbounds-routing.mdx @@ -151,6 +151,20 @@ put specific rules above general ones. } ``` +### Lua scripts + +Xray 26.10.10 can hand routing and DNS to Lua. **Basics → Routing Script** takes the +path of a `.lua` file that defines `HandleRoute` (absolute, or relative to the Xray +`bin` folder); **DNS → Lua Script** takes one that defines `HandleDNSQuery`, and a +DNS server's **ID** is the name such a script picks it by. + + + A routing script replaces **every** routing rule, the panel's own `api` rule + included. Send the `api` inbound to the `api` outbound in your script, or traffic + statistics and live client changes stop. Xray does not start if the file is missing + or fails to load. + + ## Balancers A **balancer** groups outbounds by a **selector** (tag prefixes, including the diff --git a/docs/content/docs/fa/operations/outbounds-routing.mdx b/docs/content/docs/fa/operations/outbounds-routing.mdx index fb9d4ad11..2028346c4 100644 --- a/docs/content/docs/fa/operations/outbounds-routing.mdx +++ b/docs/content/docs/fa/operations/outbounds-routing.mdx @@ -152,6 +152,20 @@ Reset یا حذف، peer مربوط به WireGuard را در حساب PIA باط } ``` +### اسکریپت‌های Lua + +Xray 26.10.10 می‌تواند مسیریابی و DNS را به Lua بسپارد. **پایه ← اسکریپت مسیریابی** +مسیر یک فایل `.lua` را می‌گیرد که `HandleRoute` را تعریف می‌کند (مطلق یا نسبت به +پوشه‌ی `bin` در Xray)؛ **DNS ← اسکریپت Lua** فایلی را می‌گیرد که `HandleDNSQuery` را +تعریف می‌کند، و **شناسه**‌ی هر سرور DNS نامی است که اسکریپت با آن سرور را انتخاب می‌کند. + + + اسکریپت مسیریابی جای **همه‌ی** قوانین مسیریابی را می‌گیرد، از جمله قانون `api` خود + پنل. در اسکریپت، اینباند `api` را به اوت‌باند `api` بفرستید، وگرنه آمار ترافیک و + اعمال زنده‌ی تغییرات کلاینت‌ها متوقف می‌شود. اگر فایل وجود نداشته باشد یا بارگذاری + نشود، Xray اجرا نمی‌شود. + + ## متعادل‌کننده‌ها یک **متعادل‌کننده** خروجی‌ها را با یک **انتخاب‌گر** (پیشوندهای برچسب، از جمله مجموعه‌های diff --git a/docs/content/docs/ru/operations/outbounds-routing.mdx b/docs/content/docs/ru/operations/outbounds-routing.mdx index 1a765e514..037318beb 100644 --- a/docs/content/docs/ru/operations/outbounds-routing.mdx +++ b/docs/content/docs/ru/operations/outbounds-routing.mdx @@ -165,6 +165,20 @@ hostname получает уникальный тег `nord-` и не } ``` +### Lua-скрипты + +Xray 26.10.10 умеет передавать маршрутизацию и DNS в Lua. **Основное → Скрипт +маршрутизации** принимает путь к файлу `.lua` с функцией `HandleRoute` (абсолютный +или относительно папки `bin` Xray); **DNS → Lua-скрипт** — файл с функцией +`HandleDNSQuery`, а **ID** DNS-сервера — имя, по которому такой скрипт его выбирает. + + + Скрипт маршрутизации заменяет **все** правила маршрутизации, включая собственное + правило `api` панели. Направляйте в скрипте входящий `api` на исходящий `api`, + иначе остановятся статистика трафика и применение изменений клиентов на лету. Xray не + запустится, если файл отсутствует или не загружается. + + ## Балансировщики **Балансировщик** группирует исходящие соединения по **селектору** (префиксы diff --git a/docs/content/docs/zh/operations/outbounds-routing.mdx b/docs/content/docs/zh/operations/outbounds-routing.mdx index 3d73a5341..8ebe0addd 100644 --- a/docs/content/docs/zh/operations/outbounds-routing.mdx +++ b/docs/content/docs/zh/operations/outbounds-routing.mdx @@ -140,6 +140,18 @@ Xray 配置中——而不会改动你已保存的模板。这是订阅一*池* } ``` +### Lua 脚本 + +Xray 26.10.10 可以把路由和 DNS 交给 Lua 处理。**基础配置 → 路由脚本** 填写定义了 +`HandleRoute` 的 `.lua` 文件路径(绝对路径或相对于 Xray `bin` 目录);**DNS → Lua +脚本** 填写定义了 `HandleDNSQuery` 的文件,DNS 服务器的 **ID** 就是脚本选择它时使用的名称。 + + + 路由脚本会取代**全部**路由规则,包括面板自带的 `api` 规则。请在脚本中把 `api` 入站 + 发往 `api` 出站,否则流量统计和客户端变更的实时生效都会停止。文件不存在或加载失败时 + Xray 无法启动。 + + ## 均衡器 **均衡器**通过一个**选择器**(标签前缀,包括来自出站订阅的通配符池)将出站分组, diff --git a/frontend/src/pages/xray/basics/BasicsTab.tsx b/frontend/src/pages/xray/basics/BasicsTab.tsx index 2ae686512..6eced02ae 100644 --- a/frontend/src/pages/xray/basics/BasicsTab.tsx +++ b/frontend/src/pages/xray/basics/BasicsTab.tsx @@ -160,6 +160,7 @@ export default function BasicsTab({ ); const routingStrategy = templateSettings?.routing?.domainStrategy ?? 'AsIs'; + const routingScript = templateSettings?.routing?.script ?? ''; const log = (templateSettings?.log || {}) as Record; const policy = (templateSettings?.policy?.system || {}) as Record; const level0 = (templateSettings?.policy?.levels?.['0'] || {}) as Record; @@ -259,6 +260,25 @@ export default function BasicsTab({ /> } /> + { + const next = e.target.value; + mutate((tt) => { + if (!tt.routing) return; + if (next.trim() === '') delete tt.routing.script; + else tt.routing.script = next; + }); + }} + /> + } + /> )} + + + diff --git a/frontend/src/pages/xray/dns/DnsTab.tsx b/frontend/src/pages/xray/dns/DnsTab.tsx index 27a011c30..711d3ef94 100644 --- a/frontend/src/pages/xray/dns/DnsTab.tsx +++ b/frontend/src/pages/xray/dns/DnsTab.tsx @@ -297,6 +297,18 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab /> } /> + setDnsField('script', e.target.value, true)} + /> + } + /> {( [ [ diff --git a/frontend/src/pages/xray/routing/RoutingTab.tsx b/frontend/src/pages/xray/routing/RoutingTab.tsx index 946b5b2c7..e62f2a33e 100644 --- a/frontend/src/pages/xray/routing/RoutingTab.tsx +++ b/frontend/src/pages/xray/routing/RoutingTab.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Dropdown, Modal, Space, Table, Tabs, message } from 'antd'; +import { Alert, Button, Dropdown, Modal, Space, Table, Tabs, message } from 'antd'; import { AimOutlined, ControlOutlined, @@ -64,6 +64,7 @@ export default function RoutingTab({ moved: false, }); + const routingScript = templateSettings?.routing?.script ?? ''; const rules = useMemo( () => (templateSettings?.routing?.rules || []) as RoutingRule[], [templateSettings?.routing?.rules], @@ -349,6 +350,14 @@ export default function RoutingTab({ <> {modalContextHolder} {messageContextHolder} + {routingScript.trim() !== '' && ( + + )} { expect(onConfirm).toHaveBeenCalledTimes(1); expect(onConfirm.mock.calls[0][0]).toMatchObject({ address: '1.1.1.1', id: 'cf' }); }); + + it('saves an id typed for a plain server', async () => { + const onConfirm = vi.fn(); + renderWithProviders( + {}} onConfirm={onConfirm} />, + ); + + fireEvent.change(screen.getByLabelText('ID'), { target: { value: 'cf' } }); + const ok = document.querySelector('.ant-modal-footer .ant-btn-primary') as HTMLElement; + await act(async () => { + fireEvent.click(ok); + }); + + expect(onConfirm.mock.calls[0][0]).toMatchObject({ address: '1.1.1.1', id: 'cf' }); + }); }); diff --git a/frontend/src/test/dns-tab.test.tsx b/frontend/src/test/dns-tab.test.tsx index b13af098f..1a9c6648c 100644 --- a/frontend/src/test/dns-tab.test.tsx +++ b/frontend/src/test/dns-tab.test.tsx @@ -1,5 +1,5 @@ -import { useState } from 'react'; -import { describe, expect, it } from 'vitest'; +import { useEffect, useState } from 'react'; +import { describe, expect, it, vi } from 'vitest'; import { fireEvent, screen } from '@testing-library/react'; import DnsTab from '@/pages/xray/dns/DnsTab'; @@ -127,4 +127,28 @@ describe('DnsTab', () => { expect(screen.queryByLabelText('Domain (e.g. domain:example.com)')).toBeNull(); }); + + // xray-core 26.10.10 dns.script is a file path; an empty one fails the core build. + it('writes the Lua script path and drops the key once cleared', () => { + const seen = vi.fn(); + const latest = () => seen.mock.lastCall?.[0] as { dns: Record }; + function Harness() { + const [templateSettings, setTemplateSettings] = useState( + withHosts({}), + ); + useEffect(() => seen(templateSettings), [templateSettings]); + const updateTemplate: SetTemplate = (next) => { + setTemplateSettings((current) => (typeof next === 'function' ? next(current) : next)); + }; + return ; + } + + renderWithProviders(); + const script = screen.getByRole('textbox', { name: 'Lua Script' }); + fireEvent.change(script, { target: { value: '/etc/xray/dns.lua' } }); + expect(latest().dns.script).toBe('/etc/xray/dns.lua'); + + fireEvent.change(script, { target: { value: '' } }); + expect(latest().dns).not.toHaveProperty('script'); + }); }); diff --git a/frontend/src/test/routing-script.test.tsx b/frontend/src/test/routing-script.test.tsx new file mode 100644 index 000000000..a4b98e183 --- /dev/null +++ b/frontend/src/test/routing-script.test.tsx @@ -0,0 +1,75 @@ +import { useEffect, useState } from 'react'; +import { describe, expect, it, vi } from 'vitest'; +import { fireEvent, screen } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +import BasicsTab from '@/pages/xray/basics/BasicsTab'; +import RoutingTab from '@/pages/xray/routing/RoutingTab'; +import type { SetTemplate, XraySettingsValue } from '@/hooks/useXraySetting'; +import { renderWithProviders } from './test-utils'; + +const SCRIPT_BANNER = 'A routing script is set under Basics, so Xray ignores these rules.'; + +function renderRoutingRules(routing: Record) { + const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } }); + renderWithProviders( + + + , + ); + fireEvent.click(screen.getByRole('tab', { name: /Routing Rules/ })); +} + +// xray-core 26.10.10 routes only through routing.script once it is set, skipping +// every rule, the panel's api rule included. +describe('routing script', () => { + it('writes the script path from Basics and drops the key once cleared', () => { + const seen = vi.fn(); + const latest = () => seen.mock.lastCall?.[0] as { routing: Record }; + function Harness() { + const [templateSettings, setTemplateSettings] = useState({ + routing: { domainStrategy: 'AsIs', rules: [] }, + outbounds: [], + } as unknown as XraySettingsValue); + useEffect(() => seen(templateSettings), [templateSettings]); + const updateTemplate: SetTemplate = (next) => { + setTemplateSettings((current) => (typeof next === 'function' ? next(current) : next)); + }; + return ( + + ); + } + + renderWithProviders(); + const script = screen.getByRole('textbox', { name: 'Routing Script' }); + fireEvent.change(script, { target: { value: 'route.lua' } }); + expect(latest().routing.script).toBe('route.lua'); + + fireEvent.change(script, { target: { value: ' ' } }); + expect(latest().routing).not.toHaveProperty('script'); + }); + + it('warns above the rules while a script is set', () => { + renderRoutingRules({ rules: [], script: 'route.lua' }); + + expect(screen.getByText(SCRIPT_BANNER)).toBeTruthy(); + }); + + it('shows no warning without a script', () => { + renderRoutingRules({ rules: [] }); + + expect(screen.queryByText(SCRIPT_BANNER)).toBeNull(); + }); +}); diff --git a/internal/web/translation/ar-EG.json b/internal/web/translation/ar-EG.json index 47f00497b..e9911cd0f 100644 --- a/internal/web/translation/ar-EG.json +++ b/internal/web/translation/ar-EG.json @@ -2275,7 +2275,11 @@ "clearAll": "حذف الكل", "clearAllTitle": "حذف جميع خوادم DNS؟", "clearAllConfirm": "سيؤدي هذا إلى إزالة جميع خوادم DNS من القائمة. لا يمكن التراجع عن هذا الإجراء.", - "dnsLeakWarning": "قد يتسرب DNS عبر localhost أو UDP/TCP غير المشفر أو وضع DoH/DoQ المحلي أو استعلامات الرجوع أو EDNS client IP. استخدم DoH عبر التوجيه، وثبت أسماء المحللات في hosts، وعطل الرجوع عندما تكون الخصوصية مهمة." + "dnsLeakWarning": "قد يتسرب DNS عبر localhost أو UDP/TCP غير المشفر أو وضع DoH/DoQ المحلي أو استعلامات الرجوع أو EDNS client IP. استخدم DoH عبر التوجيه، وثبت أسماء المحللات في hosts، وعطل الرجوع عندما تكون الخصوصية مهمة.", + "script": "سكريبت Lua", + "scriptDesc": "مسار ملف ‎.lua‎ بيعرّف HandleDNSQuery، مطلق أو نسبةً لمجلد bin بتاع Xray. بعدها السكريبت هو اللي بيرد على كل الاستعلامات وما بيوصلش للسيرفرات غير من خلال الكود بتاعه. Xray مش هيشتغل لو الملف مش موجود أو مش صالح.", + "serverId": "المعرّف", + "serverIdDesc": "الاسم اللي سكريبت DNS بلغة Lua بيستخدمه عشان يختار السيرفر ده" }, "fakedns": { "add": "أضف Fake DNS", @@ -2283,7 +2287,10 @@ "poolSize": "حجم المجموعة" }, "defaultOutbound": "الصادر الافتراضي", - "defaultOutboundDesc": "الحركة التي لا تطابق أي قاعدة توجيه تستخدم هذا الصادر (الأول في القائمة)." + "defaultOutboundDesc": "الحركة التي لا تطابق أي قاعدة توجيه تستخدم هذا الصادر (الأول في القائمة).", + "routingScript": "سكريبت التوجيه", + "routingScriptDesc": "مسار ملف ‎.lua‎ بيعرّف HandleRoute، مطلق أو نسبةً لمجلد bin بتاع Xray. بعدها السكريبت هو اللي بيختار كل مسار وXray بيتجاهل كل قواعد التوجيه، ومنها قاعدة api بتاعة البانل: لازم توجّه الإدخال api للإخراج api وإلا إحصائيات الترافيك وتطبيق تغييرات العملاء مباشرةً هيقفوا. Xray مش هيشتغل لو الملف مش موجود أو مش صالح.", + "routingScriptActive": "فيه سكريبت توجيه متظبط في {section}، عشان كده Xray بيتجاهل القواعد دي." }, "hosts": { "addHost": "إضافة مضيف", diff --git a/internal/web/translation/en-US.json b/internal/web/translation/en-US.json index f1fbf4a17..3cfb13769 100644 --- a/internal/web/translation/en-US.json +++ b/internal/web/translation/en-US.json @@ -2393,7 +2393,11 @@ "clearAll": "Delete All", "clearAllTitle": "Delete all DNS servers?", "clearAllConfirm": "This removes every DNS server from the list. This cannot be undone.", - "dnsLeakWarning": "DNS can leak through localhost, plain UDP/TCP, local-mode DoH/DoQ, fallback queries, or EDNS client IP. Use routed DoH, hosts pins, and disable fallback when privacy matters." + "dnsLeakWarning": "DNS can leak through localhost, plain UDP/TCP, local-mode DoH/DoQ, fallback queries, or EDNS client IP. Use routed DoH, hosts pins, and disable fallback when privacy matters.", + "script": "Lua Script", + "scriptDesc": "Path to a .lua file defining HandleDNSQuery, absolute or relative to the Xray bin folder. The script then answers every query and reaches the servers only through its own code. Xray will not start if the file is missing or invalid.", + "serverId": "ID", + "serverIdDesc": "The name a Lua DNS script uses to pick this server" }, "fakedns": { "add": "Add Fake DNS", @@ -2401,7 +2405,10 @@ "poolSize": "Pool Size" }, "defaultOutbound": "Default Outbound", - "defaultOutboundDesc": "Traffic that does not match any routing rule uses this outbound (Xray uses the first outbound in the list)." + "defaultOutboundDesc": "Traffic that does not match any routing rule uses this outbound (Xray uses the first outbound in the list).", + "routingScript": "Routing Script", + "routingScriptDesc": "Path to a .lua file defining HandleRoute, absolute or relative to the Xray bin folder. The script then picks every route and Xray ignores all routing rules, the panel's api rule included: send the api inbound to the api outbound or traffic stats and live client changes stop. Xray will not start if the file is missing or invalid.", + "routingScriptActive": "A routing script is set under {section}, so Xray ignores these rules." }, "sponsors": { "title": "Sponsors", diff --git a/internal/web/translation/es-ES.json b/internal/web/translation/es-ES.json index 02f29b1c0..2c1a764ae 100644 --- a/internal/web/translation/es-ES.json +++ b/internal/web/translation/es-ES.json @@ -2275,7 +2275,11 @@ "clearAll": "Eliminar todos", "clearAllTitle": "¿Eliminar todos los servidores DNS?", "clearAllConfirm": "Esto eliminará todos los servidores DNS de la lista. No se puede deshacer.", - "dnsLeakWarning": "El DNS puede filtrarse por localhost, UDP/TCP sin cifrar, DoH/DoQ en modo local, consultas de respaldo o EDNS client IP. Usa DoH enrutado, fija los resolutores en hosts y desactiva el respaldo cuando la privacidad importe." + "dnsLeakWarning": "El DNS puede filtrarse por localhost, UDP/TCP sin cifrar, DoH/DoQ en modo local, consultas de respaldo o EDNS client IP. Usa DoH enrutado, fija los resolutores en hosts y desactiva el respaldo cuando la privacidad importe.", + "script": "Script Lua", + "scriptDesc": "Ruta a un archivo .lua que define HandleDNSQuery, absoluta o relativa a la carpeta bin de Xray. El script responde entonces a cada consulta y solo llega a los servidores a través de su propio código. Xray no arrancará si el archivo falta o no es válido.", + "serverId": "ID", + "serverIdDesc": "Nombre con el que un script DNS en Lua elige este servidor" }, "fakedns": { "add": "Agregar DNS Falso", @@ -2283,7 +2287,10 @@ "poolSize": "Tamaño del grupo" }, "defaultOutbound": "Salida predeterminada", - "defaultOutboundDesc": "El tráfico que no coincide con ninguna regla de enrutamiento usa esta salida (la primera de la lista)." + "defaultOutboundDesc": "El tráfico que no coincide con ninguna regla de enrutamiento usa esta salida (la primera de la lista).", + "routingScript": "Script de enrutamiento", + "routingScriptDesc": "Ruta a un archivo .lua que define HandleRoute, absoluta o relativa a la carpeta bin de Xray. El script elige entonces cada ruta y Xray ignora todas las reglas de enrutamiento, incluida la regla api del panel: envía el inbound api al outbound api o se detendrán las estadísticas de tráfico y los cambios de clientes en vivo. Xray no arrancará si el archivo falta o no es válido.", + "routingScriptActive": "Hay un script de enrutamiento definido en {section}, así que Xray ignora estas reglas." }, "hosts": { "addHost": "Agregar host", diff --git a/internal/web/translation/fa-IR.json b/internal/web/translation/fa-IR.json index 9e7f2ac04..d20f9741e 100644 --- a/internal/web/translation/fa-IR.json +++ b/internal/web/translation/fa-IR.json @@ -2275,7 +2275,11 @@ "clearAll": "حذف همه", "clearAllTitle": "حذف همه سرورهای DNS؟", "clearAllConfirm": "این کار همه سرورهای DNS را از لیست حذف می‌کند و قابل بازگشت نیست.", - "dnsLeakWarning": "DNS ممکن است از طریق localhost، UDP/TCP ساده، حالت محلی DoH/DoQ، درخواست‌های fallback یا EDNS client IP نشت کند. برای حریم خصوصی از DoH مسیریابی‌شده، مقدارهای hosts ثابت و غیرفعال‌سازی fallback استفاده کنید." + "dnsLeakWarning": "DNS ممکن است از طریق localhost، UDP/TCP ساده، حالت محلی DoH/DoQ، درخواست‌های fallback یا EDNS client IP نشت کند. برای حریم خصوصی از DoH مسیریابی‌شده، مقدارهای hosts ثابت و غیرفعال‌سازی fallback استفاده کنید.", + "script": "اسکریپت Lua", + "scriptDesc": "مسیر یک فایل ‎.lua‎ که HandleDNSQuery را تعریف می‌کند، به‌صورت مطلق یا نسبت به پوشه‌ی bin در Xray. از آن پس اسکریپت به همه‌ی کوئری‌ها پاسخ می‌دهد و سرورها فقط از طریق کد خودش استفاده می‌شوند. اگر فایل وجود نداشته باشد یا نامعتبر باشد، Xray اجرا نمی‌شود.", + "serverId": "شناسه", + "serverIdDesc": "نامی که اسکریپت Lua‌ی DNS با آن این سرور را انتخاب می‌کند" }, "fakedns": { "add": "افزودن دی‌ان‌اس جعلی", @@ -2283,7 +2287,10 @@ "poolSize": "اندازه استخر" }, "defaultOutbound": "خروجی پیش‌فرض", - "defaultOutboundDesc": "ترافیکی که با هیچ قانون مسیریابی جور نشود از این خروجی استفاده می‌کند (اولین خروجی در فهرست)." + "defaultOutboundDesc": "ترافیکی که با هیچ قانون مسیریابی جور نشود از این خروجی استفاده می‌کند (اولین خروجی در فهرست).", + "routingScript": "اسکریپت مسیریابی", + "routingScriptDesc": "مسیر یک فایل ‎.lua‎ که HandleRoute را تعریف می‌کند، به‌صورت مطلق یا نسبت به پوشه‌ی bin در Xray. از آن پس اسکریپت همه‌ی مسیرها را انتخاب می‌کند و Xray همه‌ی قوانین مسیریابی، از جمله قانون api پنل، را نادیده می‌گیرد: اینباند api را به اوت‌باند api بفرستید، وگرنه آمار ترافیک و اعمال زنده‌ی تغییرات کلاینت‌ها متوقف می‌شود. اگر فایل وجود نداشته باشد یا نامعتبر باشد، Xray اجرا نمی‌شود.", + "routingScriptActive": "یک اسکریپت مسیریابی در بخش {section} تنظیم شده است، بنابراین Xray این قوانین را نادیده می‌گیرد." }, "hosts": { "addHost": "افزودن میزبان", diff --git a/internal/web/translation/id-ID.json b/internal/web/translation/id-ID.json index 8ac58554e..0cb4d7e1a 100644 --- a/internal/web/translation/id-ID.json +++ b/internal/web/translation/id-ID.json @@ -2275,7 +2275,11 @@ "clearAll": "Hapus Semua", "clearAllTitle": "Hapus semua server DNS?", "clearAllConfirm": "Ini akan menghapus semua server DNS dari daftar. Tidak dapat dibatalkan.", - "dnsLeakWarning": "DNS dapat bocor lewat localhost, UDP/TCP polos, DoH/DoQ mode lokal, kueri fallback, atau EDNS client IP. Gunakan DoH yang dirutekan, pin resolver di hosts, dan nonaktifkan fallback saat privasi penting." + "dnsLeakWarning": "DNS dapat bocor lewat localhost, UDP/TCP polos, DoH/DoQ mode lokal, kueri fallback, atau EDNS client IP. Gunakan DoH yang dirutekan, pin resolver di hosts, dan nonaktifkan fallback saat privasi penting.", + "script": "Skrip Lua", + "scriptDesc": "Path ke file .lua yang mendefinisikan HandleDNSQuery, absolut atau relatif terhadap folder bin Xray. Skrip lalu menjawab setiap kueri dan hanya menjangkau server melalui kodenya sendiri. Xray tidak akan berjalan jika file tidak ada atau tidak valid.", + "serverId": "ID", + "serverIdDesc": "Nama yang dipakai skrip DNS Lua untuk memilih server ini" }, "fakedns": { "add": "Tambahkan DNS Palsu", @@ -2283,7 +2287,10 @@ "poolSize": "Ukuran Kolam" }, "defaultOutbound": "Outbound default", - "defaultOutboundDesc": "Lalu lintas tanpa aturan routing memakai outbound ini (yang pertama dalam daftar)." + "defaultOutboundDesc": "Lalu lintas tanpa aturan routing memakai outbound ini (yang pertama dalam daftar).", + "routingScript": "Skrip Routing", + "routingScriptDesc": "Path ke file .lua yang mendefinisikan HandleRoute, absolut atau relatif terhadap folder bin Xray. Skrip lalu memilih setiap rute dan Xray mengabaikan semua aturan routing, termasuk aturan api panel: arahkan inbound api ke outbound api atau statistik trafik dan perubahan klien langsung akan berhenti. Xray tidak akan berjalan jika file tidak ada atau tidak valid.", + "routingScriptActive": "Skrip routing diatur di {section}, jadi Xray mengabaikan aturan ini." }, "hosts": { "addHost": "Tambah Host", diff --git a/internal/web/translation/ja-JP.json b/internal/web/translation/ja-JP.json index 98aee605f..442025a20 100644 --- a/internal/web/translation/ja-JP.json +++ b/internal/web/translation/ja-JP.json @@ -2275,7 +2275,11 @@ "clearAll": "すべて削除", "clearAllTitle": "すべての DNS サーバを削除しますか?", "clearAllConfirm": "リストからすべての DNS サーバが削除されます。この操作は元に戻せません。", - "dnsLeakWarning": "DNS は localhost、暗号化なしの UDP/TCP、ローカルモードの DoH/DoQ、フォールバック問い合わせ、EDNS client IP から漏れる可能性があります。プライバシー重視ではルーティングされた DoH、hosts 固定、フォールバック無効化を使ってください。" + "dnsLeakWarning": "DNS は localhost、暗号化なしの UDP/TCP、ローカルモードの DoH/DoQ、フォールバック問い合わせ、EDNS client IP から漏れる可能性があります。プライバシー重視ではルーティングされた DoH、hosts 固定、フォールバック無効化を使ってください。", + "script": "Lua スクリプト", + "scriptDesc": "HandleDNSQuery を定義した .lua ファイルのパス(絶対パス、または Xray の bin フォルダからの相対パス)。設定するとスクリプトがすべてのクエリに応答し、サーバーへはスクリプト自身のコードからのみ問い合わせます。ファイルが存在しないか不正な場合、Xray は起動しません。", + "serverId": "ID", + "serverIdDesc": "Lua DNS スクリプトがこのサーバーを選ぶときの名前" }, "fakedns": { "add": "フェイクDNS追加", @@ -2283,7 +2287,10 @@ "poolSize": "プールサイズ" }, "defaultOutbound": "デフォルトアウトバウンド", - "defaultOutboundDesc": "ルーティング規則に一致しないトラフィックはこのアウトバウンドを使います(一覧の先頭)。" + "defaultOutboundDesc": "ルーティング規則に一致しないトラフィックはこのアウトバウンドを使います(一覧の先頭)。", + "routingScript": "ルーティングスクリプト", + "routingScriptDesc": "HandleRoute を定義した .lua ファイルのパス(絶対パス、または Xray の bin フォルダからの相対パス)。設定するとスクリプトがすべての経路を選び、Xray はパネルの api ルールを含むすべてのルーティングルールを無視します。api インバウンドを api アウトバウンドへ送らないと、トラフィック統計とクライアント変更の即時反映が止まります。ファイルが存在しないか不正な場合、Xray は起動しません。", + "routingScriptActive": "{section} でルーティングスクリプトが設定されているため、Xray はこれらのルールを無視します。" }, "hosts": { "addHost": "ホストを追加", diff --git a/internal/web/translation/pt-BR.json b/internal/web/translation/pt-BR.json index 3b8e36dcf..bbba2b6a4 100644 --- a/internal/web/translation/pt-BR.json +++ b/internal/web/translation/pt-BR.json @@ -2275,7 +2275,11 @@ "clearAll": "Remover Todos", "clearAllTitle": "Remover todos os servidores DNS?", "clearAllConfirm": "Isso remove todos os servidores DNS da lista. Não pode ser desfeito.", - "dnsLeakWarning": "DNS pode vazar por localhost, UDP/TCP sem criptografia, DoH/DoQ em modo local, consultas de fallback ou EDNS client IP. Use DoH roteado, fixe resolvedores em hosts e desative fallback quando privacidade importar." + "dnsLeakWarning": "DNS pode vazar por localhost, UDP/TCP sem criptografia, DoH/DoQ em modo local, consultas de fallback ou EDNS client IP. Use DoH roteado, fixe resolvedores em hosts e desative fallback quando privacidade importar.", + "script": "Script Lua", + "scriptDesc": "Caminho para um arquivo .lua que define HandleDNSQuery, absoluto ou relativo à pasta bin do Xray. O script passa a responder a todas as consultas e só alcança os servidores pelo próprio código. O Xray não inicia se o arquivo estiver ausente ou for inválido.", + "serverId": "ID", + "serverIdDesc": "Nome com que um script DNS em Lua escolhe este servidor" }, "fakedns": { "add": "Adicionar Fake DNS", @@ -2283,7 +2287,10 @@ "poolSize": "Tamanho do Pool" }, "defaultOutbound": "Saída padrão", - "defaultOutboundDesc": "Tráfego sem regra de roteamento usa esta saída (a primeira da lista)." + "defaultOutboundDesc": "Tráfego sem regra de roteamento usa esta saída (a primeira da lista).", + "routingScript": "Script de roteamento", + "routingScriptDesc": "Caminho para um arquivo .lua que define HandleRoute, absoluto ou relativo à pasta bin do Xray. O script passa a escolher cada rota e o Xray ignora todas as regras de roteamento, inclusive a regra api do painel: envie o inbound api para o outbound api ou as estatísticas de tráfego e as alterações de clientes ao vivo param. O Xray não inicia se o arquivo estiver ausente ou for inválido.", + "routingScriptActive": "Há um script de roteamento definido em {section}, então o Xray ignora estas regras." }, "hosts": { "addHost": "Adicionar Host", diff --git a/internal/web/translation/ru-RU.json b/internal/web/translation/ru-RU.json index a438036da..188fb3a6c 100644 --- a/internal/web/translation/ru-RU.json +++ b/internal/web/translation/ru-RU.json @@ -2275,7 +2275,11 @@ "clearAll": "Удалить все", "clearAllTitle": "Удалить все DNS-серверы?", "clearAllConfirm": "Все DNS-серверы будут удалены из списка. Это действие нельзя отменить.", - "dnsLeakWarning": "DNS может утекать через localhost, обычный UDP/TCP, локальный режим DoH/DoQ, fallback-запросы или EDNS client IP. Для приватности используйте маршрутизируемый DoH, закрепляйте резолверы в hosts и отключайте fallback." + "dnsLeakWarning": "DNS может утекать через localhost, обычный UDP/TCP, локальный режим DoH/DoQ, fallback-запросы или EDNS client IP. Для приватности используйте маршрутизируемый DoH, закрепляйте резолверы в hosts и отключайте fallback.", + "script": "Lua-скрипт", + "scriptDesc": "Путь к файлу .lua с функцией HandleDNSQuery — абсолютный или относительно папки bin Xray. Скрипт отвечает на все запросы и обращается к серверам только из своего кода. Xray не запустится, если файл отсутствует или содержит ошибки.", + "serverId": "ID", + "serverIdDesc": "Имя, по которому DNS-скрипт на Lua выбирает этот сервер" }, "fakedns": { "add": "Создать Fake DNS", @@ -2283,7 +2287,10 @@ "poolSize": "Размер пула" }, "defaultOutbound": "Исходящий по умолчанию", - "defaultOutboundDesc": "Трафик без совпадения с правилами маршрутизации идёт через этот исходящий (первый в списке)." + "defaultOutboundDesc": "Трафик без совпадения с правилами маршрутизации идёт через этот исходящий (первый в списке).", + "routingScript": "Скрипт маршрутизации", + "routingScriptDesc": "Путь к файлу .lua с функцией HandleRoute — абсолютный или относительно папки bin Xray. Скрипт выбирает каждый маршрут, а Xray игнорирует все правила маршрутизации, включая правило api панели: направляйте входящий api на исходящий api, иначе остановятся статистика трафика и применение изменений клиентов на лету. Xray не запустится, если файл отсутствует или содержит ошибки.", + "routingScriptActive": "В разделе «{section}» задан скрипт маршрутизации, поэтому Xray игнорирует эти правила." }, "hosts": { "addHost": "Добавить хост", diff --git a/internal/web/translation/tr-TR.json b/internal/web/translation/tr-TR.json index 8ce5bac44..bd26b91c9 100644 --- a/internal/web/translation/tr-TR.json +++ b/internal/web/translation/tr-TR.json @@ -2275,7 +2275,11 @@ "clearAll": "Tümünü Sil", "clearAllTitle": "Tüm DNS sunucularını sil?", "clearAllConfirm": "Bu işlem tüm DNS sunucularını listeden kaldırır. Geri alınamaz.", - "dnsLeakWarning": "DNS; localhost, düz UDP/TCP, yerel mod DoH/DoQ, fallback sorguları veya EDNS client IP üzerinden sızabilir. Gizlilik önemliyse yönlendirilmiş DoH, hosts sabitlemeleri ve kapalı fallback kullanın." + "dnsLeakWarning": "DNS; localhost, düz UDP/TCP, yerel mod DoH/DoQ, fallback sorguları veya EDNS client IP üzerinden sızabilir. Gizlilik önemliyse yönlendirilmiş DoH, hosts sabitlemeleri ve kapalı fallback kullanın.", + "script": "Lua Betiği", + "scriptDesc": "HandleDNSQuery tanımlayan bir .lua dosyasının yolu; mutlak ya da Xray bin klasörüne göre göreli. Betik bundan sonra her sorguyu yanıtlar ve sunuculara yalnızca kendi koduyla ulaşır. Dosya yoksa veya geçersizse Xray başlamaz.", + "serverId": "Kimlik", + "serverIdDesc": "Bir Lua DNS betiğinin bu sunucuyu seçerken kullandığı ad" }, "fakedns": { "add": "Sahte DNS Ekle", @@ -2283,7 +2287,10 @@ "poolSize": "Havuz Boyutu" }, "defaultOutbound": "Varsayılan giden", - "defaultOutboundDesc": "Yönlendirme kuralıyla eşleşmeyen trafik bu gideni kullanır (listedeki ilk giden)." + "defaultOutboundDesc": "Yönlendirme kuralıyla eşleşmeyen trafik bu gideni kullanır (listedeki ilk giden).", + "routingScript": "Yönlendirme Betiği", + "routingScriptDesc": "HandleRoute tanımlayan bir .lua dosyasının yolu; mutlak ya da Xray bin klasörüne göre göreli. Betik bundan sonra her rotayı seçer ve Xray, panelin api kuralı dahil tüm yönlendirme kurallarını yok sayar: api gelen bağlantısını api giden bağlantısına yönlendirin, yoksa trafik istatistikleri ve canlı istemci değişiklikleri durur. Dosya yoksa veya geçersizse Xray başlamaz.", + "routingScriptActive": "{section} bölümünde bir yönlendirme betiği ayarlı, bu yüzden Xray bu kuralları yok sayar." }, "hosts": { "addHost": "Host Ekle", diff --git a/internal/web/translation/uk-UA.json b/internal/web/translation/uk-UA.json index 9ac1da9b8..d88d1a8bc 100644 --- a/internal/web/translation/uk-UA.json +++ b/internal/web/translation/uk-UA.json @@ -2275,7 +2275,11 @@ "clearAll": "Видалити всі", "clearAllTitle": "Видалити всі DNS-сервери?", "clearAllConfirm": "Усі DNS-сервери буде видалено зі списку. Дію не можна скасувати.", - "dnsLeakWarning": "DNS може витікати через localhost, звичайний UDP/TCP, локальний режим DoH/DoQ, fallback-запити або EDNS client IP. Для приватності використовуйте маршрутизований DoH, фіксацію hosts і вимикайте fallback." + "dnsLeakWarning": "DNS може витікати через localhost, звичайний UDP/TCP, локальний режим DoH/DoQ, fallback-запити або EDNS client IP. Для приватності використовуйте маршрутизований DoH, фіксацію hosts і вимикайте fallback.", + "script": "Lua-скрипт", + "scriptDesc": "Шлях до файлу .lua з функцією HandleDNSQuery — абсолютний або відносно теки bin Xray. Скрипт відповідає на всі запити й звертається до серверів лише зі свого коду. Xray не запуститься, якщо файл відсутній або містить помилки.", + "serverId": "ID", + "serverIdDesc": "Ім'я, за яким DNS-скрипт на Lua вибирає цей сервер" }, "fakedns": { "add": "Додати підроблений DNS", @@ -2283,7 +2287,10 @@ "poolSize": "Розмір пулу" }, "defaultOutbound": "Вихідний за замовчуванням", - "defaultOutboundDesc": "Трафік без збігу з правилами маршрутизації йде через цей вихідний (перший у списку)." + "defaultOutboundDesc": "Трафік без збігу з правилами маршрутизації йде через цей вихідний (перший у списку).", + "routingScript": "Скрипт маршрутизації", + "routingScriptDesc": "Шлях до файлу .lua з функцією HandleRoute — абсолютний або відносно теки bin Xray. Скрипт обирає кожен маршрут, а Xray ігнорує всі правила маршрутизації, зокрема правило api панелі: спрямовуйте вхідний api на вихідний api, інакше зупиниться статистика трафіку й застосування змін клієнтів на льоту. Xray не запуститься, якщо файл відсутній або містить помилки.", + "routingScriptActive": "У розділі «{section}» задано скрипт маршрутизації, тому Xray ігнорує ці правила." }, "hosts": { "addHost": "Додати хост", diff --git a/internal/web/translation/vi-VN.json b/internal/web/translation/vi-VN.json index aba0dd526..8482698b5 100644 --- a/internal/web/translation/vi-VN.json +++ b/internal/web/translation/vi-VN.json @@ -2275,7 +2275,11 @@ "clearAll": "Xóa tất cả", "clearAllTitle": "Xóa tất cả máy chủ DNS?", "clearAllConfirm": "Thao tác này sẽ xóa toàn bộ máy chủ DNS khỏi danh sách. Không thể hoàn tác.", - "dnsLeakWarning": "DNS có thể rò rỉ qua localhost, UDP/TCP không mã hóa, DoH/DoQ chế độ cục bộ, truy vấn fallback hoặc EDNS client IP. Hãy dùng DoH được định tuyến, ghim resolver trong hosts và tắt fallback khi cần riêng tư." + "dnsLeakWarning": "DNS có thể rò rỉ qua localhost, UDP/TCP không mã hóa, DoH/DoQ chế độ cục bộ, truy vấn fallback hoặc EDNS client IP. Hãy dùng DoH được định tuyến, ghim resolver trong hosts và tắt fallback khi cần riêng tư.", + "script": "Script Lua", + "scriptDesc": "Đường dẫn tới tệp .lua định nghĩa HandleDNSQuery, tuyệt đối hoặc tương đối với thư mục bin của Xray. Khi đó script trả lời mọi truy vấn và chỉ dùng các máy chủ qua mã của chính nó. Xray sẽ không khởi động nếu tệp không tồn tại hoặc không hợp lệ.", + "serverId": "ID", + "serverIdDesc": "Tên mà script DNS Lua dùng để chọn máy chủ này" }, "fakedns": { "add": "Thêm DNS giả", @@ -2283,7 +2287,10 @@ "poolSize": "Kích thước bể bơi" }, "defaultOutbound": "Outbound mặc định", - "defaultOutboundDesc": "Lưu lượng không khớp quy tắc định tuyến dùng outbound này (mục đầu danh sách)." + "defaultOutboundDesc": "Lưu lượng không khớp quy tắc định tuyến dùng outbound này (mục đầu danh sách).", + "routingScript": "Script định tuyến", + "routingScriptDesc": "Đường dẫn tới tệp .lua định nghĩa HandleRoute, tuyệt đối hoặc tương đối với thư mục bin của Xray. Khi đó script chọn mọi tuyến và Xray bỏ qua tất cả quy tắc định tuyến, kể cả quy tắc api của panel: hãy chuyển inbound api tới outbound api, nếu không thống kê lưu lượng và việc áp dụng thay đổi client trực tiếp sẽ dừng. Xray sẽ không khởi động nếu tệp không tồn tại hoặc không hợp lệ.", + "routingScriptActive": "Một script định tuyến đã được đặt trong {section}, nên Xray bỏ qua các quy tắc này." }, "hosts": { "addHost": "Thêm Host", diff --git a/internal/web/translation/zh-CN.json b/internal/web/translation/zh-CN.json index 2c6e8f1a2..3ed919c00 100644 --- a/internal/web/translation/zh-CN.json +++ b/internal/web/translation/zh-CN.json @@ -2275,7 +2275,11 @@ "clearAll": "删除全部", "clearAllTitle": "删除所有 DNS 服务器?", "clearAllConfirm": "此操作将从列表中删除所有 DNS 服务器,且无法撤销。", - "dnsLeakWarning": "DNS 可能通过 localhost、明文 UDP/TCP、本地模式 DoH/DoQ、回退查询或 EDNS client IP 泄漏。重视隐私时请使用经路由的 DoH、在 hosts 中固定解析器,并禁用回退。" + "dnsLeakWarning": "DNS 可能通过 localhost、明文 UDP/TCP、本地模式 DoH/DoQ、回退查询或 EDNS client IP 泄漏。重视隐私时请使用经路由的 DoH、在 hosts 中固定解析器,并禁用回退。", + "script": "Lua 脚本", + "scriptDesc": "定义了 HandleDNSQuery 的 .lua 文件路径,可为绝对路径或相对于 Xray bin 目录的路径。设置后由脚本应答所有查询,只通过脚本自身的代码访问服务器。文件不存在或无效时 Xray 无法启动。", + "serverId": "ID", + "serverIdDesc": "Lua DNS 脚本用来选择此服务器的名称" }, "fakedns": { "add": "添加假 DNS", @@ -2283,7 +2287,10 @@ "poolSize": "池大小" }, "defaultOutbound": "默认出站", - "defaultOutboundDesc": "未匹配任何路由规则的流量走此出站(列表中的第一个出站)。" + "defaultOutboundDesc": "未匹配任何路由规则的流量走此出站(列表中的第一个出站)。", + "routingScript": "路由脚本", + "routingScriptDesc": "定义了 HandleRoute 的 .lua 文件路径,可为绝对路径或相对于 Xray bin 目录的路径。设置后由脚本选择所有路由,Xray 会忽略全部路由规则,包括面板的 api 规则:请把 api 入站路由到 api 出站,否则流量统计和客户端变更的实时生效都会停止。文件不存在或无效时 Xray 无法启动。", + "routingScriptActive": "已在“{section}”中设置路由脚本,因此 Xray 会忽略这些规则。" }, "hosts": { "addHost": "添加主机", diff --git a/internal/web/translation/zh-TW.json b/internal/web/translation/zh-TW.json index 859569342..718e052c0 100644 --- a/internal/web/translation/zh-TW.json +++ b/internal/web/translation/zh-TW.json @@ -2275,7 +2275,11 @@ "clearAll": "全部刪除", "clearAllTitle": "刪除所有 DNS 伺服器?", "clearAllConfirm": "此操作將從清單中刪除所有 DNS 伺服器,無法復原。", - "dnsLeakWarning": "DNS 可能透過 localhost、明文 UDP/TCP、本機模式 DoH/DoQ、回退查詢或 EDNS client IP 洩漏。重視隱私時請使用經路由的 DoH、在 hosts 固定解析器,並停用回退。" + "dnsLeakWarning": "DNS 可能透過 localhost、明文 UDP/TCP、本機模式 DoH/DoQ、回退查詢或 EDNS client IP 洩漏。重視隱私時請使用經路由的 DoH、在 hosts 固定解析器,並停用回退。", + "script": "Lua 腳本", + "scriptDesc": "定義了 HandleDNSQuery 的 .lua 檔案路徑,可為絕對路徑或相對於 Xray bin 資料夾的路徑。設定後由腳本回應所有查詢,只透過腳本自身的程式碼存取伺服器。檔案不存在或無效時 Xray 無法啟動。", + "serverId": "ID", + "serverIdDesc": "Lua DNS 腳本用來選擇此伺服器的名稱" }, "fakedns": { "add": "新增假 DNS", @@ -2283,7 +2287,10 @@ "poolSize": "池大小" }, "defaultOutbound": "預設出站", - "defaultOutboundDesc": "未符合任何路由規則的流量走此出站(清單中的第一個出站)。" + "defaultOutboundDesc": "未符合任何路由規則的流量走此出站(清單中的第一個出站)。", + "routingScript": "路由腳本", + "routingScriptDesc": "定義了 HandleRoute 的 .lua 檔案路徑,可為絕對路徑或相對於 Xray bin 資料夾的路徑。設定後由腳本選擇所有路由,Xray 會忽略全部路由規則,包括面板的 api 規則:請將 api 入站路由到 api 出站,否則流量統計與用戶端變更的即時套用都會停止。檔案不存在或無效時 Xray 無法啟動。", + "routingScriptActive": "已在「{section}」中設定路由腳本,因此 Xray 會忽略這些規則。" }, "hosts": { "addHost": "新增 Host",