精简版第四轮补裁(P4): 页面层摘除 + Xray更新端点下线 + 本机核心监管下线
CI / go-test (push) Canceled after 0s
CI / postgres-durable-first (push) Canceled after 0s
CI / codegen (push) Canceled after 0s
CI / govulncheck (push) Canceled after 0s
CI / race (push) Canceled after 0s
CI / fuzz-smoke (push) Canceled after 0s
CI / golangci (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CodeQL Advanced / Analyze (go) (push) Canceled after 0s
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (javascript-typescript) (push) Canceled after 0s
Release 3X-UI / build (386) (push) Canceled after 0s
Release 3X-UI / build (amd64) (push) Canceled after 0s
Release 3X-UI / build (arm64) (push) Canceled after 0s
Release 3X-UI / build (armv5) (push) Canceled after 0s
Release 3X-UI / build (armv6) (push) Canceled after 0s
Release 3X-UI / build (armv7) (push) Canceled after 0s
Release 3X-UI / build (s390x) (push) Canceled after 0s
Release 3X-UI / Build for Windows (amd64) (push) Canceled after 0s
Release 3X-UI / Publish rolling dev release (push) Canceled after 0s
CI / go-test (push) Canceled after 0s
CI / postgres-durable-first (push) Canceled after 0s
CI / codegen (push) Canceled after 0s
CI / govulncheck (push) Canceled after 0s
CI / race (push) Canceled after 0s
CI / fuzz-smoke (push) Canceled after 0s
CI / golangci (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CodeQL Advanced / Analyze (go) (push) Canceled after 0s
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (javascript-typescript) (push) Canceled after 0s
Release 3X-UI / build (386) (push) Canceled after 0s
Release 3X-UI / build (amd64) (push) Canceled after 0s
Release 3X-UI / build (arm64) (push) Canceled after 0s
Release 3X-UI / build (armv5) (push) Canceled after 0s
Release 3X-UI / build (armv6) (push) Canceled after 0s
Release 3X-UI / build (armv7) (push) Canceled after 0s
Release 3X-UI / build (s390x) (push) Canceled after 0s
Release 3X-UI / Build for Windows (amd64) (push) Canceled after 0s
Release 3X-UI / Publish rolling dev release (push) Canceled after 0s
页面层(用户真机截图发现前两轮漏裁): - 设置: 摘除 Telegram机器人/邮件菜单与页面, 及页内残留入口(通知页/外部流量/LDAP/2FA设置页) - Xray配置: 摘除负载均衡/DNS/高级配置菜单与页面; 基础配置(出站+路由)完好 - 总览: 摘除 Xray更新弹窗(VersionModal+GeodataSection)全部入口, 版本号改为静态展示 - 13个locale同步摘除461个已删功能专属翻译键(逐键核查前后端引用为零; i18n-dead-keys测试全绿) Xray更新后端(经调查确认仅服务本机bin/xray, 与agent下发/订阅无关): - 删除 getXrayVersion/installXray/updateGeofile 路由与handler(访问返回404) - 删除 ServerService 对应实现与校验和函数; 同步api-docs/monitor白名单/openapi 本机核心监管下线(设计: 主控永不运行本机xray, 入站全在agent): - XrayService.RestartXray 降级为no-op(一次性Warning说明日志); StopXray无进程时幂等返回 - web.go 摘除启动拉起本机核心/CheckXrayRunning看门狗(1s)/ApplyPendingRestart cron(30s)/XrayTrafficJob/CheckClientIpJob 注册 - ApplyPendingRestart 降级为消费即清, 其测试更新为新语义 - XrayMetricsService.Sample 短路: 不再每2s探本机/debug/vars, 状态优雅置为不可用 - 配置生成(纯JSON)/agent链路/订阅/入站CRUD未动; 状态读数优雅归零(stop/Unknown) 注: TestGetXrayConfig_EnabledClientsStillEmitted 在基线945b3a5同样失败(既有问题, 非本轮引入)
This commit is contained in:
@@ -67,16 +67,12 @@
|
||||
"success": "Success",
|
||||
"lastOnline": "Last Online",
|
||||
"lastSubFetch": "Last Subscription Fetch",
|
||||
"getVersion": "Get Version",
|
||||
"install": "Install",
|
||||
"clients": "Clients",
|
||||
"usage": "Usage",
|
||||
"twoFactorCode": "Code",
|
||||
"remained": "Remaining",
|
||||
"security": "Security",
|
||||
"emptyDnsDesc": "No added DNS servers.",
|
||||
"emptyFakeDnsDesc": "No added Fake DNS servers.",
|
||||
"emptyBalancersDesc": "No added balancers.",
|
||||
"somethingWentWrong": "Something went wrong",
|
||||
"subscription": {
|
||||
"title": "Subscription info",
|
||||
@@ -87,7 +83,6 @@
|
||||
"uploaded": "Uploaded",
|
||||
"expiry": "Expiry",
|
||||
"totalQuota": "Total quota",
|
||||
"individualLinks": "Individual links",
|
||||
"active": "Active",
|
||||
"inactive": "Inactive",
|
||||
"unlimited": "Unlimited",
|
||||
@@ -136,9 +131,6 @@
|
||||
"xrayStatus": "Xray",
|
||||
"stopXray": "Stop",
|
||||
"restartXray": "Restart",
|
||||
"xraySwitch": "Version",
|
||||
"xrayUpdates": "Xray Updates",
|
||||
"xraySwitchClickDesk": "Choose carefully, as older versions may not be compatible with current configurations.",
|
||||
"updatePanel": "Update Panel",
|
||||
"panelUpdateDesc": "This will update 3X-UI itself to the latest release and restart the panel service.",
|
||||
"currentPanelVersion": "Current panel version",
|
||||
@@ -200,9 +192,6 @@
|
||||
"download": "Download",
|
||||
"sent": "Sent",
|
||||
"received": "Received",
|
||||
"xraySwitchVersionDialog": "Do you really want to change the Xray version?",
|
||||
"xraySwitchVersionDialogDesc": "This will change the Xray version to #version#.",
|
||||
"xraySwitchVersionPopover": "Xray updated successfully",
|
||||
"panelUpdateDialog": "Do you really want to update the panel?",
|
||||
"panelUpdateDialogDesc": "This will update 3X-UI to #version# and restart the panel service.",
|
||||
"panelUpdateStartedPopover": "Panel update started",
|
||||
@@ -210,24 +199,6 @@
|
||||
"panelUpdateFailedDesc": "The update did not finish successfully. Check the server logs, or run 'x-ui update' from the command line.",
|
||||
"panelUpdateUnknownTitle": "Couldn't confirm the update finished",
|
||||
"panelUpdateUnknownDesc": "The panel didn't report a result in time. Reload to check the current version, or check the server logs.",
|
||||
"geofileUpdateDialog": "Do you really want to update the geofile?",
|
||||
"geofileUpdateDialogDesc": "This will update the #filename# file.",
|
||||
"geofilesUpdateDialogDesc": "This will update all geofiles.",
|
||||
"geofilesUpdateAll": "Update all",
|
||||
"geofileUpdatePopover": "Geofile updated successfully",
|
||||
"geodataTitle": "Geodata Auto-Update",
|
||||
"geodataHint": "Xray downloads these files on schedule and hot-reloads them without a restart. URLs must be HTTPS. Each file must already exist in the bin folder once before Xray can update it.",
|
||||
"geodataCron": "Schedule (cron)",
|
||||
"geodataOutbound": "Download through outbound (optional)",
|
||||
"geodataFile": "File name",
|
||||
"geodataAddFile": "Add file",
|
||||
"geodataSaveRestart": "Save & Restart Xray",
|
||||
"geodataConfirmTitle": "Save geodata settings?",
|
||||
"geodataConfirmContent": "This updates the Xray config template and restarts Xray.",
|
||||
"geodataInvalidUrl": "Each file needs an HTTPS URL.",
|
||||
"geodataInvalidFile": "File names must be plain names like geosite_custom.dat (no paths).",
|
||||
"geodataInvalidCron": "Cron must have 5 fields, e.g. 0 4 * * *",
|
||||
"geodataEmpty": "No files configured. Reference files in routing rules as ext:geosite_custom.dat:category.",
|
||||
"dontRefresh": "Installation is in progress, please do not refresh this page",
|
||||
"logs": "Logs",
|
||||
"accessLogs": "Access Logs",
|
||||
@@ -1179,19 +1150,7 @@
|
||||
"pinnedCertPlaceholder": "base64 or hex SHA-256",
|
||||
"fetchPin": "Fetch",
|
||||
"pinFetched": "Fetched the node's current certificate",
|
||||
"pinFetchFailed": "Could not fetch the certificate",
|
||||
"nodeType": "Node Type",
|
||||
"nodeTypeTraditional": "Traditional Panel Node",
|
||||
"nodeTypeAgent": "Agent Lightweight Node",
|
||||
"agentHint": "Agent nodes connect out to the master; no address, port or API token needed. An install command is generated on creation.",
|
||||
"agentTokenTitle": "Agent Node Setup",
|
||||
"agentTokenCreated": "Node {{name}} created successfully",
|
||||
"agentTokenHint": "Copy the command below and run it on the node machine. This token is shown only once!",
|
||||
"agentTokenInstructions": "The command downloads the installer, configures the master URL and token. The node comes online in ~30s.",
|
||||
"agentTokenCopied": "Install command copied",
|
||||
"agentTokenCopyFailed": "Copy failed, please copy manually",
|
||||
"copyToken": "Copy Install Command",
|
||||
"agentMasterUrlHint": "Master URL (used by agent to reach the master; change to public address if behind proxy):"
|
||||
"pinFetchFailed": "Could not fetch the certificate"
|
||||
},
|
||||
"settings": {
|
||||
"defaultTag": "Default",
|
||||
@@ -1212,7 +1171,6 @@
|
||||
"warnDefaultBasePath": "Default base path \"/\" is well-known — change it to a random path.",
|
||||
"warnDefaultSubPath": "Default subscription path \"/sub/\" is well-known — change it.",
|
||||
"warnDefaultJsonPath": "Default JSON subscription path \"/json/\" is well-known — change it.",
|
||||
"TGBotSettings": "Telegram Bot",
|
||||
"panelListeningIP": "Listen IP",
|
||||
"panelListeningIPDesc": "The IP address for the web panel. (leave blank to listen on all IPs)",
|
||||
"panelListeningDomain": "Listen Domain",
|
||||
@@ -1241,43 +1199,12 @@
|
||||
"currentPassword": "Current Password",
|
||||
"newUsername": "New Username",
|
||||
"newPassword": "New Password",
|
||||
"telegramBotEnable": "Enable Telegram Bot",
|
||||
"telegramBotEnableDesc": "Enables the Telegram bot.",
|
||||
"telegramToken": "Telegram Token",
|
||||
"telegramTokenDesc": "The Telegram bot token obtained from '{'@'}BotFather'.",
|
||||
"telegramProxy": "SOCKS Proxy",
|
||||
"telegramProxyDesc": "Enables SOCKS5 proxy for connecting to Telegram. (adjust settings as per guide)",
|
||||
"telegramAPIServer": "Telegram API Server",
|
||||
"telegramAPIServerDesc": "The Telegram API server to use. Leave blank to use the default server.",
|
||||
"telegramChatId": "Admin Chat ID",
|
||||
"telegramChatIdDesc": "The Telegram Admin Chat ID(s). (comma-separated)(get it here {'@'}userinfobot) or (use '/id' command in the bot)",
|
||||
"telegramNotifyTime": "Notification Time",
|
||||
"telegramNotifyTimeDesc": "How often the Telegram bot sends periodic reports. Pick a preset interval, or choose Custom to enter a raw crontab expression.",
|
||||
"notifyTime": {
|
||||
"every": "@every — repeat at an interval",
|
||||
"hourly": "@hourly — every hour",
|
||||
"daily": "@daily — every day at 00:00",
|
||||
"weekly": "@weekly — every week",
|
||||
"monthly": "@monthly — every month",
|
||||
"custom": "Custom (crontab)",
|
||||
"seconds": "Seconds",
|
||||
"minutes": "Minutes",
|
||||
"hours": "Hours",
|
||||
"interval": "Interval",
|
||||
"unit": "Unit"
|
||||
},
|
||||
"tgNotifyBackup": "Database Backup",
|
||||
"tgNotifyBackupDesc": "Send a database backup file with a report.",
|
||||
"tgNotifyLogin": "Login Notification",
|
||||
"tgNotifyLoginDesc": "Get notified about the username, IP address, and time whenever someone attempts to log into your web panel.",
|
||||
"sessionMaxAge": "Session Duration",
|
||||
"sessionMaxAgeDesc": "The duration for which you can stay logged in. (unit: minute)",
|
||||
"expireTimeDiff": "Expiration Date Notification",
|
||||
"expireTimeDiffDesc": "Get notified about expiration date when reaching this threshold. (unit: day)",
|
||||
"trafficDiff": "Traffic Cap Notification",
|
||||
"trafficDiffDesc": "Get notified about traffic cap when reaching this threshold. (unit: GB)",
|
||||
"tgNotifyCpu": "CPU Load Notification",
|
||||
"tgNotifyCpuDesc": "Get notified if CPU load exceeds this threshold. (unit: %)",
|
||||
"timeZone": "Time Zone",
|
||||
"timeZoneDesc": "Scheduled tasks will run based on this time zone.",
|
||||
"subSettings": "Subscription",
|
||||
@@ -1342,10 +1269,6 @@
|
||||
"subEncryptDesc": "The returned content of subscription service will be Base64 encoded.",
|
||||
"subURI": "Reverse Proxy URI",
|
||||
"subURIDesc": "The full base URL (scheme://domain[:port]/path/) for the subscription link and QR code, used instead of Listen Domain/Listen Port. Set this whenever the subscription is reached through a reverse proxy or a domain/port different from the ones above.",
|
||||
"externalTrafficInformEnable": "External Traffic Inform",
|
||||
"externalTrafficInformEnableDesc": "Inform external API on every traffic update.",
|
||||
"externalTrafficInformURI": "External Traffic Inform URI",
|
||||
"externalTrafficInformURIDesc": "Traffic updates are sent to this URI.",
|
||||
"restartXrayOnClientDisable": "Restart Xray After Auto Disable",
|
||||
"restartXrayOnClientDisableDesc": "When a client is automatically disabled due to expiration or traffic limit, restart Xray.",
|
||||
"fragment": "Fragmentation",
|
||||
@@ -1355,38 +1278,6 @@
|
||||
"noisesSett": "Noises Settings",
|
||||
"trustedProxyCidrs": "Trusted proxy CIDRs",
|
||||
"trustedProxyCidrsDesc": "Comma-separated IPs/CIDRs allowed to set forwarded host, proto, and client IP headers.",
|
||||
"ldap": {
|
||||
"enable": "Enable LDAP sync",
|
||||
"host": "LDAP host",
|
||||
"port": "LDAP port",
|
||||
"useTls": "Use TLS (LDAPS)",
|
||||
"skipTlsVerify": "Skip TLS certificate verification",
|
||||
"skipTlsVerifyDesc": "Insecure — disables server certificate validation. Use only with internal/untrusted CAs.",
|
||||
"bindDn": "Bind DN",
|
||||
"passwordConfigured": "Configured; leave blank to keep current password.",
|
||||
"passwordUnconfigured": "Not configured.",
|
||||
"passwordPlaceholder": "Configured - enter a new value to replace",
|
||||
"baseDn": "Base DN",
|
||||
"userFilter": "User filter",
|
||||
"userAttr": "User attribute (username/email)",
|
||||
"vlessField": "VLESS flag attribute",
|
||||
"flagField": "Generic flag attribute (optional)",
|
||||
"flagFieldDesc": "If set, overrides VLESS flag — e.g. shadowInactive.",
|
||||
"truthyValues": "Truthy values",
|
||||
"truthyValuesDesc": "Comma-separated; default: true,1,yes,on",
|
||||
"invertFlag": "Invert flag",
|
||||
"invertFlagDesc": "Enable when the attribute means disabled (e.g. shadowInactive).",
|
||||
"syncSchedule": "Sync schedule",
|
||||
"syncScheduleDesc": "Cron-like string, e.g. @every 1m",
|
||||
"inboundTags": "Inbound tags",
|
||||
"inboundTagsDesc": "Inbounds that LDAP sync may auto-create or auto-delete clients on.",
|
||||
"noInbounds": "No inbounds found. Create one in Inbounds first.",
|
||||
"autoCreate": "Auto create clients",
|
||||
"autoDelete": "Auto delete clients",
|
||||
"defaultTotalGb": "Default total (GB)",
|
||||
"defaultExpiryDays": "Default expiry (days)",
|
||||
"defaultIpLimit": "Default IP limit"
|
||||
},
|
||||
"subFormats": {
|
||||
"finalMask": "Final Mask",
|
||||
"finalMaskDesc": "Inject Xray finalmask TCP/UDP masks and QUIC parameters into every generated Xray JSON profile. Requires a client app that supports Xray JSON subscriptions and a recent Xray core.",
|
||||
@@ -1410,31 +1301,15 @@
|
||||
"muxSett": "Mux Settings",
|
||||
"direct": "Direct Connection",
|
||||
"directDesc": "Directly establishes connections with domains or IP ranges of a specific country.",
|
||||
"notifications": "Notifications",
|
||||
"certs": "Certificates",
|
||||
"externalTraffic": "External Traffic",
|
||||
"dateAndTime": "Date and Time",
|
||||
"proxyAndServer": "Proxy and Server",
|
||||
"intervals": "Intervals",
|
||||
"information": "Information",
|
||||
"profile": "Profile",
|
||||
"language": "Language",
|
||||
"telegramBotLanguage": "Telegram Bot Language",
|
||||
"security": {
|
||||
"admin": "Admin credentials",
|
||||
"twoFactor": "Two-factor authentication",
|
||||
"twoFactorEnable": "Enable 2FA",
|
||||
"twoFactorEnableDesc": "Adds an additional layer of authentication to provide more security.",
|
||||
"twoFactorModalSetTitle": "Enable two-factor authentication",
|
||||
"twoFactorModalDeleteTitle": "Disable two-factor authentication",
|
||||
"twoFactorModalSteps": "To set up two-factor authentication, perform a few steps:",
|
||||
"twoFactorModalFirstStep": "1. Scan this QR code in the app for authentication or copy the token near the QR code and paste it into the app",
|
||||
"twoFactorModalSecondStep": "2. Enter the code from the app",
|
||||
"twoFactorModalRemoveStep": "Enter the code from the application to remove two-factor authentication.",
|
||||
"twoFactorModalChangeCredentialsTitle": "Change credentials",
|
||||
"twoFactorModalChangeCredentialsStep": "Enter the code from the application to change administrator credentials.",
|
||||
"twoFactorModalSetSuccess": "Two-factor authentication has been successfully established",
|
||||
"twoFactorModalDeleteSuccess": "Two-factor authentication has been successfully deleted",
|
||||
"twoFactorModalError": "Wrong code",
|
||||
"show": "Show",
|
||||
"hide": "Hide",
|
||||
@@ -1457,36 +1332,6 @@
|
||||
"getOutboundTrafficError": "Error getting traffic",
|
||||
"resetOutboundTrafficError": "Error resetting outbound traffic"
|
||||
},
|
||||
"smtpSettings": "SMTP Settings",
|
||||
"smtpEnable": "Enable Email Notifications",
|
||||
"smtpEnableDesc": "Enable email notifications via SMTP",
|
||||
"smtpHost": "SMTP Host",
|
||||
"smtpHostDesc": "SMTP server hostname (e.g. smtp.gmail.com)",
|
||||
"smtpPort": "SMTP Port",
|
||||
"smtpPortDesc": "SMTP server port (default: 587)",
|
||||
"smtpUsername": "SMTP Username",
|
||||
"smtpUsernameDesc": "SMTP authentication username",
|
||||
"smtpFrom": "SMTP From Address",
|
||||
"smtpFromDesc": "Sender address used in the email From header. Leave empty to use the username.",
|
||||
"smtpFromName": "SMTP Sender Name",
|
||||
"smtpFromNameDesc": "Optional display name shown before the sender address in the From header.",
|
||||
"smtpPassword": "SMTP Password",
|
||||
"smtpPasswordDesc": "SMTP authentication password",
|
||||
"smtpTo": "Recipients",
|
||||
"smtpToDesc": "Comma-separated recipient email addresses",
|
||||
"emailSettings": "Email",
|
||||
"emailNotifications": "Notifications",
|
||||
"smtpEventBusNotify": "Email Event Notifications",
|
||||
"smtpEventBusNotifyDesc": "Select which events trigger email notifications",
|
||||
"tgEventBusNotify": "Telegram Event Notifications",
|
||||
"tgEventBusNotifyDesc": "Select which events trigger Telegram notifications",
|
||||
"testSmtp": "Send Test Email",
|
||||
"testTgBot": "Send Test Message",
|
||||
"eventGroupOutbound": "Outbound",
|
||||
"eventGroupXray": "Xray Core",
|
||||
"eventGroupSystem": "System",
|
||||
"eventGroupSecurity": "Security",
|
||||
"eventGroupNode": "Nodes",
|
||||
"eventOutboundDown": "Down",
|
||||
"eventOutboundUp": "Up",
|
||||
"eventXrayCrash": "Crash",
|
||||
@@ -1494,36 +1339,7 @@
|
||||
"eventNodeUp": "Up",
|
||||
"eventCPUHigh": "CPU high (%)",
|
||||
"requestFailed": "Request failed",
|
||||
"smtpEncryption": "Encryption",
|
||||
"smtpEncryptionDesc": "SMTP connection encryption method",
|
||||
"smtpEncryptionNone": "None (plain text)",
|
||||
"smtpEncryptionStartTLS": "STARTTLS",
|
||||
"smtpEncryptionTLS": "TLS (implicit)",
|
||||
"smtpStageConnect": "Connection",
|
||||
"smtpStageAuth": "Authentication",
|
||||
"smtpStageSend": "Send",
|
||||
"smtpTestSuccess": "Test email sent successfully",
|
||||
"smtpHostNotConfigured": "SMTP host not configured",
|
||||
"smtpNoRecipients": "No recipients configured",
|
||||
"smtpFromNotConfigured": "SMTP sender address not configured",
|
||||
"eventLoginAttempt": "Login attempt",
|
||||
"telegramTokenConfigured": "Configured; leave blank to keep current token.",
|
||||
"telegramTokenPlaceholder": "Configured - enter a new token to replace",
|
||||
"smtpPasswordConfigured": "Configured; leave blank to keep current password.",
|
||||
"smtpPasswordPlaceholder": "Configured - enter a new password to replace",
|
||||
"smtpNotInitialized": "SMTP not initialized",
|
||||
"tgBotNotEnabled": "Telegram bot is not enabled",
|
||||
"tgTestFailed": "Telegram test failed",
|
||||
"tgTestSuccess": "Test message sent to Telegram",
|
||||
"tgBotNotRunning": "Telegram bot not running",
|
||||
"smtpErrorAuth": "Authentication failed — check username and password",
|
||||
"smtpErrorStarttls": "Server requires STARTTLS — change encryption type",
|
||||
"smtpErrorTls": "Server requires TLS — change encryption type",
|
||||
"smtpErrorRefused": "Connection refused — check host and port",
|
||||
"smtpErrorTimeout": "Connection timeout — host unreachable",
|
||||
"smtpErrorRelay": "Server rejects sending from this address",
|
||||
"smtpErrorEof": "Connection closed by server",
|
||||
"smtpErrorUnknown": "SMTP error: {{ .Error }}",
|
||||
"eventMemoryHigh": "Memory high (%)",
|
||||
"validation": {
|
||||
"pathLeadingSlash": "Path must start with /"
|
||||
@@ -1605,8 +1421,6 @@
|
||||
"directdomains": "Direct Domains",
|
||||
"ipv4Routing": "IPv4 Routing",
|
||||
"ipv4RoutingDesc": "These options will route traffic based on a specific destination via IPv4.",
|
||||
"Template": "Advanced Xray Configuration Template",
|
||||
"TemplateDesc": "The final Xray config file will be generated based on this template.",
|
||||
"FreedomStrategy": "Freedom Protocol Strategy",
|
||||
"FreedomStrategyDesc": "Set the output strategy for the network in the Freedom Protocol.",
|
||||
"FreedomHappyEyeballs": "Freedom Happy Eyeballs (IPv4/IPv6)",
|
||||
@@ -1622,11 +1436,6 @@
|
||||
"Balancers": "Balancers",
|
||||
"balancerTagRequired": "Tag is required",
|
||||
"balancerSelectorRequired": "Pick at least one outbound",
|
||||
"balancerLive": "Live Target",
|
||||
"balancerOverride": "Override",
|
||||
"balancerOverridePh": "Auto (strategy)",
|
||||
"balancerLiveRefresh": "Refresh live balancer state",
|
||||
"balancerNotRunning": "This balancer is not active in the running Xray — save your changes or start Xray first",
|
||||
"routeTester": "Route Tester",
|
||||
"routeTesterDesc": "Ask the running Xray which outbound would handle a connection. No traffic is sent — the decision comes straight from the live routing engine.",
|
||||
"routeTesterDest": "Domain or IP",
|
||||
@@ -1643,7 +1452,6 @@
|
||||
"importOutbounds": "Import Outbounds",
|
||||
"exportOutbounds": "Export Outbounds",
|
||||
"importInvalidJson": "Invalid JSON — expected an array or an object with a matching key.",
|
||||
"completeTemplate": "All",
|
||||
"logLevel": "Log Level",
|
||||
"logLevelDesc": "The log level for error logs, indicating the information that needs to be recorded.",
|
||||
"accessLog": "Access Log",
|
||||
@@ -1674,7 +1482,6 @@
|
||||
"source": "Source",
|
||||
"dest": "Destination",
|
||||
"inbound": "Inbound",
|
||||
"balancer": "Balancer",
|
||||
"useComma": "Comma-separated list"
|
||||
},
|
||||
"routing": {
|
||||
@@ -1855,32 +1662,7 @@
|
||||
"alreadyAdded": "This server is already in the outbound list. Use {reset} to renew its key.",
|
||||
"provisionFailed": "Could not build the PIA outbound. Try again."
|
||||
},
|
||||
"tabBalancerSettings": "Balancer Settings",
|
||||
"tabObservatory": "Observatory",
|
||||
"observatory": {
|
||||
"autoManaged": "Observers are managed automatically from your balancers. Tune how they probe below — the watched outbounds follow your balancer selectors.",
|
||||
"emptyHint": "No connection observer is active. One is added automatically when you create a Least Ping or Least Load balancer — or a Random / Round-robin balancer with a fallback — so observer-backed balancers can check outbound health before choosing a target.",
|
||||
"mixedLegacy": "This config contains both Observatory and Burst Observatory. Xray uses one global observer, so this mixed legacy state is not supported; saving balancers will normalize it to one observer.",
|
||||
"subjectSelector": "Watched Outbounds",
|
||||
"subjectSelectorDesc": "Outbound tags this observer probes. Managed automatically from your balancers.",
|
||||
"probeURL": "Probe URL",
|
||||
"probeURLDesc": "URL fetched to measure each outbound. Should return HTTP 204.",
|
||||
"probeInterval": "Probe Interval",
|
||||
"probeIntervalDesc": "How often to probe each outbound, e.g. 30s, 1m, 2h45m.",
|
||||
"enableConcurrency": "Concurrent Probing",
|
||||
"enableConcurrencyDesc": "Probe all watched outbounds at once instead of one-by-one. Faster, but more visible on the network.",
|
||||
"destination": "Probe Destination",
|
||||
"destinationDesc": "URL fetched to measure each outbound. Should return HTTP 204.",
|
||||
"connectivity": "Connectivity Check",
|
||||
"connectivityDesc": "Optional local-network check URL, tried only after the destination fails. Leave empty to skip.",
|
||||
"interval": "Probe Interval",
|
||||
"intervalDesc": "Average time between probes per outbound, e.g. 1m. Minimum 10s.",
|
||||
"timeout": "Probe Timeout",
|
||||
"timeoutDesc": "How long to wait for a probe before it counts as failed, e.g. 5s.",
|
||||
"sampling": "Sampling Count",
|
||||
"samplingDesc": "Number of recent probe results kept to score each outbound.",
|
||||
"httpMethod": "HTTP Method",
|
||||
"httpMethodDesc": "HTTP method used for probes.",
|
||||
"deleteAlsoObservatory": "This is the last balancer using the Observatory, so it will be removed too.",
|
||||
"deleteAlsoBurst": "This is the last balancer using the Burst Observatory, so it will be removed too."
|
||||
},
|
||||
@@ -1892,26 +1674,8 @@
|
||||
},
|
||||
"balancer": {
|
||||
"balancerStrategy": "Strategy",
|
||||
"tag": "Tag",
|
||||
"tagDuplicate": "Tag already used by another balancer",
|
||||
"tagPlaceholder": "unique balancer tag",
|
||||
"selector": "Selector",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Select another balancer as fallback",
|
||||
"balancerFallbackInfo": "Traffic will be routed through: Balancer → Loopback → Server → Target Balancer → Outbound. This adds an extra hop through the server, which may introduce slight delays.",
|
||||
"balancerFallbackCycle": "Cannot set this balancer as fallback — it would create a circular dependency.",
|
||||
"balancerDeleteInUse": "Cannot delete this balancer — it is used as fallback by: {names}",
|
||||
"reservedPrefix": "_bl_ prefix is reserved for internal balancer loopback objects",
|
||||
"cycleTooltip": "Cycle: {path} → (back to {start})",
|
||||
"expected": "Expected",
|
||||
"expectedPlaceholder": "optimal node count",
|
||||
"maxRtt": "Max RTT",
|
||||
"tolerance": "Tolerance",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"costMatch": "Tag pattern",
|
||||
"costValue": "Weight",
|
||||
"costRegexp": "Regular expression match"
|
||||
"reservedPrefix": "_bl_ prefix is reserved for internal balancer loopback objects"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Secret Key",
|
||||
@@ -2013,252 +1777,14 @@
|
||||
"usage": "Usage",
|
||||
"addOutbound": "Add outbound"
|
||||
},
|
||||
"dns": {
|
||||
"enable": "Enable DNS",
|
||||
"enableDesc": "Enable built-in DNS server",
|
||||
"tag": "DNS Inbound Tag",
|
||||
"tagDesc": "This tag will be available as an Inbound tag in routing rules.",
|
||||
"clientIp": "Client IP",
|
||||
"clientIpDesc": "Used to notify the server of the specified IP location during DNS queries",
|
||||
"disableCache": "Disable cache",
|
||||
"disableCacheDesc": "Disables DNS caching",
|
||||
"disableFallback": "Disable Fallback",
|
||||
"disableFallbackDesc": "Disables fallback DNS queries",
|
||||
"disableFallbackIfMatch": "Disable Fallback If Match",
|
||||
"disableFallbackIfMatchDesc": "Disables fallback DNS queries when the matching domain list of the DNS server is hit",
|
||||
"enableParallelQuery": "Enable Parallel Query",
|
||||
"enableParallelQueryDesc": "Enable parallel DNS queries to multiple servers for faster resolution",
|
||||
"strategy": "Query Strategy",
|
||||
"strategyDesc": "Overall strategy to resolve domain names",
|
||||
"add": "Add Server",
|
||||
"edit": "Edit Server",
|
||||
"domains": "Domains",
|
||||
"expectIPs": "Expect IPs",
|
||||
"unexpectIPs": "Unexpected IPs",
|
||||
"useSystemHosts": "Use System Hosts",
|
||||
"useSystemHostsDesc": "Use the operating system's hosts file",
|
||||
"serveStale": "Serve Stale",
|
||||
"serveStaleDesc": "Return expired cached results while refreshing in the background",
|
||||
"serveExpiredTTL": "Serve Expired TTL",
|
||||
"serveExpiredTTLDesc": "Validity (seconds) of stale cache entries; 0 = never expire",
|
||||
"timeoutMs": "Timeout (ms)",
|
||||
"skipFallback": "Skip Fallback",
|
||||
"finalQuery": "Final Query",
|
||||
"hosts": "Hosts",
|
||||
"hostsAdd": "Add Host",
|
||||
"hostsEmpty": "No host overrides defined",
|
||||
"hostsDomain": "Domain (e.g. domain:example.com)",
|
||||
"hostsValues": "IP or domain — type and press Enter",
|
||||
"usePreset": "Use Preset",
|
||||
"dnsPresetTitle": "DNS Presets",
|
||||
"dnsPresetFamily": "Family",
|
||||
"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."
|
||||
},
|
||||
"fakedns": {
|
||||
"add": "Add Fake DNS",
|
||||
"ipPool": "IP Pool Subnet",
|
||||
"poolSize": "Pool Size"
|
||||
},
|
||||
"dns": {},
|
||||
"fakedns": {},
|
||||
"defaultOutbound": "Default Outbound",
|
||||
"defaultOutboundDesc": "Traffic that does not match any routing rule uses this outbound (Xray uses the first outbound in the list)."
|
||||
}
|
||||
},
|
||||
"tgbot": {
|
||||
"keyboardClosed": "❌ Custom keyboard closed!",
|
||||
"noResult": "❗ No result!",
|
||||
"noQuery": "❌ Query not found! Please use the command again!",
|
||||
"wentWrong": "❌ Something went wrong!",
|
||||
"noIpRecord": "❗ No IP Record!",
|
||||
"noInbounds": "❗ No inbound found!",
|
||||
"unlimited": "♾ Unlimited(Reset)",
|
||||
"add": "Add",
|
||||
"month": "Month",
|
||||
"months": "Months",
|
||||
"days": "Days",
|
||||
"hours": "Hours",
|
||||
"minutes": "Minutes",
|
||||
"unknown": "Unknown",
|
||||
"inbounds": "Inbounds",
|
||||
"clients": "Clients",
|
||||
"offline": "🔴 Offline",
|
||||
"online": "🟢 Online",
|
||||
"commands": {
|
||||
"unknown": "❗ Unknown command.",
|
||||
"pleaseChoose": "👇 Please choose:\r\n",
|
||||
"help": "🤖 Welcome to this bot! It's designed to offer specific data from the web panel and allows you to make modifications as needed.\r\n\r\n",
|
||||
"start": "👋 Hello <i>{{ .Firstname }}</i>.\r\n",
|
||||
"welcome": "🤖 Welcome to <b>{{ .Hostname }}</b> management bot.\r\n",
|
||||
"status": "✅ Bot is OK!",
|
||||
"usage": "❗ Please provide a text to search!",
|
||||
"getID": "🆔 Your ID: <code>{{ .ID }}</code>",
|
||||
"helpAdminCommands": "To restart Xray Core:\r\n<code>/restart</code>\r\n\r\nTo search for a client email:\r\n<code>/usage [Email]</code>\r\n\r\nTo search for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>",
|
||||
"helpClientCommands": "To search for statistics, use the following command:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>",
|
||||
"restartUsage": "\r\n\r\n<code>/restart</code>",
|
||||
"restartSuccess": "✅ Operation successful!",
|
||||
"restartFailed": "❗ Error in operation.\r\n\r\n<code>Error: {{ .Error }}</code>.",
|
||||
"xrayNotRunning": "❗ Xray Core is not running.",
|
||||
"startDesc": "Show the main menu",
|
||||
"helpDesc": "Bot help",
|
||||
"statusDesc": "Check bot status",
|
||||
"idDesc": "Show your Telegram ID",
|
||||
"usageDesc": "Show client usage: /usage email",
|
||||
"inboundDesc": "Search inbounds: /inbound remark (admin)",
|
||||
"restartDesc": "Restart Xray core (admin)",
|
||||
"clearallDesc": "Reset all clients' traffic (admin)"
|
||||
},
|
||||
"messages": {
|
||||
"cpuThreshold": "CPU Load {{ .Percent }}% exceeds the threshold of {{ .Threshold }}%",
|
||||
"selectUserFailed": "❌ Error in user selection!",
|
||||
"userSaved": "✅ Telegram User saved.",
|
||||
"loginSuccess": "✅ Logged in to the panel successfully.\r\n",
|
||||
"loginFailed": "❗️Login attempt to the panel failed.\r\n",
|
||||
"report": "🕰 Scheduled Reports: {{ .RunTime }}\r\n",
|
||||
"datetime": "⏰ Date&Time: {{ .DateTime }}\r\n",
|
||||
"hostname": "💻 Host: {{ .Hostname }}\r\n",
|
||||
"version": "🚀 3X-UI Version: {{ .Version }}\r\n",
|
||||
"xrayVersion": "📡 Xray Version: {{ .XrayVersion }}\r\n",
|
||||
"ipv6": "🌐 IPv6: {{ .IPv6 }}\r\n",
|
||||
"ipv4": "🌐 IPv4: {{ .IPv4 }}\r\n",
|
||||
"ip": "🌐 IP: {{ .IP }}\r\n",
|
||||
"ips": "🔢 IPs:\r\n{{ .IPs }}\r\n",
|
||||
"serverUpTime": "⏳ Uptime: {{ .UpTime }} {{ .Unit }}\r\n",
|
||||
"serverLoad": "📈 System Load: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n",
|
||||
"serverMemory": "📋 RAM: {{ .Current }}/{{ .Total }}\r\n",
|
||||
"tcpCount": "🔹 TCP: {{ .Count }}\r\n",
|
||||
"udpCount": "🔸 UDP: {{ .Count }}\r\n",
|
||||
"traffic": "🚦 Traffic: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n",
|
||||
"xrayStatus": "ℹ️ Status: {{ .State }}\r\n",
|
||||
"username": "👤 Username: {{ .Username }}\r\n",
|
||||
"reason": "❗️ Reason: {{ .Reason }}\r\n",
|
||||
"time": "⏰ Time: {{ .Time }}\r\n",
|
||||
"inbound": "📍 Inbound: {{ .Remark }}\r\n",
|
||||
"port": "🔌 Port: {{ .Port }}\r\n",
|
||||
"expire": "📅 Expire Date: {{ .Time }}\r\n",
|
||||
"expireIn": "📅 Expire In: {{ .Time }}\r\n",
|
||||
"active": "💡 Active: {{ .Enable }}\r\n",
|
||||
"enabled": "🚨 Enabled: {{ .Enable }}\r\n",
|
||||
"online": "🌐 Connection status: {{ .Status }}\r\n",
|
||||
"lastOnline": "🔙 Last online: {{ .Time }}\r\n",
|
||||
"email": "📧 Email: {{ .Email }}\r\n",
|
||||
"upload": "🔼 Upload: ↑{{ .Upload }}\r\n",
|
||||
"download": "🔽 Download: ↓{{ .Download }}\r\n",
|
||||
"total": "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
|
||||
"TGUser": "👤 Telegram User: {{ .TelegramID }}\r\n",
|
||||
"exhaustedCount": "🚨 Exhausted {{ .Type }} count:\r\n",
|
||||
"onlinesCount": "🌐 Online Clients: {{ .Count }}\r\n",
|
||||
"disabled": "🛑 Disabled: {{ .Disabled }}\r\n",
|
||||
"depleteSoon": "🔜 Deplete Soon: {{ .Deplete }}\r\n\r\n",
|
||||
"backupTime": "🗄 Backup Time: {{ .Time }}\r\n",
|
||||
"refreshedOn": "\r\n📋🔄 Refreshed On: {{ .Time }}\r\n\r\n",
|
||||
"yes": "✅ Yes",
|
||||
"no": "❌ No",
|
||||
"received_email": "📧📥 Email updated.",
|
||||
"received_comment": "💬📥 Comment updated.",
|
||||
"email_prompt": "📧 Default Email: {{ .ClientEmail }}\n\nEnter your email.",
|
||||
"comment_prompt": "💬 Default Comment: {{ .ClientComment }}\n\nEnter your comment.",
|
||||
"cancel": "❌ Process Canceled! \n\nYou can /start again anytime. 🔄",
|
||||
"error_add_client": "⚠️ Error:\n\n {{ .error }}",
|
||||
"using_default_value": "Okay, I'll stick with the default value. 😊",
|
||||
"incorrect_input": "Your input is not valid.\nThe phrases should be continuous without spaces.\nCorrect example: aaaaaa\nIncorrect example: aaa aaa 🚫",
|
||||
"AreYouSure": "Are you sure? 🤔",
|
||||
"SuccessResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Result: ✅ Success",
|
||||
"FailedResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Result: ❌ Failed \n\n🛠️ Error: [ {{ .ErrorMessage }} ]",
|
||||
"FinishProcess": "🔚 Traffic reset process finished for all clients.",
|
||||
"eventOutboundDown": "Outbound {{ .Tag }} is DOWN",
|
||||
"eventOutboundUp": "Outbound {{ .Tag }} is UP",
|
||||
"eventErrorDetail": "Error: {{ .Error }}",
|
||||
"eventDelayDetail": "Delay: {{ .Delay }}ms",
|
||||
"eventXrayCrash": "Xray CRASHED",
|
||||
"eventXrayCrashError": "Error: {{ .Error }}",
|
||||
"eventNodeDown": "Node {{ .Name }} is DOWN",
|
||||
"eventNodeUp": "Node {{ .Name }} is UP",
|
||||
"eventLoginFallback": "Login failed from {{ .Source }}",
|
||||
"memoryThreshold": "Memory Load {{ .Percent }}% exceeds the threshold of {{ .Threshold }}%"
|
||||
},
|
||||
"buttons": {
|
||||
"closeKeyboard": "❌ Close Keyboard",
|
||||
"cancel": "❌ Cancel",
|
||||
"cancelReset": "❌ Cancel Reset",
|
||||
"cancelIpLimit": "❌ Cancel IP Limit",
|
||||
"confirmResetTraffic": "✅ Confirm Reset Traffic?",
|
||||
"confirmClearIps": "✅ Confirm Clear IPs?",
|
||||
"confirmRemoveTGUser": "✅ Confirm Remove Telegram User?",
|
||||
"confirmToggle": "✅ Confirm Enable/Disable User?",
|
||||
"dbBackup": "Get DB Backup",
|
||||
"serverUsage": "Server Usage",
|
||||
"getInbounds": "Get Inbounds",
|
||||
"depleteSoon": "Deplete Soon",
|
||||
"clientUsage": "Get Usage",
|
||||
"onlines": "Online Clients",
|
||||
"commands": "Commands",
|
||||
"refresh": "🔄 Refresh",
|
||||
"clearIPs": "❌ Clear IPs",
|
||||
"removeTGUser": "❌ Remove Telegram User",
|
||||
"selectTGUser": "👤 Select Telegram User",
|
||||
"selectOneTGUser": "👤 Select a Telegram User:",
|
||||
"resetTraffic": "📈 Reset Traffic",
|
||||
"resetExpire": "📅 Change Expiry Date",
|
||||
"ipLog": "🔢 IP Log",
|
||||
"ipLimit": "🔢 IP Limit",
|
||||
"setTGUser": "👤 Set Telegram User",
|
||||
"toggle": "🔘 Enable / Disable",
|
||||
"custom": "🔢 Custom",
|
||||
"confirmNumber": "✅ Confirm: {{ .Num }}",
|
||||
"confirmNumberAdd": "✅ Confirm adding: {{ .Num }}",
|
||||
"limitTraffic": "🚧 Traffic Limit",
|
||||
"getBanLogs": "Get Ban Logs",
|
||||
"allClients": "All Clients",
|
||||
"addClient": "Add Client",
|
||||
"submitDisable": "Submit As Disable ☑️",
|
||||
"submitEnable": "Submit As Enable ✅",
|
||||
"use_default": "🏷️ Use default",
|
||||
"change_email": "⚙️📧 Email",
|
||||
"change_comment": "⚙️💬 Comment",
|
||||
"ResetAllTraffics": "Reset All Traffic",
|
||||
"SortedTrafficUsageReport": "Sorted Traffic Usage Report"
|
||||
},
|
||||
"answers": {
|
||||
"successfulOperation": "✅ Operation successful!",
|
||||
"errorOperation": "❗ Error in operation.",
|
||||
"getInboundsFailed": "❌ Failed to get inbounds.",
|
||||
"getClientsFailed": "❌ Failed to get clients.",
|
||||
"canceled": "❌ {{ .Email }}: Operation canceled.",
|
||||
"clientRefreshSuccess": "✅ {{ .Email }}: Client refreshed successfully.",
|
||||
"IpRefreshSuccess": "✅ {{ .Email }}: IPs refreshed successfully.",
|
||||
"TGIdRefreshSuccess": "✅ {{ .Email }}: Client's Telegram User refreshed successfully.",
|
||||
"resetTrafficSuccess": "✅ {{ .Email }}: Traffic reset successfully.",
|
||||
"setTrafficLimitSuccess": "✅ {{ .Email }}: Traffic limit saved successfully.",
|
||||
"expireResetSuccess": "✅ {{ .Email }}: Expire days reset successfully.",
|
||||
"resetIpSuccess": "✅ {{ .Email }}: IP limit {{ .Count }} saved successfully.",
|
||||
"clearIpSuccess": "✅ {{ .Email }}: IPs cleared successfully.",
|
||||
"getIpLog": "✅ {{ .Email }}: Get IP Log.",
|
||||
"getUserInfo": "✅ {{ .Email }}: Get Telegram User Info.",
|
||||
"removedTGUserSuccess": "✅ {{ .Email }}: Telegram User removed successfully.",
|
||||
"enableSuccess": "✅ {{ .Email }}: Enabled successfully.",
|
||||
"disableSuccess": "✅ {{ .Email }}: Disabled successfully.",
|
||||
"askToAddUserId": "Your configuration is not found!\r\nPlease ask your admin to use your Telegram ChatID in your configuration(s).\r\n\r\nYour ChatID: <code>{{ .TgUserID }}</code>",
|
||||
"chooseClient": "Choose a Client for Inbound {{ .Inbound }}",
|
||||
"chooseInbound": "Choose an Inbound"
|
||||
}
|
||||
"noIpRecord": "❗ No IP Record!"
|
||||
},
|
||||
"email": {
|
||||
"labelStatus": "Status",
|
||||
"labelOutbound": "Outbound",
|
||||
"labelNode": "Node",
|
||||
"labelError": "Error",
|
||||
"labelDelay": "Delay",
|
||||
"labelUsername": "Username",
|
||||
"labelIP": "IP",
|
||||
"labelReason": "Reason",
|
||||
"labelSource": "Source",
|
||||
"statusCrashed": "CRASHED",
|
||||
"statusHigh": "HIGH",
|
||||
"statusSuccess": "SUCCESS",
|
||||
"statusFailed": "FAILED",
|
||||
"statusDown": "DOWN",
|
||||
"statusUp": "UP"
|
||||
}
|
||||
}
|
||||
"email": {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user