精简版第四轮补裁(P4): 页面层摘除 + Xray更新端点下线 + 本机核心监管下线

页面层(用户真机截图发现前两轮漏裁):
- 设置: 摘除 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:
Muse
2026-10-20 14:58:05 +00:00
parent 945b3a56a2
commit 4828f946b1
56 changed files with 149 additions and 11458 deletions
+4 -466
View File
@@ -67,16 +67,12 @@
"success": "Berhasil",
"lastOnline": "Terakhir online",
"lastSubFetch": "Pengambilan langganan terakhir",
"getVersion": "Dapatkan Versi",
"install": "Instal",
"clients": "Klien",
"usage": "Penggunaan",
"twoFactorCode": "Kode",
"remained": "Tersisa",
"security": "Keamanan",
"emptyDnsDesc": "Tidak ada server DNS yang ditambahkan.",
"emptyFakeDnsDesc": "Tidak ada server Fake DNS yang ditambahkan.",
"emptyBalancersDesc": "Tidak ada penyeimbang yang ditambahkan.",
"somethingWentWrong": "Terjadi kesalahan",
"subscription": {
"title": "Info langganan",
@@ -86,7 +82,6 @@
"uploaded": "Diunggah",
"expiry": "Kedaluwarsa",
"totalQuota": "Kuota total",
"individualLinks": "Tautan individual",
"active": "Aktif",
"inactive": "Nonaktif",
"unlimited": "Tanpa batas",
@@ -136,9 +131,6 @@
"xrayStatus": "Xray",
"stopXray": "Hentikan",
"restartXray": "Mulai ulang",
"xraySwitch": "Versi",
"xrayUpdates": "Pembaruan Xray",
"xraySwitchClickDesk": "Pilih dengan hati-hati, karena versi yang lebih lama mungkin tidak kompatibel dengan konfigurasi saat ini.",
"updatePanel": "Perbarui Panel",
"panelUpdateDesc": "Ini akan memperbarui 3X-UI ke rilis terbaru dan me-restart layanan panel.",
"currentPanelVersion": "Versi panel saat ini",
@@ -200,9 +192,6 @@
"download": "Unduh",
"sent": "Dikirim",
"received": "Diterima",
"xraySwitchVersionDialog": "Apakah Anda yakin ingin mengubah versi Xray?",
"xraySwitchVersionDialogDesc": "Ini akan mengubah versi Xray ke #version#.",
"xraySwitchVersionPopover": "Xray berhasil diperbarui",
"panelUpdateDialog": "Apakah Anda benar-benar ingin memperbarui panel?",
"panelUpdateDialogDesc": "Ini akan memperbarui 3X-UI ke #version# dan me-restart layanan panel.",
"panelUpdateStartedPopover": "Pembaruan panel dimulai",
@@ -210,24 +199,6 @@
"panelUpdateFailedDesc": "Pembaruan tidak selesai dengan sukses. Periksa log server, atau jalankan 'x-ui update' dari baris perintah.",
"panelUpdateUnknownTitle": "Tidak dapat memastikan pembaruan selesai",
"panelUpdateUnknownDesc": "Panel tidak melaporkan hasil tepat waktu. Muat ulang untuk memeriksa versi saat ini, atau periksa log server.",
"geofileUpdateDialog": "Apakah Anda yakin ingin memperbarui geofile?",
"geofileUpdateDialogDesc": "Ini akan memperbarui file #filename#.",
"geofilesUpdateDialogDesc": "Ini akan memperbarui semua berkas.",
"geofilesUpdateAll": "Perbarui semua",
"geofileUpdatePopover": "Geofile berhasil diperbarui",
"geodataTitle": "Pembaruan Otomatis Geodata",
"geodataHint": "Xray mengunduh berkas ini sesuai jadwal dan memuat ulang tanpa restart. URL harus HTTPS. Setiap berkas harus sudah ada di folder bin agar Xray dapat memperbaruinya.",
"geodataCron": "Jadwal (cron)",
"geodataOutbound": "Unduh melalui outbound (opsional)",
"geodataFile": "Nama berkas",
"geodataAddFile": "Tambah berkas",
"geodataSaveRestart": "Simpan & Mulai Ulang Xray",
"geodataConfirmTitle": "Simpan pengaturan geodata?",
"geodataConfirmContent": "Templat konfigurasi Xray akan diperbarui dan Xray akan dimulai ulang.",
"geodataInvalidUrl": "Setiap berkas memerlukan URL HTTPS.",
"geodataInvalidFile": "Nama berkas harus berupa nama sederhana, mis. geosite_custom.dat (tanpa path).",
"geodataInvalidCron": "Cron harus terdiri dari 5 bagian, mis. 0 4 * * *",
"geodataEmpty": "Belum ada berkas yang dikonfigurasi. Pada aturan routing, rujuk berkas sebagai ext:geosite_custom.dat:category.",
"dontRefresh": "Instalasi sedang berlangsung, harap jangan menyegarkan halaman ini",
"logs": "Log",
"accessLogs": "Log Akses",
@@ -1082,7 +1053,6 @@
"warnDefaultBasePath": "Base path default \"/\" sudah umum diketahui — ubah ke path acak.",
"warnDefaultSubPath": "Path langganan default \"/sub/\" sudah umum diketahui — ubahlah.",
"warnDefaultJsonPath": "Path langganan JSON default \"/json/\" sudah umum diketahui — ubahlah.",
"TGBotSettings": "Bot Telegram",
"panelListeningIP": "IP Pendengar",
"panelListeningIPDesc": "Alamat IP untuk panel web. (biarkan kosong untuk mendengarkan semua IP)",
"panelListeningDomain": "Domain Pendengar",
@@ -1107,43 +1077,12 @@
"currentPassword": "Kata Sandi Saat Ini",
"newUsername": "Username Baru",
"newPassword": "Kata Sandi Baru",
"telegramBotEnable": "Aktifkan Bot Telegram",
"telegramBotEnableDesc": "Mengaktifkan bot Telegram.",
"telegramToken": "Token Telegram",
"telegramTokenDesc": "Token bot Telegram yang diperoleh dari '{'@'}BotFather'.",
"telegramProxy": "Proxy SOCKS",
"telegramProxyDesc": "Mengaktifkan proxy SOCKS5 untuk terhubung ke Telegram. (sesuaikan pengaturan sesuai panduan)",
"telegramAPIServer": "Server API Telegram",
"telegramAPIServerDesc": "Server API Telegram yang akan digunakan. Biarkan kosong untuk menggunakan server default.",
"telegramChatId": "ID Obrolan Admin",
"telegramChatIdDesc": "ID Obrolan Admin Telegram. (dipisahkan koma)(dapatkan di sini {'@'}userinfobot) atau (gunakan perintah '/id' di bot)",
"telegramNotifyTime": "Waktu Notifikasi",
"telegramNotifyTimeDesc": "Seberapa sering bot Telegram mengirim laporan berkala. Pilih interval siap pakai, atau pilih Kustom untuk memasukkan ekspresi crontab.",
"notifyTime": {
"every": "@every — ulangi dalam interval",
"hourly": "@hourly — setiap jam",
"daily": "@daily — setiap hari pukul 00:00",
"weekly": "@weekly — setiap minggu",
"monthly": "@monthly — setiap bulan",
"custom": "Kustom (crontab)",
"seconds": "Detik",
"minutes": "Menit",
"hours": "Jam",
"interval": "Interval",
"unit": "Satuan"
},
"tgNotifyBackup": "Cadangan Database",
"tgNotifyBackupDesc": "Kirim berkas cadangan database dengan laporan.",
"tgNotifyLogin": "Notifikasi Login",
"tgNotifyLoginDesc": "Dapatkan notifikasi tentang username, alamat IP, dan waktu setiap kali seseorang mencoba masuk ke panel web Anda.",
"sessionMaxAge": "Durasi Sesi",
"sessionMaxAgeDesc": "Durasi di mana Anda dapat tetap masuk. (unit: menit)",
"expireTimeDiff": "Notifikasi Tanggal Kedaluwarsa",
"expireTimeDiffDesc": "Dapatkan notifikasi tentang tanggal kedaluwarsa saat mencapai ambang batas ini. (unit: hari)",
"trafficDiff": "Notifikasi Batas Traffic",
"trafficDiffDesc": "Dapatkan notifikasi tentang batas traffic saat mencapai ambang batas ini. (unit: GB)",
"tgNotifyCpu": "Notifikasi Beban CPU",
"tgNotifyCpuDesc": "Dapatkan notifikasi jika beban CPU melebihi ambang batas ini. (unit: %)",
"timeZone": "Zone Waktu",
"timeZoneDesc": "Tugas terjadwal akan berjalan berdasarkan zona waktu ini.",
"subSettings": "Langganan",
@@ -1208,10 +1147,6 @@
"subEncryptDesc": "Konten yang dikembalikan dari layanan langganan akan dienkripsi Base64.",
"subURI": "URI Proxy Terbalik",
"subURIDesc": "URL dasar lengkap (scheme://domain[:port]/path/) untuk tautan langganan dan kode QR, digunakan sebagai pengganti Domain/Port Pendengar. Atur ini kapan pun langganan diakses melalui reverse proxy atau domain/port yang berbeda dari yang di atas.",
"externalTrafficInformEnable": "Informasikan API eksternal pada setiap pembaruan lalu lintas.",
"externalTrafficInformEnableDesc": "Beritahu API eksternal setiap kali ada pembaruan trafik.",
"externalTrafficInformURI": "Lalu Lintas Eksternal Menginformasikan URI",
"externalTrafficInformURIDesc": "Pembaruan lalu lintas dikirim ke URI ini.",
"restartXrayOnClientDisable": "Nyalakan Ulang Xray Setelah Nonaktif Otomatis",
"restartXrayOnClientDisableDesc": "Saat klien otomatis dinonaktifkan karena kedaluwarsa atau batas trafik, mulai ulang Xray.",
"fragment": "Fragmentasi",
@@ -1221,38 +1156,6 @@
"noisesSett": "Pengaturan Noises",
"trustedProxyCidrs": "CIDR proxy tepercaya",
"trustedProxyCidrsDesc": "IP/CIDR (dipisahkan koma) yang diizinkan mengatur header forwarded host, proto, dan client IP.",
"ldap": {
"enable": "Aktifkan sinkronisasi LDAP",
"host": "LDAP host",
"port": "Port LDAP",
"useTls": "Gunakan TLS (LDAPS)",
"skipTlsVerify": "Lewati verifikasi sertifikat TLS",
"skipTlsVerifyDesc": "Tidak aman — menonaktifkan validasi sertifikat server. Gunakan hanya dengan CA internal/tidak terpercaya.",
"bindDn": "Bind DN",
"passwordConfigured": "Terkonfigurasi; biarkan kosong untuk mempertahankan kata sandi saat ini.",
"passwordUnconfigured": "Tidak terkonfigurasi.",
"passwordPlaceholder": "Terkonfigurasi — masukkan nilai baru untuk menggantikan",
"baseDn": "Base DN",
"userFilter": "Filter pengguna",
"userAttr": "Atribut pengguna (username/email)",
"vlessField": "Atribut flag VLESS",
"flagField": "Atribut flag umum (opsional)",
"flagFieldDesc": "Jika diatur, menimpa flag VLESS — mis. shadowInactive.",
"truthyValues": "Nilai truthy",
"truthyValuesDesc": "Dipisahkan koma; default: true,1,yes,on",
"invertFlag": "Balik flag",
"invertFlagDesc": "Aktifkan saat atribut berarti «dinonaktifkan» (mis. shadowInactive).",
"syncSchedule": "Jadwal sinkronisasi",
"syncScheduleDesc": "String mirip cron, mis. @every 1m",
"inboundTags": "Tag inbound",
"inboundTagsDesc": "Inbound di mana sinkronisasi LDAP dapat membuat/menghapus klien secara otomatis.",
"noInbounds": "Tidak ada inbound. Buat dulu di Inbound.",
"autoCreate": "Buat klien otomatis",
"autoDelete": "Hapus klien otomatis",
"defaultTotalGb": "Total default (GB)",
"defaultExpiryDays": "Kedaluwarsa default (hari)",
"defaultIpLimit": "Batas IP default"
},
"subFormats": {
"finalMask": "Final Mask",
"finalMaskDesc": "Menyisipkan mask TCP/UDP Xray finalmask dan parameter QUIC ke setiap profil Xray JSON yang dibuat. Membutuhkan aplikasi klien yang mendukung langganan Xray JSON dan inti Xray terbaru.",
@@ -1276,31 +1179,15 @@
"muxSett": "Pengaturan Mux",
"direct": "Koneksi langsung",
"directDesc": "Secara langsung membuat koneksi dengan domain atau rentang IP negara tertentu.",
"notifications": "Notifikasi",
"certs": "Sertifikat",
"externalTraffic": "Lalu Lintas Eksternal",
"dateAndTime": "Tanggal dan Waktu",
"proxyAndServer": "Proxy dan Server",
"intervals": "Interval",
"information": "Informasi",
"profile": "Profil",
"language": "Bahasa",
"telegramBotLanguage": "Bahasa Bot Telegram",
"security": {
"admin": "Kredensial admin",
"twoFactor": "Autentikasi dua faktor",
"twoFactorEnable": "Aktifkan 2FA",
"twoFactorEnableDesc": "Menambahkan lapisan autentikasi tambahan untuk keamanan lebih.",
"twoFactorModalSetTitle": "Aktifkan autentikasi dua faktor",
"twoFactorModalDeleteTitle": "Nonaktifkan autentikasi dua faktor",
"twoFactorModalSteps": "Untuk menyiapkan autentikasi dua faktor, lakukan beberapa langkah:",
"twoFactorModalFirstStep": "1. Pindai kode QR ini di aplikasi autentikasi atau salin token di dekat kode QR dan tempelkan ke aplikasi",
"twoFactorModalSecondStep": "2. Masukkan kode dari aplikasi",
"twoFactorModalRemoveStep": "Masukkan kode dari aplikasi untuk menghapus autentikasi dua faktor.",
"twoFactorModalChangeCredentialsTitle": "Ubah kredensial",
"twoFactorModalChangeCredentialsStep": "Masukkan kode dari aplikasi untuk mengubah kredensial administrator.",
"twoFactorModalSetSuccess": "Autentikasi dua faktor telah berhasil dibuat",
"twoFactorModalDeleteSuccess": "Autentikasi dua faktor telah berhasil dihapus",
"twoFactorModalError": "Kode salah",
"show": "Tampilkan",
"hide": "Sembunyikan",
@@ -1323,36 +1210,6 @@
"getOutboundTrafficError": "Gagal mendapatkan lalu lintas keluar",
"resetOutboundTrafficError": "Gagal mereset lalu lintas keluar"
},
"smtpSettings": "Pengaturan SMTP",
"smtpEnable": "Aktifkan Notifikasi Email",
"smtpEnableDesc": "Aktifkan notifikasi email melalui SMTP",
"smtpHost": "Host SMTP",
"smtpHostDesc": "Nama host server SMTP (mis. smtp.gmail.com)",
"smtpPort": "Port SMTP",
"smtpPortDesc": "Port server SMTP (bawaan: 587)",
"smtpUsername": "Nama Pengguna SMTP",
"smtpUsernameDesc": "Nama pengguna autentikasi SMTP",
"smtpFrom": "Alamat Pengirim (From)",
"smtpFromDesc": "Alamat yang dipakai pada header From email. Kosongkan untuk memakai nama pengguna.",
"smtpFromName": "Nama Pengirim (From)",
"smtpFromNameDesc": "Nama tampilan opsional sebelum alamat pada header From.",
"smtpPassword": "Kata Sandi SMTP",
"smtpPasswordDesc": "Kata sandi autentikasi SMTP",
"smtpTo": "Penerima",
"smtpToDesc": "Alamat email penerima dipisahkan dengan koma",
"emailSettings": "Email",
"emailNotifications": "Notifikasi",
"smtpEventBusNotify": "Notifikasi Peristiwa Email",
"smtpEventBusNotifyDesc": "Pilih peristiwa yang memicu notifikasi email",
"tgEventBusNotify": "Notifikasi Peristiwa Telegram",
"tgEventBusNotifyDesc": "Pilih peristiwa yang memicu notifikasi Telegram",
"testSmtp": "Kirim Email Uji",
"testTgBot": "Kirim Pesan Uji",
"eventGroupOutbound": "Outbound",
"eventGroupXray": "Xray Core",
"eventGroupSystem": "Sistem",
"eventGroupSecurity": "Keamanan",
"eventGroupNode": "Node",
"eventOutboundDown": "Mati",
"eventOutboundUp": "Aktif",
"eventXrayCrash": "Crash",
@@ -1360,36 +1217,7 @@
"eventNodeUp": "Aktif",
"eventCPUHigh": "CPU tinggi (%)",
"requestFailed": "Permintaan gagal",
"smtpEncryption": "Enkripsi",
"smtpEncryptionDesc": "Metode enkripsi koneksi SMTP",
"smtpEncryptionNone": "Tidak ada (teks biasa)",
"smtpEncryptionStartTLS": "STARTTLS",
"smtpEncryptionTLS": "TLS (implisit)",
"smtpStageConnect": "Koneksi",
"smtpStageAuth": "Autentikasi",
"smtpStageSend": "Kirim",
"smtpTestSuccess": "Email uji berhasil dikirim",
"smtpHostNotConfigured": "Host SMTP belum dikonfigurasi",
"smtpNoRecipients": "Tidak ada penerima yang dikonfigurasi",
"smtpFromNotConfigured": "Alamat pengirim SMTP belum dikonfigurasi",
"eventLoginAttempt": "Percobaan masuk",
"telegramTokenConfigured": "Terkonfigurasi; kosongkan untuk mempertahankan token saat ini.",
"telegramTokenPlaceholder": "Terkonfigurasi - masukkan token baru untuk mengganti",
"smtpPasswordConfigured": "Terkonfigurasi; kosongkan untuk mempertahankan kata sandi saat ini.",
"smtpPasswordPlaceholder": "Terkonfigurasi - masukkan kata sandi baru untuk mengganti",
"smtpNotInitialized": "SMTP belum diinisialisasi",
"tgBotNotEnabled": "Bot Telegram tidak aktif",
"tgTestFailed": "Uji Telegram gagal",
"tgTestSuccess": "Pesan uji terkirim ke Telegram",
"tgBotNotRunning": "Bot Telegram tidak berjalan",
"smtpErrorAuth": "Autentikasi gagal — periksa nama pengguna dan kata sandi",
"smtpErrorStarttls": "Server memerlukan STARTTLS — ubah jenis enkripsi",
"smtpErrorTls": "Server memerlukan TLS — ubah jenis enkripsi",
"smtpErrorRefused": "Koneksi ditolak — periksa host dan port",
"smtpErrorTimeout": "Koneksi waktu habis — host tidak dapat dijangkau",
"smtpErrorRelay": "Server menolak pengiriman dari alamat ini",
"smtpErrorEof": "Koneksi ditutup oleh server",
"smtpErrorUnknown": "Kesalahan SMTP: {{ .Error }}",
"eventMemoryHigh": "Penggunaan memori tinggi (%)",
"remarkTemplate": "Templat Catatan",
"remarkTemplateDesc": "Jika diatur, ini menggantikan model catatan untuk setiap tautan langganan — tulis format Anda sendiri dengan token variabel (gunakan tombol untuk menyisipkannya). Biarkan kosong untuk memakai model di atas.",
@@ -1475,8 +1303,6 @@
"directdomains": "Domain Langsung",
"ipv4Routing": "Perutean IPv4",
"ipv4RoutingDesc": "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui IPv4.",
"Template": "Template Konfigurasi Xray Lanjutan",
"TemplateDesc": "File konfigurasi Xray akhir akan dibuat berdasarkan template ini.",
"FreedomStrategy": "Strategi Protokol Freedom",
"FreedomStrategyDesc": "Atur strategi output untuk jaringan dalam Protokol Freedom.",
"FreedomHappyEyeballs": "Freedom Happy Eyeballs (IPv4/IPv6)",
@@ -1500,11 +1326,6 @@
"Balancers": "Penyeimbang",
"balancerTagRequired": "Tag wajib diisi",
"balancerSelectorRequired": "Pilih setidaknya satu outbound",
"balancerLive": "Target Saat Ini",
"balancerOverride": "Paksa Tujuan",
"balancerOverridePh": "Otomatis (strategi)",
"balancerLiveRefresh": "Perbarui status penyeimbang beban",
"balancerNotRunning": "Penyeimbang ini tidak aktif di Xray yang berjalan — simpan perubahan atau mulai Xray terlebih dahulu",
"routeTester": "Uji Rute",
"routeTesterDesc": "Tanyakan kepada Xray yang berjalan outbound mana yang akan menangani koneksi. Tidak ada lalu lintas yang dikirim — keputusan langsung datang dari mesin routing langsung.",
"routeTesterDest": "Domain atau IP",
@@ -1516,7 +1337,6 @@
"routeTesterViaBalancer": "melalui penyeimbang",
"routeTesterDefaultOutbound": "Tidak ada aturan routing yang cocok — lalu lintas menuju outbound default (pertama).",
"Routings": "Aturan Pengalihan",
"completeTemplate": "Semua",
"logLevel": "Tingkat Log",
"logLevelDesc": "Tingkat log untuk log kesalahan, menunjukkan informasi yang perlu dicatat.",
"accessLog": "Log Akses",
@@ -1544,7 +1364,6 @@
"source": "Sumber",
"dest": "Tujuan",
"inbound": "Masuk",
"balancer": "Pengimbang",
"useComma": "Item yang dipisahkan koma"
},
"routing": {
@@ -1725,32 +1544,7 @@
"alreadyAdded": "Server ini sudah ada di daftar outbound. Gunakan {reset} untuk memperbarui kuncinya.",
"provisionFailed": "Gagal membuat outbound PIA. Coba lagi."
},
"tabBalancerSettings": "Pengaturan Balancer",
"tabObservatory": "Observatory",
"observatory": {
"autoManaged": "Observer dikelola otomatis dari balancer Anda. Atur cara mereka melakukan probe di bawah; outbound yang dipantau mengikuti selector balancer.",
"emptyHint": "Tidak ada observer koneksi yang aktif. Satu akan ditambahkan otomatis saat Anda membuat balancer Least Ping atau Least Load — atau balancer Random / Round-robin dengan fallback — sehingga balancer yang memakai observer dapat memeriksa kesehatan outbound sebelum memilih target.",
"mixedLegacy": "Konfigurasi ini berisi Observatory dan Burst Observatory sekaligus. Xray memakai satu observer global, jadi status campuran lama ini tidak didukung; menyimpan balancer akan menormalkannya menjadi satu observer.",
"subjectSelector": "Outbound yang Dipantau",
"subjectSelectorDesc": "Tag outbound yang di-probe observer ini. Dikelola otomatis dari balancer Anda.",
"probeURL": "URL Probe",
"probeURLDesc": "URL yang diminta untuk mengukur setiap outbound. Harus mengembalikan HTTP 204.",
"probeInterval": "Interval Probe",
"probeIntervalDesc": "Seberapa sering memprobe tiap outbound, mis. 30s, 1m, 2h45m.",
"enableConcurrency": "Probe Bersamaan",
"enableConcurrencyDesc": "Probe semua outbound yang dipantau sekaligus, bukan satu per satu. Lebih cepat, tetapi lebih terlihat di jaringan.",
"destination": "Tujuan Probe",
"destinationDesc": "URL yang diminta untuk mengukur setiap outbound. Harus mengembalikan HTTP 204.",
"connectivity": "Pemeriksaan Konektivitas",
"connectivityDesc": "URL pemeriksaan jaringan lokal opsional, dicoba hanya setelah tujuan gagal. Kosongkan untuk melewati.",
"interval": "Interval Probe",
"intervalDesc": "Rata-rata waktu antar probe per outbound, mis. 1m. Minimal 10s.",
"timeout": "Batas Waktu Probe",
"timeoutDesc": "Berapa lama menunggu probe sebelum dianggap gagal, mis. 5s.",
"sampling": "Jumlah Sampling",
"samplingDesc": "Jumlah hasil probe terbaru yang disimpan untuk menilai tiap outbound.",
"httpMethod": "Metode HTTP",
"httpMethodDesc": "Metode HTTP yang digunakan untuk probe.",
"deleteAlsoObservatory": "Ini balancer terakhir yang memakai Observatory, jadi itu juga akan dihapus.",
"deleteAlsoBurst": "Ini balancer terakhir yang memakai Burst Observatory, jadi itu juga akan dihapus."
},
@@ -1762,25 +1556,7 @@
},
"balancer": {
"balancerStrategy": "Strategi",
"tag": "Tag",
"tagDuplicate": "Tag sudah digunakan oleh balancer lain",
"tagPlaceholder": "tag balancer unik",
"selector": "Selector",
"fallback": "Fallback",
"cycleTooltip": "Siklus: {path} → (kembali ke {start})",
"expected": "Diharapkan",
"expectedPlaceholder": "jumlah node optimal",
"maxRtt": "Maks. RTT",
"tolerance": "Toleransi",
"baselines": "Baselines",
"costs": "Costs",
"costMatch": "Pola tag",
"costValue": "Bobot",
"costRegexp": "Pencocokan ekspresi reguler",
"balancerDeleteInUse": "Tidak dapat menghapus load balancer ini — digunakan sebagai fallback untuk: {names}",
"balancerFallbackCycle": "Tidak dapat mengatur load balancer ini sebagai fallback — akan menciptakan dependensi siklik.",
"balancerFallbackInfo": "Lalu lintas akan di-routing melalui: Load Balancer → Loopback → Server → Load Balancer tujuan → Koneksi keluar. Ini menambahkan hop tambahan melalui server, yang dapat menyebabkan sedikit penundaan.",
"fallbackBalancerHint": "Pilih load balancer lain sebagai fallback",
"reservedPrefix": "Awalan _bl_ dicadangkan untuk objek loopback internal load balancer"
},
"wireguard": {
@@ -1883,55 +1659,8 @@
"usage": "Penggunaan",
"addOutbound": "Tambah outbound"
},
"dns": {
"enable": "Aktifkan DNS",
"enableDesc": "Aktifkan server DNS bawaan",
"tag": "Tanda DNS Masuk",
"tagDesc": "Tanda ini akan tersedia sebagai tanda masuk dalam aturan penataan.",
"clientIp": "IP Klien",
"clientIpDesc": "Digunakan untuk memberi tahu server tentang lokasi IP yang ditentukan selama kueri DNS",
"disableCache": "Nonaktifkan cache",
"disableCacheDesc": "Menonaktifkan caching DNS",
"disableFallback": "Nonaktifkan Fallback",
"disableFallbackDesc": "Menonaktifkan kueri DNS fallback",
"disableFallbackIfMatch": "Nonaktifkan Fallback Jika Cocok",
"disableFallbackIfMatchDesc": "Menonaktifkan kueri DNS fallback ketika daftar domain yang cocok dari server DNS terpenuhi",
"enableParallelQuery": "Aktifkan Kueri Paralel",
"enableParallelQueryDesc": "Aktifkan kueri DNS paralel ke beberapa server untuk resolusi yang lebih cepat",
"strategy": "Strategi Kueri",
"strategyDesc": "Strategi keseluruhan untuk menyelesaikan nama domain",
"add": "Tambahkan Server",
"edit": "Sunting Server",
"domains": "Domain",
"expectIPs": "IP yang Diharapkan",
"unexpectIPs": "IP tak terduga",
"useSystemHosts": "Gunakan Hosts Sistem",
"useSystemHostsDesc": "Gunakan file hosts dari sistem yang terinstal",
"serveStale": "Sajikan Kedaluwarsa",
"serveStaleDesc": "Mengembalikan hasil cache yang kedaluwarsa saat memperbarui di latar belakang",
"serveExpiredTTL": "TTL Kedaluwarsa",
"serveExpiredTTLDesc": "Masa berlaku (detik) entri cache kedaluwarsa; 0 = tidak pernah kedaluwarsa",
"timeoutMs": "Batas waktu (ms)",
"skipFallback": "Lewati Fallback",
"finalQuery": "Kueri Akhir",
"hosts": "Hosts",
"hostsAdd": "Tambah Host",
"hostsEmpty": "Tidak ada Host yang ditentukan",
"hostsDomain": "Domain (mis. domain:example.com)",
"hostsValues": "IP atau domain — ketik dan tekan Enter",
"usePreset": "Gunakan templat",
"dnsPresetTitle": "Templat DNS",
"dnsPresetFamily": "Keluarga",
"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."
},
"fakedns": {
"add": "Tambahkan DNS Palsu",
"ipPool": "Subnet Kumpulan IP",
"poolSize": "Ukuran Kolam"
},
"dns": {},
"fakedns": {},
"defaultOutbound": "Outbound default",
"defaultOutboundDesc": "Lalu lintas tanpa aturan routing memakai outbound ini (yang pertama dalam daftar)."
},
@@ -2055,198 +1784,7 @@
}
},
"tgbot": {
"keyboardClosed": "❌ Keyboard ditutup!",
"noResult": "❗ Tidak ada hasil!",
"noQuery": "❌ Kueri tidak ditemukan! Silakan gunakan perintah lagi!",
"wentWrong": "❌ Terjadi kesalahan!",
"noIpRecord": "❗ Tidak ada Catatan IP!",
"noInbounds": "❗ Tidak ada inbound yang ditemukan!",
"unlimited": "♾ Tidak terbatas (Reset)",
"add": "Tambah",
"month": "Bulan",
"months": "Bulan",
"days": "Hari",
"hours": "Jam",
"minutes": "Menit",
"unknown": "Tidak diketahui",
"inbounds": "Inbound",
"clients": "Klien",
"offline": "🔴 Offline",
"online": "🟢 Online",
"commands": {
"unknown": "❗ Perintah tidak dikenal.",
"pleaseChoose": "👇 Harap pilih:\r\n",
"help": "🤖 Selamat datang di bot ini! Ini dirancang untuk menyediakan data tertentu dari panel web dan memungkinkan Anda melakukan modifikasi sesuai kebutuhan.\r\n\r\n",
"start": "👋 Halo <i>{{ .Firstname }}</i>.\r\n",
"welcome": "🤖 Selamat datang di <b>{{.Hostname }}</b> bot managemen.\r\n",
"status": "✅ Bot dalam keadaan baik!",
"usage": "❗ Harap berikan teks untuk mencari!",
"getID": "🆔 ID Anda: <code>{{ .ID }}</code>",
"helpAdminCommands": "Untuk memulai ulang Xray Core:\r\n<code>/restart</code>\r\n\r\nUntuk mencari email klien:\r\n<code>/usage [Email]</code>\r\n\r\nUntuk mencari inbound (dengan statistik klien):\r\n<code>/inbound [Catatan]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>",
"helpClientCommands": "Untuk mencari statistik, gunakan perintah berikut:\r\n<code>/usage [Email]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>",
"restartUsage": "\r\n\r\n<code>/restart</code>",
"restartSuccess": "✅ Operasi berhasil!",
"restartFailed": "❗ Kesalahan dalam operasi.\r\n\r\n<code>Error: {{ .Error }}</code>.",
"xrayNotRunning": "❗ Xray Core tidak berjalan.",
"startDesc": "Tampilkan menu utama",
"helpDesc": "Bantuan bot",
"statusDesc": "Periksa status bot",
"idDesc": "Tampilkan ID Telegram Anda",
"usageDesc": "Lihat pemakaian klien: /usage email",
"inboundDesc": "Cari inbound: /inbound nama (admin)",
"restartDesc": "Mulai ulang inti Xray (admin)",
"clearallDesc": "Reset trafik semua klien (admin)"
},
"messages": {
"cpuThreshold": "Beban CPU {{ .Percent }}% melebihi batas {{ .Threshold }}%",
"selectUserFailed": "❌ Kesalahan dalam pemilihan pengguna!",
"userSaved": "✅ Pengguna Telegram tersimpan.",
"loginSuccess": "✅ Berhasil masuk ke panel.\r\n",
"loginFailed": "❗️ Gagal masuk ke panel.\r\n",
"report": "🕰 Laporan Terjadwal: {{ .RunTime }}\r\n",
"datetime": "⏰ Tanggal & Waktu: {{ .DateTime }}\r\n",
"hostname": "💻 Host: {{ .Hostname }}\r\n",
"version": "🚀 Versi 3X-UI: {{ .Version }}\r\n",
"xrayVersion": "📡 Versi Xray: {{ .XrayVersion }}\r\n",
"ipv6": "🌐 IPv6: {{ .IPv6 }}\r\n",
"ipv4": "🌐 IPv4: {{ .IPv4 }}\r\n",
"ip": "🌐 IP: {{ .IP }}\r\n",
"ips": "🔢 IP:\r\n{{ .IPs }}\r\n",
"serverUpTime": "⏳ Waktu Aktif: {{ .UpTime }} {{ .Unit }}\r\n",
"serverLoad": "📈 Beban Sistem: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n",
"serverMemory": "📋 RAM: {{ .Current }}/{{ .Total }}\r\n",
"tcpCount": "🔹 TCP: {{ .Count }}\r\n",
"udpCount": "🔸 UDP: {{ .Count }}\r\n",
"traffic": "🚦 Lalu Lintas: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n",
"xrayStatus": "ℹ️ Status: {{ .State }}\r\n",
"username": "👤 Nama Pengguna: {{ .Username }}\r\n",
"reason": "❗️ Alasan: {{ .Reason }}\r\n",
"time": "⏰ Waktu: {{ .Time }}\r\n",
"inbound": "📍 Inbound: {{ .Remark }}\r\n",
"port": "🔌 Port: {{ .Port }}\r\n",
"expire": "📅 Tanggal Kadaluarsa: {{ .Time }}\r\n",
"expireIn": "📅 Kadaluarsa Dalam: {{ .Time }}\r\n",
"active": "💡 Aktif: {{ .Enable }}\r\n",
"enabled": "🚨 Diaktifkan: {{ .Enable }}\r\n",
"online": "🌐 Status Koneksi: {{ .Status }}\r\n",
"lastOnline": "🔙 Terakhir online: {{ .Time }}\r\n",
"email": "📧 Email: {{ .Email }}\r\n",
"upload": "🔼 Unggah: ↑{{ .Upload }}\r\n",
"download": "🔽 Unduh: ↓{{ .Download }}\r\n",
"total": "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
"TGUser": "👤 Pengguna Telegram: {{ .TelegramID }}\r\n",
"exhaustedCount": "🚨 Jumlah Habis {{ .Type }}:\r\n",
"onlinesCount": "🌐 Klien Online: {{ .Count }}\r\n",
"disabled": "🛑 Dinonaktifkan: {{ .Disabled }}\r\n",
"depleteSoon": "🔜 Habis Sebentar: {{ .Deplete }}\r\n\r\n",
"backupTime": "🗄 Waktu Backup: {{ .Time }}\r\n",
"refreshedOn": "\r\n📋🔄 Diperbarui Pada: {{ .Time }}\r\n\r\n",
"yes": "✅ Ya",
"no": "❌ Tidak",
"received_email": "📧📥 Email diperbarui.",
"received_comment": "💬📥 Komentar diperbarui.",
"email_prompt": "📧 Email Default: {{ .ClientEmail }}\n\nMasukkan email Anda.",
"comment_prompt": "💬 Komentar Default: {{ .ClientComment }}\n\nMasukkan komentar Anda.",
"cancel": "❌ Proses Dibatalkan! \n\nAnda dapat /start lagi kapan saja. 🔄",
"error_add_client": "⚠️ Error:\n\n {{ .error }}",
"using_default_value": "Oke, saya akan tetap menggunakan nilai default. 😊",
"incorrect_input": "Masukan Anda tidak valid.\nFrasa harus berlanjut tanpa spasi.\nContoh benar: aaaaaa\nContoh salah: aaa aaa 🚫",
"AreYouSure": "Apakah kamu yakin? 🤔",
"SuccessResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Hasil: ✅ Berhasil",
"FailedResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Hasil: ❌ Gagal \n\n🛠️ Kesalahan: [ {{ .ErrorMessage }} ]",
"FinishProcess": "🔚 Proses reset traffic selesai untuk semua klien.",
"eventOutboundDown": "Outbound {{ .Tag }} MATI",
"eventOutboundUp": "Outbound {{ .Tag }} AKTIF",
"eventErrorDetail": "Kesalahan: {{ .Error }}",
"eventDelayDetail": "Penundaan: {{ .Delay }}ms",
"eventXrayCrash": "Xray CRASH",
"eventXrayCrashError": "Kesalahan: {{ .Error }}",
"eventNodeDown": "Node {{ .Name }} MATI",
"eventNodeUp": "Node {{ .Name }} AKTIF",
"eventLoginFallback": "Gagal masuk dari {{ .Source }}",
"memoryThreshold": "Penggunaan memori {{ .Percent }}% melebihi ambang batas {{ .Threshold }}%"
},
"buttons": {
"closeKeyboard": "❌ Tutup Papan Ketik",
"cancel": "❌ Batal",
"cancelReset": "❌ Batal Reset",
"cancelIpLimit": "❌ Batal Batas IP",
"confirmResetTraffic": "✅ Konfirmasi Reset Lalu Lintas?",
"confirmClearIps": "✅ Konfirmasi Hapus IPs?",
"confirmRemoveTGUser": "✅ Konfirmasi Hapus Pengguna Telegram?",
"confirmToggle": "✅ Konfirmasi Aktifkan/Nonaktifkan Pengguna?",
"dbBackup": "Dapatkan Cadangan DB",
"serverUsage": "Penggunaan Server",
"getInbounds": "Dapatkan Inbounds",
"depleteSoon": "Habis Sebentar",
"clientUsage": "Dapatkan Penggunaan",
"onlines": "Klien Online",
"commands": "Perintah",
"refresh": "🔄 Perbarui",
"clearIPs": "❌ Hapus IPs",
"removeTGUser": "❌ Hapus Pengguna Telegram",
"selectTGUser": "👤 Pilih Pengguna Telegram",
"selectOneTGUser": "👤 Pilih Pengguna Telegram:",
"resetTraffic": "📈 Reset Lalu Lintas",
"resetExpire": "📅 Ubah Tanggal Kadaluarsa",
"ipLog": "🔢 Log IP",
"ipLimit": "🔢 Batas IP",
"setTGUser": "👤 Set Pengguna Telegram",
"toggle": "🔘 Aktifkan / Nonaktifkan",
"custom": "🔢 Kustom",
"confirmNumber": "✅ Konfirmasi: {{ .Num }}",
"confirmNumberAdd": "✅ Konfirmasi menambahkan: {{ .Num }}",
"limitTraffic": "🚧 Batas Lalu Lintas",
"getBanLogs": "Dapatkan Log Pemblokiran",
"allClients": "Semua Klien",
"addClient": "Tambah Klien",
"submitDisable": "Kirim Sebagai Nonaktif ☑️",
"submitEnable": "Kirim Sebagai Aktif ✅",
"use_default": "🏷️ Gunakan Default",
"change_email": "⚙️📧 Email",
"change_comment": "⚙️💬 Komentar",
"ResetAllTraffics": "Reset Semua Lalu Lintas",
"SortedTrafficUsageReport": "Laporan Penggunaan Lalu Lintas yang Terurut"
},
"answers": {
"successfulOperation": "✅ Operasi berhasil!",
"errorOperation": "❗ Kesalahan dalam operasi.",
"getInboundsFailed": "❌ Gagal mendapatkan inbounds.",
"getClientsFailed": "❌ Gagal mendapatkan klien.",
"canceled": "❌ {{ .Email }}: Operasi dibatalkan.",
"clientRefreshSuccess": "✅ {{ .Email }}: Klien diperbarui dengan berhasil.",
"IpRefreshSuccess": "✅ {{ .Email }}: IP diperbarui dengan berhasil.",
"TGIdRefreshSuccess": "✅ {{ .Email }}: Pengguna Telegram Klien diperbarui dengan berhasil.",
"resetTrafficSuccess": "✅ {{ .Email }}: Lalu lintas direset dengan berhasil.",
"setTrafficLimitSuccess": "✅ {{ .Email }}: Batas lalu lintas disimpan dengan berhasil.",
"expireResetSuccess": "✅ {{ .Email }}: Hari kadaluarsa direset dengan berhasil.",
"resetIpSuccess": "✅ {{ .Email }}: Batas IP {{ .Count }} disimpan dengan berhasil.",
"clearIpSuccess": "✅ {{ .Email }}: IP dihapus dengan berhasil.",
"getIpLog": "✅ {{ .Email }}: Dapatkan Log IP.",
"getUserInfo": "✅ {{ .Email }}: Dapatkan Info Pengguna Telegram.",
"removedTGUserSuccess": "✅ {{ .Email }}: Pengguna Telegram dihapus dengan berhasil.",
"enableSuccess": "✅ {{ .Email }}: Diaktifkan dengan berhasil.",
"disableSuccess": "✅ {{ .Email }}: Dinonaktifkan dengan berhasil.",
"askToAddUserId": "Konfigurasi Anda tidak ditemukan!\r\nSilakan minta admin Anda untuk menggunakan ChatID Telegram Anda dalam konfigurasi Anda.\r\n\r\nChatID Pengguna Anda: <code>{{ .TgUserID }}</code>",
"chooseClient": "Pilih Klien untuk Inbound {{ .Inbound }}",
"chooseInbound": "Pilih Inbound"
}
"noIpRecord": "❗ Tidak ada Catatan IP!"
},
"email": {
"labelStatus": "Status",
"labelOutbound": "Outbound",
"labelNode": "Node",
"labelError": "Kesalahan",
"labelDelay": "Penundaan",
"labelUsername": "Nama Pengguna",
"labelIP": "IP",
"labelReason": "Alasan",
"labelSource": "Sumber",
"statusCrashed": "CRASH",
"statusHigh": "TINGGI",
"statusSuccess": "BERHASIL",
"statusFailed": "GAGAL",
"statusDown": "MATI",
"statusUp": "AKTIF"
}
"email": {}
}