feat(amneziawg): complete frontend parity for the Inbounds list page

The Clients page (form, CRUD, QR/config) already worked from the
prior commit; this closes the remaining gap on the Inbounds side and
in a couple of protocol allowlists that a plain search for existing
wireguard/mtproto handling turned up.

lib/xray/inbound-link.ts gets amneziawg-specific link/config builders
(genAmneziaWGLink/genAmneziaWGConfig, plus the *s fan-out variants)
mirroring the wireguard ones — AmneziaWG has no legacy peers-array to
fall back to, so these read settings.clients directly and add the
obfuscation lines every client must share with the server. Wired into
genInboundLinks generically, and into three consumers that call the
wireguard builders directly rather than through that dispatcher:
QrCodeModal, InboundInfoModal, and InboundsPage's bulk export.

ClientInfoModal, ClientBulkAddModal, and the bulk attach/detach modals
each had their own protocol allowlist that needed amneziawg added
alongside wireguard/mtproto.

Two real gaps surfaced by grepping every remaining 'wireguard' /
Protocols.WIREGUARD hit in frontend/src rather than trusting the
checklist was exhaustive:
- useInbounds.ts's TRACKED_PROTOCOLS gates the deactive/depleted/
  expiring/online client counts shown per inbound on the list page;
  without amneziawg those counts would silently read zero.
- inbound-tag.ts is an explicit client-side mirror of the Go backend's
  port_conflict.go (the file says so itself: "Keep in sync"). It still
  only special-cased wireguard for UDP, so an amneziawg inbound would
  have fallen through to the TCP default and disagreed with the
  backend's own port-conflict math.

Also finishes translating the AmneziaWG UI strings into the 11 locale
files that were still falling back to English (ar-EG, es-ES, fa-IR,
id-ID, ja-JP, pt-BR, tr-TR, uk-UA, vi-VN, zh-CN, zh-TW), matching
en-US/ru-RU key-for-key (26 new keys, verified by count in every file).

Not run anywhere: npm run typecheck / build. This machine has neither
Node nor npm, so nothing here has compiled — reviewed by hand plus
brace/paren balance checks and cross-referencing the generated Zod/TS
types. Treat this as needing a real typecheck before shipping.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kuzz007
2026-07-25 02:06:03 +03:00
parent 19082fdfe9
commit 266f40d79f
22 changed files with 614 additions and 9 deletions
+133 -1
View File
@@ -1,6 +1,7 @@
import { Base64, Wireguard } from '@/utils';
import type { Inbound } from '@/schemas/api/inbound';
import type { AmneziawgInboundSettings } from '@/schemas/protocols/inbound/amneziawg';
import type { VlessClient } from '@/schemas/protocols/inbound/vless';
import type { VmessSecurity } from '@/schemas/protocols/shared/vmess';
import type {
@@ -869,6 +870,134 @@ export function genWireguardConfig(input: GenWireguardLinkInput): string {
return txt;
}
// Shared input shape for both the per-client amneziawg:// link and .conf
// builders below — settings.clients (not a peers array; unlike WireGuard,
// AmneziaWG was multi-client from day one, so there's no legacy format).
export interface GenAmneziaWGLinkInput {
settings: AmneziawgInboundSettings;
address: string;
port: number;
remark?: string;
peerIndex: number;
}
function amneziaWGHLine(key: string, value: string | undefined, fallback: string): string {
return `${key} = ${value && value.trim() !== '' ? value : fallback}`;
}
// AmneziaWG share link: amneziawg://<clientPrivKey>@<host>:<port>
// ?publickey=<serverPub>&address=<clientAllowedIP>&mtu=<mtu>#<remark>
// Unlike WireGuard, the server's publicKey is a real persisted field (not
// derived from a secretKey at call time), so this just reads it straight off
// settings.server. Mirrors genWireguardLink.
export function genAmneziaWGLink(input: GenAmneziaWGLinkInput): string {
const { settings, address, port, remark = '', peerIndex } = input;
const client = settings.clients[peerIndex];
if (!client) return '';
const server = settings.server;
const url = new URL(`amneziawg://${formatUrlHost(address)}:${port}`);
url.username = client.privateKey ?? '';
if (server.publicKey.length > 0) url.searchParams.set('publickey', server.publicKey);
if ((client.allowedIPs ?? []).length > 0) {
url.searchParams.set('address', client.allowedIPs.join(','));
}
if (typeof server.mtu === 'number' && server.mtu > 0) {
url.searchParams.set('mtu', String(server.mtu));
}
url.hash = encodeURIComponent(remark);
return url.toString();
}
// Plain-text AmneziaWG client config (.conf format). Mirrors
// genWireguardConfig, plus the obfuscation lines every AmneziaWG client must
// share with the server (see internal/amneziawg.writeObfuscation on the Go
// side).
export function genAmneziaWGConfig(input: GenAmneziaWGLinkInput): string {
const { settings, address, port, remark = '', peerIndex } = input;
const client = settings.clients[peerIndex];
if (!client) return '';
const server = settings.server;
let txt = `[Interface]\n`;
txt += `PrivateKey = ${client.privateKey ?? ''}\n`;
txt += `Address = ${(client.allowedIPs ?? []).join(', ')}\n`;
const dns = [server.primaryDns, server.secondaryDns].filter((v) => !!v && v.trim() !== '');
if (dns.length > 0) txt += `DNS = ${dns.join(', ')}\n`;
if (typeof server.mtu === 'number' && server.mtu > 0) {
txt += `MTU = ${server.mtu}\n`;
}
txt += `Jc = ${server.jc}\n`;
txt += `Jmin = ${server.jmin}\n`;
txt += `Jmax = ${server.jmax}\n`;
txt += `S1 = ${server.s1}\n`;
txt += `S2 = ${server.s2}\n`;
if (server.s3) txt += `S3 = ${server.s3}\n`;
if (server.s4) txt += `S4 = ${server.s4}\n`;
txt += `${amneziaWGHLine('H1', server.h1, '1')}\n`;
txt += `${amneziaWGHLine('H2', server.h2, '2')}\n`;
txt += `${amneziaWGHLine('H3', server.h3, '3')}\n`;
txt += `${amneziaWGHLine('H4', server.h4, '4')}\n`;
if (server.i1) txt += `I1 = ${server.i1}\n`;
txt += `\n# ${remark}\n`;
txt += `[Peer]\n`;
txt += `PublicKey = ${server.publicKey ?? ''}\n`;
txt += `AllowedIPs = 0.0.0.0/0, ::/0\n`;
txt += `Endpoint = ${address}:${port}`;
if (client.preSharedKey && client.preSharedKey.length > 0) {
txt += `\nPresharedKey = ${client.preSharedKey}`;
}
if (typeof client.keepAlive === 'number' && client.keepAlive > 0) {
txt += `\nPersistentKeepalive = ${client.keepAlive}\n`;
}
return txt;
}
export interface GenAmneziaWGFanoutInput {
inbound: Inbound;
remark?: string;
hostOverride?: string;
fallbackHostname: string;
}
export function genAmneziaWGLinks(input: GenAmneziaWGFanoutInput): string {
const { inbound, remark = '', hostOverride = '', fallbackHostname } = input;
if (inbound.protocol !== 'amneziawg') return '';
const addr = resolveAddr(inbound, hostOverride, fallbackHostname);
const sep = '-';
const settings = inbound.settings as AmneziawgInboundSettings;
const clients = settings.clients ?? [];
return clients
.map((c, i) => genAmneziaWGLink({
settings,
address: addr,
port: inbound.port,
remark: `${remark}${sep}${i + 1}${wgPeerCommentSuffix(c)}`,
peerIndex: i,
}))
.join('\r\n');
}
export function genAmneziaWGConfigs(input: GenAmneziaWGFanoutInput): string {
const { inbound, remark = '', hostOverride = '', fallbackHostname } = input;
if (inbound.protocol !== 'amneziawg') return '';
const addr = resolveAddr(inbound, hostOverride, fallbackHostname);
const sep = '-';
const settings = inbound.settings as AmneziawgInboundSettings;
const clients = settings.clients ?? [];
return clients
.map((c, i) => genAmneziaWGConfig({
settings,
address: addr,
port: inbound.port,
remark: `${remark}${sep}${i + 1}${wgPeerCommentSuffix(c)}`,
peerIndex: i,
}))
.join('\r\n');
}
export function wireguardConfigFromLink(link: string, fallbackRemark = ''): string {
let url: URL;
try {
@@ -1201,7 +1330,7 @@ export interface GenInboundLinksInput {
// Top-level entrypoint that produces the full \r\n-joined block a user
// pastes into a client. Iterates per-client for protocols with clients,
// falls back to a single SS link for single-user 2022-blake3-chacha20,
// and emits per-peer .conf blocks for wireguard. Returns '' for the
// and emits per-peer .conf blocks for wireguard and amneziawg. Returns '' for the
// other clientless protocols (http, mixed, tunnel).
export function genInboundLinks(input: GenInboundLinksInput): string {
const {
@@ -1226,6 +1355,9 @@ export function genInboundLinks(input: GenInboundLinksInput): string {
if (inbound.protocol === 'wireguard') {
return genWireguardConfigs({ inbound, remark, hostOverride, fallbackHostname });
}
if (inbound.protocol === 'amneziawg') {
return genAmneziaWGConfigs({ inbound, remark, hostOverride, fallbackHostname });
}
return '';
}
+1 -1
View File
@@ -14,7 +14,7 @@ function inboundTransports(
streamSettings: Record<string, unknown> | undefined,
settings: Record<string, unknown> | undefined,
): TransportBits {
if (protocol === 'hysteria' || protocol === 'wireguard') return UDP;
if (protocol === 'hysteria' || protocol === 'wireguard' || protocol === 'amneziawg') return UDP;
let bits: TransportBits = 0;
const network = asString(streamSettings?.network);
@@ -7,7 +7,7 @@ import type { InboundOption } from '@/hooks/useClients';
import { formatInboundLabel } from '@/lib/inbounds/label';
import type { BulkAttachResult } from '@/schemas/client';
const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks', 'wireguard', 'mtproto']);
const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks', 'wireguard', 'mtproto', 'amneziawg']);
interface BulkAttachInboundsModalProps {
open: boolean;
@@ -7,7 +7,7 @@ import type { InboundOption } from '@/hooks/useClients';
import { formatInboundLabel } from '@/lib/inbounds/label';
import type { BulkDetachResult } from '@/schemas/client';
const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks', 'wireguard', 'mtproto']);
const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks', 'wireguard', 'mtproto', 'amneziawg']);
interface BulkDetachInboundsModalProps {
open: boolean;
@@ -18,7 +18,7 @@ import { ClientBulkAddFormSchema, type ClientBulkAddFormValues } from '@/schemas
const FLOW_OPTIONS = Object.values(TLS_FLOW_CONTROL);
const MULTI_CLIENT_PROTOCOLS = new Set([
'shadowsocks', 'vless', 'vmess', 'trojan', 'hysteria', 'wireguard',
'shadowsocks', 'vless', 'vmess', 'trojan', 'hysteria', 'wireguard', 'amneziawg',
]);
const EMPTY: ClientBulkAddFormValues = {
@@ -13,6 +13,7 @@ import { LinkTags, linkMetaText, parseLinkParts } from '@/lib/xray/link-label';
import { QrPanel } from '@/pages/inbounds/qr';
import ConfigBlock from '@/components/clients/ConfigBlock';
import { buildWireguardClientConfig, findWireguardInbound, isWireguardClient } from './wireguardConfig';
import { buildAmneziaWGClientConfig, findAmneziaWGInbound, isAmneziaWGClient } from './amneziawgConfig';
import './ClientInfoModal.css';
const INBOUND_PROTOCOL_COLORS: Record<string, string> = {
@@ -23,6 +24,7 @@ const INBOUND_PROTOCOL_COLORS: Record<string, string> = {
hysteria: 'cyan',
hysteria2: 'green',
wireguard: 'gold',
amneziawg: 'yellow',
http: 'purple',
mixed: 'lime',
tunnel: 'orange',
@@ -149,6 +151,12 @@ export default function ClientInfoModal({
return buildWireguardClientConfig(client, wgInbound, window.location.hostname, subSettings?.publicHost ?? '');
}, [client, wgInbound, subSettings?.publicHost]);
const awgInbound = useMemo(() => findAmneziaWGInbound(client, inboundsById), [client, inboundsById]);
const awgConfigText = useMemo(() => {
if (!client || !awgInbound || !isAmneziaWGClient(client)) return '';
return buildAmneziaWGClientConfig(client, awgInbound, window.location.hostname, subSettings?.publicHost ?? '');
}, [client, awgInbound, subSettings?.publicHost]);
async function copyValue(text: string) {
if (!text) return;
const ok = await ClipboardManager.copyText(String(text));
@@ -538,6 +546,18 @@ export default function ClientInfoModal({
/>
</>
)}
{awgConfigText && client && (
<>
<Divider>{t('pages.clients.amneziaWgConfig')}</Divider>
<ConfigBlock
label={t('pages.clients.config')}
text={awgConfigText}
fileName={`${client.email}.conf`}
qrRemark={client.email || 'peer'}
/>
</>
)}
</>
)}
</Modal>
+8 -2
View File
@@ -24,8 +24,9 @@ import {
import { HttpUtil, SizeFormatter, RandomUtil } from '@/utils';
import { createDefaultInboundSettings } from '@/lib/xray/inbound-defaults';
import { genInboundLinks, genWireguardLinks, preferPublicHost } from '@/lib/xray/inbound-link';
import { genAmneziaWGLinks, genInboundLinks, genWireguardLinks, preferPublicHost } from '@/lib/xray/inbound-link';
import { inboundFromDb } from '@/lib/xray/inbound-from-db';
import { Protocols } from '@/schemas/primitives';
import { coerceInboundJsonField, type DBInbound } from '@/models/dbinbound';
import { useTheme } from '@/hooks/useTheme';
import { useMediaQuery } from '@/hooks/useMediaQuery';
@@ -274,7 +275,12 @@ export default function InboundsPage() {
{ key: 'config', label: t('pages.clients.config'), content },
{ key: 'links', label: t('pages.clients.tabLinks'), content: genWireguardLinks(genInput) },
]
: undefined;
: projected.protocol === Protocols.AMNEZIAWG
? [
{ key: 'config', label: t('pages.clients.config'), content },
{ key: 'links', label: t('pages.clients.tabLinks'), content: genAmneziaWGLinks(genInput) },
]
: undefined;
openText({
title: t('pages.inbounds.exportLinksTitle'),
content,
@@ -10,6 +10,8 @@ import { InfinityIcon } from '@/components/ui';
import { useDatepicker } from '@/hooks/useDatepicker';
import {
genAllLinks,
genAmneziaWGConfigs,
genAmneziaWGLinks,
genWireguardConfigs,
genWireguardLinks,
preferPublicHost,
@@ -49,6 +51,8 @@ export default function InboundInfoModal({
const [links, setLinks] = useState<{ remark?: string; link: string }[]>([]);
const [wireguardConfigs, setWireguardConfigs] = useState<string[]>([]);
const [wireguardLinks, setWireguardLinks] = useState<string[]>([]);
const [amneziawgConfigs, setAmneziawgConfigs] = useState<string[]>([]);
const [amneziawgLinks, setAmneziawgLinks] = useState<string[]>([]);
const [subLink, setSubLink] = useState('');
const [subJsonLink, setSubJsonLink] = useState('');
const [refreshing, setRefreshing] = useState(false);
@@ -132,6 +136,28 @@ export default function InboundInfoModal({
fallbackHostname,
}).split('\r\n'),
);
setAmneziawgConfigs([]);
setAmneziawgLinks([]);
setLinks([]);
} else if (info.protocol === Protocols.AMNEZIAWG) {
setAmneziawgConfigs(
genAmneziaWGConfigs({
inbound: inboundForLinks,
remark: dbInbound.remark,
hostOverride: nodeAddress,
fallbackHostname,
}).split('\r\n'),
);
setAmneziawgLinks(
genAmneziaWGLinks({
inbound: inboundForLinks,
remark: dbInbound.remark,
hostOverride: nodeAddress,
fallbackHostname,
}).split('\r\n'),
);
setWireguardConfigs([]);
setWireguardLinks([]);
setLinks([]);
} else {
setLinks(
@@ -145,6 +171,8 @@ export default function InboundInfoModal({
);
setWireguardConfigs([]);
setWireguardLinks([]);
setAmneziawgConfigs([]);
setAmneziawgLinks([]);
}
if (clientSet?.subId) {
@@ -851,6 +879,41 @@ export default function InboundInfoModal({
</>
)}
{inbound?.protocol === Protocols.AMNEZIAWG && amneziawgConfigs.length > 0 && (
<>
<Divider>{t('pages.inbounds.copyLink')}</Divider>
{amneziawgConfigs.map((cfg, idx) => (
<Fragment key={idx}>
{cfg && (
<div className="link-panel">
<div className="link-panel-header">
<Tag color="green">{t('pages.inbounds.info.peerNumberConfig', { n: idx + 1 })}</Tag>
<Tooltip title={t('copy')}>
<Button size="small" icon={<CopyOutlined />} aria-label={t('copy')} onClick={() => copyText(cfg, t)} />
</Tooltip>
<Tooltip title={t('download')}>
<Button size="small" icon={<DownloadOutlined />} aria-label={t('download')} onClick={() => downloadText(cfg, `peer-${idx + 1}.conf`)} />
</Tooltip>
</div>
<code className="link-panel-text">{cfg}</code>
</div>
)}
{amneziawgLinks[idx] && (
<div className="link-panel">
<div className="link-panel-header">
<Tag color="green">Peer {idx + 1} link</Tag>
<Tooltip title={t('copy')}>
<Button size="small" icon={<CopyOutlined />} aria-label={t('copy')} onClick={() => copyText(amneziawgLinks[idx], t)} />
</Tooltip>
</div>
<code className="link-panel-text">{amneziawgLinks[idx]}</code>
</div>
)}
</Fragment>
))}
</>
)}
{dbInbound.isSS && !inbound.isSSMultiUser && links.length > 0 && (
<>
<Divider>{t('pages.inbounds.copyLink')}</Divider>
+43 -1
View File
@@ -6,6 +6,8 @@ import type { CollapseProps } from 'antd';
import { Protocols } from '@/schemas/primitives';
import {
genAllLinks,
genAmneziaWGConfigs,
genAmneziaWGLinks,
genWireguardConfigs,
genWireguardLinks,
isPostQuantumLink,
@@ -50,6 +52,8 @@ export default function QrCodeModal({
const [links, setLinks] = useState<{ remark?: string; link: string }[]>([]);
const [wireguardConfigs, setWireguardConfigs] = useState<string[]>([]);
const [wireguardLinks, setWireguardLinks] = useState<string[]>([]);
const [amneziawgConfigs, setAmneziawgConfigs] = useState<string[]>([]);
const [amneziawgLinks, setAmneziawgLinks] = useState<string[]>([]);
const [subLink, setSubLink] = useState('');
const [subJsonLink, setSubJsonLink] = useState('');
const [activeKey, setActiveKey] = useState<string[]>([]);
@@ -78,6 +82,31 @@ export default function QrCodeModal({
fallbackHostname,
}).split('\r\n'),
);
setAmneziawgConfigs([]);
setAmneziawgLinks([]);
setLinks([]);
} else if (inbound.protocol === Protocols.AMNEZIAWG) {
const peerRemark = client?.email
? `${dbInbound.remark}-${client.email}`
: dbInbound.remark || '';
setAmneziawgConfigs(
genAmneziaWGConfigs({
inbound,
remark: peerRemark,
hostOverride: nodeAddress,
fallbackHostname,
}).split('\r\n'),
);
setAmneziawgLinks(
genAmneziaWGLinks({
inbound,
remark: peerRemark,
hostOverride: nodeAddress,
fallbackHostname,
}).split('\r\n'),
);
setWireguardConfigs([]);
setWireguardLinks([]);
setLinks([]);
} else {
setLinks(
@@ -91,6 +120,8 @@ export default function QrCodeModal({
);
setWireguardConfigs([]);
setWireguardLinks([]);
setAmneziawgConfigs([]);
setAmneziawgLinks([]);
}
const subId = client?.subId;
@@ -126,8 +157,19 @@ export default function QrCodeModal({
items.push({ key: `wl${idx}`, header: `Peer ${idx + 1} link`, value: wireguardLinks[idx], showQr: false });
}
});
amneziawgConfigs.forEach((cfg, idx) => {
items.push({
key: `ac${idx}`,
header: `Peer ${idx + 1} config`,
value: cfg,
downloadName: `peer-${idx + 1}.conf`,
});
if (amneziawgLinks[idx]) {
items.push({ key: `al${idx}`, header: `Peer ${idx + 1} link`, value: amneziawgLinks[idx], showQr: false });
}
});
return items;
}, [subLink, subJsonLink, links, wireguardConfigs, wireguardLinks, t]);
}, [subLink, subJsonLink, links, wireguardConfigs, wireguardLinks, amneziawgConfigs, amneziawgLinks, t]);
const collapseItems: CollapseProps['items'] = useMemo(
() => qrItems.map((item) => ({
@@ -62,6 +62,7 @@ const TRACKED_PROTOCOLS: readonly string[] = [
Protocols.HYSTERIA,
Protocols.WIREGUARD,
Protocols.MTPROTO,
Protocols.AMNEZIAWG,
];
async function fetchSlimInbounds(): Promise<unknown[]> {
+1 -1
View File
@@ -7,7 +7,7 @@ import { NetworkSettingsSchema, StreamExtrasSchema } from '@/schemas/protocols/s
// Top-level inbound shape on the wire. Composes:
// - Per-protocol settings via the InboundSettingsSchema discriminated
// union (10 protocols, tagged-wrapper {protocol, settings}).
// union (11 protocols, tagged-wrapper {protocol, settings}).
// - StreamSettings as an intersection of the network DU (6 branches),
// security DU (3 branches), and the orthogonal extras (finalmask,
// sockopt, externalProxy). Zod 4 supports DU intersection — each
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "مفتاح وايرغارد المشترك مسبقًا",
"wireguardAllowedIPs": "عناوين IP المسموحة لوايرغارد",
"wireguardAllowedIPsHint": "اتركه فارغًا للتعيين التلقائي؛ افصل بين الإدخالات بفواصل",
"amneziaWgPrivateKey": "مفتاح AmneziaWG الخاص",
"amneziaWgPublicKey": "مفتاح AmneziaWG العام",
"amneziaWgPreSharedKey": "مفتاح AmneziaWG المشترك مسبقًا",
"amneziaWgAllowedIPs": "عناوين IP المسموحة لـ AmneziaWG",
"amneziaWgAllowedIPsHint": "اتركه فارغًا للتعيين التلقائي؛ افصل بين الإدخالات بفواصل",
"amneziaWgConfig": "إعدادات AmneziaWG",
"mtprotoSecret": "سر MTProto",
"mtprotoSecretHint": "سر FakeTLS الخاص بالعميل. أعد التوليد لتغييره.",
"mtprotoAdTag": "علامة إعلانية (قناة مموّلة)",
@@ -1800,6 +1806,31 @@
"psk": "المفتاح المشترك",
"domainStrategy": "استراتيجية الدومين"
},
"amneziawg": {
"privateKey": "المفتاح الخاص",
"publicKey": "المفتاح العام",
"subnetIp": "الشبكة الفرعية",
"subnetCidr": "بادئة الشبكة الفرعية (CIDR)",
"mtu": "الحد الأقصى لوحدة النقل (MTU)",
"primaryDns": "DNS الأساسي",
"secondaryDns": "DNS الثانوي",
"externalInterface": "الواجهة الخارجية",
"externalInterfaceHint": "واجهة الشبكة على الخادم المستخدمة لـ NAT (PostUp/PostDown). اتركها فارغة للاكتشاف التلقائي.",
"jc": "Jc (عدد الحزم العشوائية)",
"jmin": "Jmin (الحد الأدنى لحجم الحزمة العشوائية)",
"jmax": "Jmax (الحد الأقصى لحجم الحزمة العشوائية)",
"s1": "S1 (حجم حشو حزمة init)",
"s2": "S2 (حجم حشو حزمة response)",
"s3": "S3 (حشو رد الكوكي، 2.0)",
"s4": "S4 (حشو حزمة النقل، 2.0)",
"h1": "H1 (رأس سحري)",
"h2": "H2 (رأس سحري)",
"h3": "H3 (رأس سحري)",
"h4": "H4 (رأس سحري)",
"hHint": "رقم واحد أو نطاق. اتركه فارغًا للقيم الافتراضية الكلاسيكية 1/2/3/4.",
"i1": "I1 (حزمة التوقيع، 2.0)",
"i1Hint": "خاص بـ AmneziaWG 2.0 فقط. اتركه فارغًا للتوافق مع الإصدار 1.x."
},
"tun": {
"nameDesc": "اسم واجهة TUN. القيمة الافتراضية هي 'xray0'",
"mtuDesc": "وحدة النقل الأقصى. الحد الأقصى لحجم حزم البيانات. القيمة الافتراضية هي 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "Clave precompartida de WireGuard",
"wireguardAllowedIPs": "IP permitidas de WireGuard",
"wireguardAllowedIPsHint": "Déjalo vacío para asignar automáticamente; separa las entradas con comas",
"amneziaWgPrivateKey": "Clave privada de AmneziaWG",
"amneziaWgPublicKey": "Clave pública de AmneziaWG",
"amneziaWgPreSharedKey": "Clave precompartida de AmneziaWG",
"amneziaWgAllowedIPs": "IP permitidas de AmneziaWG",
"amneziaWgAllowedIPsHint": "Déjalo vacío para asignar automáticamente; separa las entradas con comas",
"amneziaWgConfig": "Configuración de AmneziaWG",
"mtprotoSecret": "Secreto MTProto",
"mtprotoSecretHint": "El secreto FakeTLS del cliente. Vuelve a generarlo para cambiarlo.",
"mtprotoAdTag": "Ad-tag (canal patrocinado)",
@@ -1800,6 +1806,31 @@
"psk": "Clave precompartida",
"domainStrategy": "Estrategia de dominio"
},
"amneziawg": {
"privateKey": "Clave privada",
"publicKey": "Clave pública",
"subnetIp": "Subred",
"subnetCidr": "CIDR de la subred",
"mtu": "MTU",
"primaryDns": "DNS primario",
"secondaryDns": "DNS secundario",
"externalInterface": "Interfaz externa",
"externalInterfaceHint": "Interfaz de red del host para NAT (PostUp/PostDown). Déjalo vacío para autodetectar.",
"jc": "Jc (cantidad de paquetes basura)",
"jmin": "Jmin (tamaño mínimo de paquete basura)",
"jmax": "Jmax (tamaño máximo de paquete basura)",
"s1": "S1 (relleno del paquete init)",
"s2": "S2 (relleno del paquete response)",
"s3": "S3 (relleno de cookie reply, 2.0)",
"s4": "S4 (relleno del paquete de transporte, 2.0)",
"h1": "H1 (cabecera mágica)",
"h2": "H2 (cabecera mágica)",
"h3": "H3 (cabecera mágica)",
"h4": "H4 (cabecera mágica)",
"hHint": "Un número entero o un rango. Déjalo vacío para los valores clásicos 1/2/3/4.",
"i1": "I1 (paquete de firma, 2.0)",
"i1Hint": "Solo para AmneziaWG 2.0. Déjalo vacío para compatibilidad con 1.x."
},
"tun": {
"nameDesc": "El nombre de la interfaz TUN. El valor predeterminado es 'xray0'",
"mtuDesc": "Unidad Máxima de Transmisión. El tamaño máximo de los paquetes de datos. El valor predeterminado es 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "کلید پیش‌اشتراکی وایرگارد",
"wireguardAllowedIPs": "آی‌پی‌های مجاز وایرگارد",
"wireguardAllowedIPsHint": "برای تخصیص خودکار خالی بگذارید؛ ورودی‌ها را با کاما جدا کنید",
"amneziaWgPrivateKey": "کلید خصوصی AmneziaWG",
"amneziaWgPublicKey": "کلید عمومی AmneziaWG",
"amneziaWgPreSharedKey": "کلید پیش‌اشتراکی AmneziaWG",
"amneziaWgAllowedIPs": "آی‌پی‌های مجاز AmneziaWG",
"amneziaWgAllowedIPsHint": "برای تخصیص خودکار خالی بگذارید؛ ورودی‌ها را با کاما جدا کنید",
"amneziaWgConfig": "پیکربندی AmneziaWG",
"mtprotoSecret": "سکرت MTProto",
"mtprotoSecretHint": "سکرت FakeTLS این کلاینت. برای تعویض، دوباره تولید کنید.",
"mtprotoAdTag": "برچسب تبلیغاتی (کانال حامی)",
@@ -1800,6 +1806,31 @@
"psk": "کلید مشترک",
"domainStrategy": "استراتژی حل دامنه"
},
"amneziawg": {
"privateKey": "کلید خصوصی",
"publicKey": "کلید عمومی",
"subnetIp": "زیرشبکه",
"subnetCidr": "پیشوند زیرشبکه (CIDR)",
"mtu": "MTU",
"primaryDns": "DNS اصلی",
"secondaryDns": "DNS ثانویه",
"externalInterface": "رابط خارجی",
"externalInterfaceHint": "رابط شبکه میزبان برای NAT (PostUp/PostDown). برای تشخیص خودکار خالی بگذارید.",
"jc": "Jc (تعداد بسته‌های زباله)",
"jmin": "Jmin (حداقل اندازه بسته زباله)",
"jmax": "Jmax (حداکثر اندازه بسته زباله)",
"s1": "S1 (اندازه پرکننده بسته init)",
"s2": "S2 (اندازه پرکننده بسته response)",
"s3": "S3 (پرکننده cookie reply، نسخه ۲.۰)",
"s4": "S4 (پرکننده بسته انتقال، نسخه ۲.۰)",
"h1": "H1 (سرصفحه جادویی)",
"h2": "H2 (سرصفحه جادویی)",
"h3": "H3 (سرصفحه جادویی)",
"h4": "H4 (سرصفحه جادویی)",
"hHint": "یک عدد صحیح یا یک بازه. برای مقادیر پیش‌فرض کلاسیک ۱/۲/۳/۴ خالی بگذارید.",
"i1": "I1 (بسته امضا، نسخه ۲.۰)",
"i1Hint": "فقط برای AmneziaWG 2.0. برای سازگاری با نسخه ۱.x خالی بگذارید."
},
"tun": {
"nameDesc": "نام رابط TUN. مقدار پیش‌فرض 'xray0' است",
"mtuDesc": "واحد انتقال حداکثر. بیشترین اندازه بسته‌های داده. مقدار پیش‌فرض 1500 است",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "Kunci Pra-Berbagi WireGuard",
"wireguardAllowedIPs": "IP yang Diizinkan WireGuard",
"wireguardAllowedIPsHint": "Biarkan kosong untuk penetapan otomatis; pisahkan entri dengan koma",
"amneziaWgPrivateKey": "Kunci Privat AmneziaWG",
"amneziaWgPublicKey": "Kunci Publik AmneziaWG",
"amneziaWgPreSharedKey": "Kunci Pra-Berbagi AmneziaWG",
"amneziaWgAllowedIPs": "IP yang Diizinkan AmneziaWG",
"amneziaWgAllowedIPsHint": "Biarkan kosong untuk penetapan otomatis; pisahkan entri dengan koma",
"amneziaWgConfig": "Konfigurasi AmneziaWG",
"mtprotoSecret": "Secret MTProto",
"mtprotoSecretHint": "Secret FakeTLS klien. Buat ulang untuk menggantinya.",
"mtprotoAdTag": "Ad-tag (kanal bersponsor)",
@@ -1800,6 +1806,31 @@
"psk": "Kunci Pra-Bagi",
"domainStrategy": "Strategi Domain"
},
"amneziawg": {
"privateKey": "Kunci Privat",
"publicKey": "Kunci Publik",
"subnetIp": "Subnet",
"subnetCidr": "CIDR Subnet",
"mtu": "MTU",
"primaryDns": "DNS Utama",
"secondaryDns": "DNS Cadangan",
"externalInterface": "Antarmuka Eksternal",
"externalInterfaceHint": "NIC host untuk NAT (PostUp/PostDown). Biarkan kosong untuk deteksi otomatis.",
"jc": "Jc (jumlah paket sampah)",
"jmin": "Jmin (ukuran min paket sampah)",
"jmax": "Jmax (ukuran maks paket sampah)",
"s1": "S1 (padding paket init)",
"s2": "S2 (padding paket response)",
"s3": "S3 (padding cookie reply, 2.0)",
"s4": "S4 (padding paket transport, 2.0)",
"h1": "H1 (header ajaib)",
"h2": "H2 (header ajaib)",
"h3": "H3 (header ajaib)",
"h4": "H4 (header ajaib)",
"hHint": "Satu bilangan bulat atau rentang. Biarkan kosong untuk nilai klasik 1/2/3/4.",
"i1": "I1 (paket tanda tangan, 2.0)",
"i1Hint": "Hanya untuk AmneziaWG 2.0. Biarkan kosong untuk kompatibilitas dengan 1.x."
},
"tun": {
"nameDesc": "Nama antarmuka TUN. Standar adalah 'xray0'",
"mtuDesc": "Unit Transmisi Maksimum. Ukuran maksimum paket data. Standar adalah 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "WireGuard 事前共有鍵",
"wireguardAllowedIPs": "WireGuard 許可IP",
"wireguardAllowedIPsHint": "空欄で自動割り当て。複数指定はカンマ区切り",
"amneziaWgPrivateKey": "AmneziaWG 秘密鍵",
"amneziaWgPublicKey": "AmneziaWG 公開鍵",
"amneziaWgPreSharedKey": "AmneziaWG 事前共有鍵",
"amneziaWgAllowedIPs": "AmneziaWG 許可IP",
"amneziaWgAllowedIPsHint": "空欄で自動割り当て。複数指定はカンマ区切り",
"amneziaWgConfig": "AmneziaWG 設定",
"mtprotoSecret": "MTProto シークレット",
"mtprotoSecretHint": "このクライアントの FakeTLS シークレット。変更するには再生成します。",
"mtprotoAdTag": "広告タグ(スポンサーチャンネル)",
@@ -1800,6 +1806,31 @@
"psk": "共有キー",
"domainStrategy": "ドメイン戦略"
},
"amneziawg": {
"privateKey": "秘密鍵",
"publicKey": "公開鍵",
"subnetIp": "サブネット",
"subnetCidr": "サブネットCIDR",
"mtu": "MTU",
"primaryDns": "プライマリDNS",
"secondaryDns": "セカンダリDNS",
"externalInterface": "外部インターフェース",
"externalInterfaceHint": "NAT(PostUp/PostDown)に使用するホストのNIC。空欄で自動検出。",
"jc": "Jc(ジャンクパケット数)",
"jmin": "Jmin(ジャンクパケット最小サイズ)",
"jmax": "Jmax(ジャンクパケット最大サイズ)",
"s1": "S1(initパケットのパディングサイズ)",
"s2": "S2responseパケットのパディングサイズ)",
"s3": "S3cookie replyパディング、2.0",
"s4": "S4(トランスポートパケットパディング、2.0)",
"h1": "H1(マジックヘッダー)",
"h2": "H2(マジックヘッダー)",
"h3": "H3(マジックヘッダー)",
"h4": "H4(マジックヘッダー)",
"hHint": "整数または範囲を指定。空欄の場合は従来の1/2/3/4がデフォルトになります。",
"i1": "I1(署名パケット、2.0",
"i1Hint": "AmneziaWG 2.0専用。空欄で1.x互換の設定になります。"
},
"tun": {
"nameDesc": "TUN インターフェースの名前。デフォルトは 'xray0' です",
"mtuDesc": "最大伝送単位。データパケットの最大サイズ。デフォルトは 1500 です",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "Chave pré-compartilhada do WireGuard",
"wireguardAllowedIPs": "IPs permitidos do WireGuard",
"wireguardAllowedIPsHint": "Deixe vazio para atribuir automaticamente; separe as entradas com vírgulas",
"amneziaWgPrivateKey": "Chave privada do AmneziaWG",
"amneziaWgPublicKey": "Chave pública do AmneziaWG",
"amneziaWgPreSharedKey": "Chave pré-compartilhada do AmneziaWG",
"amneziaWgAllowedIPs": "IPs permitidos do AmneziaWG",
"amneziaWgAllowedIPsHint": "Deixe vazio para atribuir automaticamente; separe as entradas com vírgulas",
"amneziaWgConfig": "Configuração do AmneziaWG",
"mtprotoSecret": "Segredo MTProto",
"mtprotoSecretHint": "O segredo FakeTLS do cliente. Gere novamente para trocá-lo.",
"mtprotoAdTag": "Ad-tag (canal patrocinado)",
@@ -1800,6 +1806,31 @@
"psk": "Chave Pré-Compartilhada",
"domainStrategy": "Estratégia de Domínio"
},
"amneziawg": {
"privateKey": "Chave Privada",
"publicKey": "Chave Pública",
"subnetIp": "Sub-rede",
"subnetCidr": "CIDR da Sub-rede",
"mtu": "MTU",
"primaryDns": "DNS Primário",
"secondaryDns": "DNS Secundário",
"externalInterface": "Interface Externa",
"externalInterfaceHint": "Interface de rede do host para NAT (PostUp/PostDown). Deixe vazio para detecção automática.",
"jc": "Jc (quantidade de pacotes de lixo)",
"jmin": "Jmin (tamanho mínimo do pacote de lixo)",
"jmax": "Jmax (tamanho máximo do pacote de lixo)",
"s1": "S1 (preenchimento do pacote init)",
"s2": "S2 (preenchimento do pacote response)",
"s3": "S3 (preenchimento de cookie reply, 2.0)",
"s4": "S4 (preenchimento do pacote de transporte, 2.0)",
"h1": "H1 (cabeçalho mágico)",
"h2": "H2 (cabeçalho mágico)",
"h3": "H3 (cabeçalho mágico)",
"h4": "H4 (cabeçalho mágico)",
"hHint": "Um número inteiro ou um intervalo. Deixe vazio para os valores clássicos 1/2/3/4.",
"i1": "I1 (pacote de assinatura, 2.0)",
"i1Hint": "Somente para AmneziaWG 2.0. Deixe vazio para compatibilidade com 1.x."
},
"tun": {
"nameDesc": "O nome da interface TUN. O padrão é 'xray0'",
"mtuDesc": "Unidade Máxima de Transmissão. O tamanho máximo dos pacotes de dados. O padrão é 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "WireGuard Ön Paylaşımlı Anahtar",
"wireguardAllowedIPs": "WireGuard İzin Verilen IP'ler",
"wireguardAllowedIPsHint": "Otomatik atama için boş bırakın; girişleri virgülle ayırın",
"amneziaWgPrivateKey": "AmneziaWG Özel Anahtarı",
"amneziaWgPublicKey": "AmneziaWG Genel Anahtarı",
"amneziaWgPreSharedKey": "AmneziaWG Ön Paylaşımlı Anahtar",
"amneziaWgAllowedIPs": "AmneziaWG İzin Verilen IP'ler",
"amneziaWgAllowedIPsHint": "Otomatik atama için boş bırakın; girişleri virgülle ayırın",
"amneziaWgConfig": "AmneziaWG Yapılandırması",
"mtprotoSecret": "MTProto sırrı",
"mtprotoSecretHint": "İstemcinin FakeTLS sırrı. Değiştirmek için yeniden oluşturun.",
"mtprotoAdTag": "Reklam etiketi (sponsorlu kanal)",
@@ -1800,6 +1806,31 @@
"psk": "Ön Paylaşılan Anahtar",
"domainStrategy": "Alan Adı Stratejisi"
},
"amneziawg": {
"privateKey": "Özel Anahtar",
"publicKey": "Genel Anahtar",
"subnetIp": "Alt Ağ",
"subnetCidr": "Alt Ağ CIDR",
"mtu": "MTU",
"primaryDns": "Birincil DNS",
"secondaryDns": "İkincil DNS",
"externalInterface": "Harici Arayüz",
"externalInterfaceHint": "NAT (PostUp/PostDown) için sunucu ağ arayüzü. Otomatik algılama için boş bırakın.",
"jc": "Jc (gereksiz paket sayısı)",
"jmin": "Jmin (min gereksiz paket boyutu)",
"jmax": "Jmax (maks gereksiz paket boyutu)",
"s1": "S1 (init paketi dolgu boyutu)",
"s2": "S2 (response paketi dolgu boyutu)",
"s3": "S3 (cookie reply dolgusu, 2.0)",
"s4": "S4 (transport paketi dolgusu, 2.0)",
"h1": "H1 (sihirli başlık)",
"h2": "H2 (sihirli başlık)",
"h3": "H3 (sihirli başlık)",
"h4": "H4 (sihirli başlık)",
"hHint": "Tek bir tam sayı veya bir aralık. Klasik 1/2/3/4 varsayılanları için boş bırakın.",
"i1": "I1 (imza paketi, 2.0)",
"i1Hint": "Yalnızca AmneziaWG 2.0 için. 1.x uyumluluğu için boş bırakın."
},
"tun": {
"nameDesc": "TUN arabiriminin adı. Varsayılan değer 'xray0'dır.",
"mtuDesc": "Maksimum İletim Birimi. Veri paketlerinin maksimum boyutu. Varsayılan değer 1500'dür.",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "Спільний ключ WireGuard",
"wireguardAllowedIPs": "Дозволені IP WireGuard",
"wireguardAllowedIPsHint": "Залиште порожнім для автопризначення; розділяйте записи комами",
"amneziaWgPrivateKey": "Приватний ключ AmneziaWG",
"amneziaWgPublicKey": "Публічний ключ AmneziaWG",
"amneziaWgPreSharedKey": "Спільний ключ AmneziaWG",
"amneziaWgAllowedIPs": "Дозволені IP AmneziaWG",
"amneziaWgAllowedIPsHint": "Залиште порожнім для автопризначення; розділяйте записи комами",
"amneziaWgConfig": "Конфігурація AmneziaWG",
"mtprotoSecret": "Секрет MTProto",
"mtprotoSecretHint": "Секрет FakeTLS клієнта. Згенеруйте заново, щоб змінити.",
"mtprotoAdTag": "Рекламний тег (спонсорський канал)",
@@ -1800,6 +1806,31 @@
"psk": "Спільний ключ",
"domainStrategy": "Стратегія домену"
},
"amneziawg": {
"privateKey": "Приватний ключ",
"publicKey": "Публічний ключ",
"subnetIp": "Підмережа",
"subnetCidr": "CIDR підмережі",
"mtu": "MTU",
"primaryDns": "Основний DNS",
"secondaryDns": "Резервний DNS",
"externalInterface": "Зовнішній інтерфейс",
"externalInterfaceHint": "Мережевий інтерфейс хоста для NAT (PostUp/PostDown). Залиште порожнім для автовизначення.",
"jc": "Jc (кількість сміттєвих пакетів)",
"jmin": "Jmin (мін. розмір сміттєвого пакета)",
"jmax": "Jmax (макс. розмір сміттєвого пакета)",
"s1": "S1 (заповнення пакета init)",
"s2": "S2 (заповнення пакета response)",
"s3": "S3 (заповнення cookie reply, 2.0)",
"s4": "S4 (заповнення транспортного пакета, 2.0)",
"h1": "H1 (магічний заголовок)",
"h2": "H2 (магічний заголовок)",
"h3": "H3 (магічний заголовок)",
"h4": "H4 (магічний заголовок)",
"hHint": "Ціле число або діапазон. Залиште порожнім для класичних значень 1/2/3/4.",
"i1": "I1 (пакет підпису, 2.0)",
"i1Hint": "Лише для AmneziaWG 2.0. Залиште порожнім для сумісності з 1.x."
},
"tun": {
"nameDesc": "Назва інтерфейсу TUN. Значення за замовчуванням - 'xray0'",
"mtuDesc": "Максимальна одиниця передачі. Максимальний розмір пакетів даних. Значення за замовчуванням - 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "Khóa chia sẻ trước WireGuard",
"wireguardAllowedIPs": "IP được phép WireGuard",
"wireguardAllowedIPsHint": "Để trống để tự động gán; phân tách các mục bằng dấu phẩy",
"amneziaWgPrivateKey": "Khóa riêng AmneziaWG",
"amneziaWgPublicKey": "Khóa công khai AmneziaWG",
"amneziaWgPreSharedKey": "Khóa chia sẻ trước AmneziaWG",
"amneziaWgAllowedIPs": "IP được phép AmneziaWG",
"amneziaWgAllowedIPsHint": "Để trống để tự động gán; phân tách các mục bằng dấu phẩy",
"amneziaWgConfig": "Cấu hình AmneziaWG",
"mtprotoSecret": "Secret MTProto",
"mtprotoSecretHint": "Secret FakeTLS của client. Tạo lại để thay đổi.",
"mtprotoAdTag": "Ad-tag (kênh tài trợ)",
@@ -1800,6 +1806,31 @@
"psk": "Khóa chia sẻ",
"domainStrategy": "Chiến lược tên miền"
},
"amneziawg": {
"privateKey": "Khóa riêng",
"publicKey": "Khóa công khai",
"subnetIp": "Mạng con",
"subnetCidr": "CIDR mạng con",
"mtu": "MTU",
"primaryDns": "DNS chính",
"secondaryDns": "DNS phụ",
"externalInterface": "Giao diện ngoài",
"externalInterfaceHint": "Card mạng của host dùng cho NAT (PostUp/PostDown). Để trống để tự động phát hiện.",
"jc": "Jc (số lượng gói rác)",
"jmin": "Jmin (kích thước tối thiểu gói rác)",
"jmax": "Jmax (kích thước tối đa gói rác)",
"s1": "S1 (đệm gói init)",
"s2": "S2 (đệm gói response)",
"s3": "S3 (đệm cookie reply, 2.0)",
"s4": "S4 (đệm gói transport, 2.0)",
"h1": "H1 (tiêu đề ma thuật)",
"h2": "H2 (tiêu đề ma thuật)",
"h3": "H3 (tiêu đề ma thuật)",
"h4": "H4 (tiêu đề ma thuật)",
"hHint": "Một số nguyên hoặc một khoảng. Để trống để dùng giá trị mặc định cổ điển 1/2/3/4.",
"i1": "I1 (gói chữ ký, 2.0)",
"i1Hint": "Chỉ dành cho AmneziaWG 2.0. Để trống để tương thích với 1.x."
},
"tun": {
"nameDesc": "Tên của giao diện TUN. Giá trị mặc định là 'xray0'",
"mtuDesc": "Đơn vị Truyền Tối đa. Kích thước tối đa của các gói dữ liệu. Giá trị mặc định là 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "WireGuard 预共享密钥",
"wireguardAllowedIPs": "WireGuard 允许的 IP",
"wireguardAllowedIPsHint": "留空则自动分配;多个条目用逗号分隔",
"amneziaWgPrivateKey": "AmneziaWG 私钥",
"amneziaWgPublicKey": "AmneziaWG 公钥",
"amneziaWgPreSharedKey": "AmneziaWG 预共享密钥",
"amneziaWgAllowedIPs": "AmneziaWG 允许的 IP",
"amneziaWgAllowedIPsHint": "留空则自动分配;多个条目用逗号分隔",
"amneziaWgConfig": "AmneziaWG 配置",
"mtprotoSecret": "MTProto 密钥",
"mtprotoSecretHint": "该客户端的 FakeTLS 密钥。重新生成即可更换。",
"mtprotoAdTag": "广告标签(赞助频道)",
@@ -1800,6 +1806,31 @@
"psk": "共享密钥",
"domainStrategy": "域策略"
},
"amneziawg": {
"privateKey": "私钥",
"publicKey": "公钥",
"subnetIp": "子网",
"subnetCidr": "子网 CIDR",
"mtu": "MTU",
"primaryDns": "主 DNS",
"secondaryDns": "备用 DNS",
"externalInterface": "外部网卡",
"externalInterfaceHint": "用于 NATPostUp/PostDown)的主机网卡。留空则自动检测。",
"jc": "Jc(垃圾包数量)",
"jmin": "Jmin(垃圾包最小大小)",
"jmax": "Jmax(垃圾包最大大小)",
"s1": "S1init 包填充大小)",
"s2": "S2response 包填充大小)",
"s3": "S3cookie reply 填充,2.0",
"s4": "S4(传输包填充,2.0",
"h1": "H1(魔术头)",
"h2": "H2(魔术头)",
"h3": "H3(魔术头)",
"h4": "H4(魔术头)",
"hHint": "单个整数或范围。留空则使用经典默认值 1/2/3/4。",
"i1": "I1(签名包,2.0",
"i1Hint": "仅适用于 AmneziaWG 2.0。留空则兼容 1.x。"
},
"tun": {
"nameDesc": "TUN 接口的名称。默认值为 'xray0'",
"mtuDesc": "最大传输单元。数据包的最大大小。默认值为 1500",
+31
View File
@@ -915,6 +915,12 @@
"wireguardPreSharedKey": "WireGuard 預共用金鑰",
"wireguardAllowedIPs": "WireGuard 允許的 IP",
"wireguardAllowedIPsHint": "留空則自動分配;多個條目用逗號分隔",
"amneziaWgPrivateKey": "AmneziaWG 私鑰",
"amneziaWgPublicKey": "AmneziaWG 公鑰",
"amneziaWgPreSharedKey": "AmneziaWG 預共用金鑰",
"amneziaWgAllowedIPs": "AmneziaWG 允許的 IP",
"amneziaWgAllowedIPsHint": "留空則自動分配;多個條目用逗號分隔",
"amneziaWgConfig": "AmneziaWG 設定",
"mtprotoSecret": "MTProto 金鑰",
"mtprotoSecretHint": "該用戶端的 FakeTLS 金鑰。重新產生即可更換。",
"mtprotoAdTag": "廣告標籤(贊助頻道)",
@@ -1800,6 +1806,31 @@
"psk": "共享金鑰",
"domainStrategy": "域策略"
},
"amneziawg": {
"privateKey": "私鑰",
"publicKey": "公鑰",
"subnetIp": "子網路",
"subnetCidr": "子網路 CIDR",
"mtu": "MTU",
"primaryDns": "主要 DNS",
"secondaryDns": "次要 DNS",
"externalInterface": "外部網路介面",
"externalInterfaceHint": "用於 NATPostUp/PostDown)的主機網路介面。留空則自動偵測。",
"jc": "Jc(垃圾封包數量)",
"jmin": "Jmin(垃圾封包最小大小)",
"jmax": "Jmax(垃圾封包最大大小)",
"s1": "S1init 封包填充大小)",
"s2": "S2response 封包填充大小)",
"s3": "S3cookie reply 填充,2.0",
"s4": "S4(傳輸封包填充,2.0",
"h1": "H1(魔術標頭)",
"h2": "H2(魔術標頭)",
"h3": "H3(魔術標頭)",
"h4": "H4(魔術標頭)",
"hHint": "單一整數或範圍。留空則使用經典預設值 1/2/3/4。",
"i1": "I1(簽章封包,2.0",
"i1Hint": "僅適用於 AmneziaWG 2.0。留空則相容 1.x。"
},
"tun": {
"nameDesc": "TUN 介面的名稱。預設值為 'xray0'",
"mtuDesc": "最大傳輸單元。資料包的最大大小。預設值為 1500",