Compare commits

...

10 Commits

Author SHA1 Message Date
2dust
f252d1395a up 1.9.19 2024-11-21 20:30:35 +08:00
2dust
2dc0472c69 When creating a new routing rule, add it to the top 2024-11-21 20:24:01 +08:00
hosêyň abāspanā
3e09adc4d1 Improved Luri Bakhtiari Translation (#4003) 2024-11-21 09:26:08 +08:00
phoenix6936
11750b9382 Improved Persian translation (#4001)
* Improved Persian translation

Improved Persian translation

* Improved Persian translation

Improved Persian translation
2024-11-21 09:25:48 +08:00
solokot
30a4c2199a Improved Russian translation (#3997) 2024-11-20 16:00:14 +08:00
2dust
406a9f996e up 1.9.18 2024-11-20 09:40:08 +08:00
Chocolate4U
5373579bd5 Import rulesets from qrcode (#3991)
* Renamed functions to be more semantically accurate

* Import rulesets from qrcode

Add capability to import rulesets from qrcode
fixes and improvements
2024-11-20 09:23:08 +08:00
Tamim Hossain
9b4cc201e7 Add preSharedKey support and fix parsing function #3512 (#3989)
Add support for preSharedKey in WireGuard configurations and fix the parsing function to correctly handle all necessary fields.

Previously, the application did not support the optional preSharedKey parameter in WireGuard config files, forcing users to rely on JSON custom configurations. This update introduces a dedicated field for preSharedKey in the UI, aligning with Xray Core's support and simplifying the setup process for users.

Changes include:
- Added `preSharedKey` field in the WireGuard UI configuration.
- Updated `parseWireguardConfFile` function to correctly parse `PrivateKey`, `PublicKey`, and `preSharedKey`.
- Ensured `preSharedKey` is optional and handled gracefully when absent.
- Updated `toOutbound` method to include `preSharedKey` in the outbound configuration.
- Set `remarks` to the current Unix time during parsing.

Tested with the following configuration:
```[Interface]
Address = 192.168.6.66/32
DNS = 1.1.1.1,8.8.8.8
PrivateKey = eD/6cpJQaEeDH05AMeFyN3KSLLX+7YFR+MYRdgPDQ3Y=
[Peer]
publickey=/HS7r3waPuU7tTBLd2FlBhC+VROpJ5bwh5XXxuOoKFs=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = sg3.vpnjantit.com:1024
```
Resolves #3512
2024-11-20 09:15:11 +08:00
2dust
6f2c96c2b6 Bug fix
https://github.com/2dust/v2rayNG/issues/3988
2024-11-19 20:38:44 +08:00
solokot
1f6104de8b Update Russian translation (#3987) 2024-11-19 19:07:13 +08:00
19 changed files with 208 additions and 94 deletions

View File

@@ -11,8 +11,8 @@ android {
applicationId = "com.v2ray.ang"
minSdk = 21
targetSdk = 35
versionCode = 613
versionName = "1.9.17"
versionCode = 615
versionName = "1.9.19"
multiDexEnabled = true
splits {

View File

@@ -44,6 +44,7 @@ data class ProfileItem(
var spiderX: String? = null,
var secretKey: String? = null,
var preSharedKey: String? = null,
var localAddress: String? = null,
var reserved: String? = null,
var mtu: Int? = null,

View File

@@ -195,6 +195,7 @@ data class V2rayConfig(
data class WireGuardBean(
var publicKey: String = "",
var preSharedKey: String = "",
var endpoint: String = ""
)
}

View File

@@ -22,9 +22,10 @@ object WireguardFmt : FmtBase() {
config.server = uri.idnHost
config.serverPort = uri.port.toString()
config.secretKey = uri.userInfo
config.secretKey = uri.userInfo.orEmpty()
config.localAddress = (queryParam["address"] ?: WIREGUARD_LOCAL_ADDRESS_V4)
config.publicKey = queryParam["publickey"].orEmpty()
config.preSharedKey = queryParam["presharedkey"].orEmpty()
config.mtu = Utils.parseInt(queryParam["mtu"] ?: AppConfig.WIREGUARD_LOCAL_MTU)
config.reserved = (queryParam["reserved"] ?: "0,0,0")
@@ -33,33 +34,75 @@ object WireguardFmt : FmtBase() {
fun parseWireguardConfFile(str: String): ProfileItem? {
val config = ProfileItem.create(EConfigType.WIREGUARD)
val queryParam: MutableMap<String, String> = mutableMapOf()
val interfaceParams: MutableMap<String, String> = mutableMapOf()
val peerParams: MutableMap<String, String> = mutableMapOf()
var currentSection: String? = null
str.lines().forEach { line ->
val trimmedLine = line.trim()
if (trimmedLine.isEmpty() || trimmedLine.startsWith("#")) {
return@forEach
}
when {
trimmedLine.startsWith("[Interface]", ignoreCase = true) -> currentSection = "Interface"
trimmedLine.startsWith("[Peer]", ignoreCase = true) -> currentSection = "Peer"
trimmedLine.isBlank() || trimmedLine.startsWith("#") -> Unit // Skip blank lines or comments
currentSection != null -> {
val (key, value) = trimmedLine.split("=").map { it.trim() }
queryParam[key.lowercase()] = value // Store the key in lowercase for case-insensitivity
else -> {
if (currentSection != null) {
val parts = trimmedLine.split("=", limit = 2).map { it.trim() }
if (parts.size == 2) {
val key = parts[0].lowercase()
val value = parts[1]
when (currentSection) {
"Interface" -> interfaceParams[key] = value
"Peer" -> peerParams[key] = value
}
}
}
}
}
}
config.secretKey = queryParam["privatekey"].orEmpty()
config.localAddress = (queryParam["address"] ?: WIREGUARD_LOCAL_ADDRESS_V4)
config.publicKey = queryParam["publickey"].orEmpty()
config.mtu = Utils.parseInt(queryParam["mtu"] ?: AppConfig.WIREGUARD_LOCAL_MTU)
config.reserved = (queryParam["reserved"] ?: "0,0,0")
config.secretKey = interfaceParams["privatekey"].orEmpty()
config.remarks = System.currentTimeMillis().toString()
config.localAddress = interfaceParams["address"] ?: WIREGUARD_LOCAL_ADDRESS_V4
config.mtu = Utils.parseInt(interfaceParams["mtu"] ?: AppConfig.WIREGUARD_LOCAL_MTU)
config.publicKey = peerParams["publickey"].orEmpty()
config.preSharedKey = peerParams["presharedkey"].orEmpty()
val endpoint = peerParams["endpoint"].orEmpty()
val endpointParts = endpoint.split(":", limit = 2)
if (endpointParts.size == 2) {
config.server = endpointParts[0]
config.serverPort = endpointParts[1]
} else {
config.server = endpoint
config.serverPort = ""
}
config.reserved = peerParams["reserved"] ?: "0,0,0"
return config
}
fun toOutbound(profileItem: ProfileItem): OutboundBean? {
val outboundBean = OutboundBean.create(EConfigType.WIREGUARD)
outboundBean?.settings?.let { wireguard ->
wireguard.secretKey = profileItem.secretKey
wireguard.address = (profileItem.localAddress ?: WIREGUARD_LOCAL_ADDRESS_V4).split(",")
wireguard.peers?.firstOrNull()?.let { peer ->
peer.publicKey = profileItem.publicKey.orEmpty()
peer.preSharedKey = profileItem.preSharedKey.orEmpty()
peer.endpoint = Utils.getIpv6Address(profileItem.server) + ":${profileItem.serverPort}"
}
wireguard.mtu = profileItem.mtu
wireguard.reserved = profileItem.reserved?.split(",")?.map { it.toInt() }
}
return outboundBean
}
fun toUri(config: ProfileItem): String {
val dicQuery = HashMap<String, String>()
@@ -72,24 +115,10 @@ object WireguardFmt : FmtBase() {
if (config.mtu != null) {
dicQuery["mtu"] = config.mtu.toString()
}
if (config.preSharedKey != null) {
dicQuery["presharedkey"] = Utils.removeWhiteSpace(config.preSharedKey).orEmpty()
}
return toUri(config, config.secretKey, dicQuery)
}
fun toOutbound(profileItem: ProfileItem): OutboundBean? {
val outboundBean = OutboundBean.create(EConfigType.WIREGUARD)
outboundBean?.settings?.let { wireguard ->
wireguard.secretKey = profileItem.secretKey
wireguard.address = (profileItem.localAddress ?: WIREGUARD_LOCAL_ADDRESS_V4).split(",")
wireguard.peers?.first()?.publicKey = profileItem.publicKey.orEmpty()
wireguard.peers?.first()?.endpoint = Utils.getIpv6Address(profileItem.server) + ":${profileItem.serverPort}"
wireguard.mtu = profileItem.mtu?.toInt()
wireguard.reserved = profileItem.reserved?.split(",")?.map { it.toInt() }
}
return outboundBean
}
}
}

View File

@@ -43,12 +43,12 @@ object SettingsManager {
}
fun resetRoutingRulesets(context: Context, index: Int) {
fun resetRoutingRulesetsFromPresets(context: Context, index: Int) {
val rulesetList = getPresetRoutingRulesets(context, index) ?: return
resetRoutingRulesetsCommon(rulesetList)
}
fun resetRoutingRulesetsFromClipboard(content: String?): Boolean {
fun resetRoutingRulesets(content: String?): Boolean {
if (content.isNullOrEmpty()) {
return false
}
@@ -95,7 +95,7 @@ object SettingsManager {
if (rulesetList.isNullOrEmpty()) return
if (index < 0 || index >= rulesetList.count()) {
rulesetList.add(ruleset)
rulesetList.add(0, ruleset)
} else {
rulesetList[index] = ruleset
}

View File

@@ -1,15 +1,18 @@
package com.v2ray.ang.ui
import android.Manifest
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.tbruyelle.rxpermissions3.RxPermissions
import com.v2ray.ang.AppConfig
import com.v2ray.ang.R
import com.v2ray.ang.databinding.ActivityRoutingSettingBinding
@@ -83,13 +86,13 @@ class RoutingSettingActivity : BaseActivity() {
true
}
R.id.import_rulesets -> {
R.id.import_predefined_rulesets -> {
AlertDialog.Builder(this).setMessage(R.string.routing_settings_import_rulesets_tip)
.setPositiveButton(android.R.string.ok) { _, _ ->
AlertDialog.Builder(this).setItems(preset_rulesets.asList().toTypedArray()) { _, i ->
try {
lifecycleScope.launch(Dispatchers.IO) {
SettingsManager.resetRoutingRulesets(this@RoutingSettingActivity, i)
SettingsManager.resetRoutingRulesetsFromPresets(this@RoutingSettingActivity, i)
launch(Dispatchers.Main) {
refreshData()
toast(R.string.toast_success)
@@ -120,7 +123,7 @@ class RoutingSettingActivity : BaseActivity() {
return@setPositiveButton
}
lifecycleScope.launch(Dispatchers.IO) {
val result = SettingsManager.resetRoutingRulesetsFromClipboard(clipboard)
val result = SettingsManager.resetRoutingRulesets(clipboard)
withContext(Dispatchers.Main) {
if (result) {
refreshData()
@@ -138,6 +141,18 @@ class RoutingSettingActivity : BaseActivity() {
true
}
R.id.import_rulesets_from_qrcode -> {
RxPermissions(this)
.request(Manifest.permission.CAMERA)
.subscribe {
if (it)
scanQRcodeForRulesets.launch(Intent(this, ScannerActivity::class.java))
else
toast(R.string.toast_permission_denied)
}
true
}
R.id.export_rulesets_to_clipboard -> {
val rulesetList = MmkvManager.decodeRoutingRulesets()
@@ -153,6 +168,34 @@ class RoutingSettingActivity : BaseActivity() {
else -> super.onOptionsItemSelected(item)
}
private val scanQRcodeForRulesets = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == RESULT_OK) {
importRulesetsFromQRcode(it.data?.getStringExtra("SCAN_RESULT"))
}
}
private fun importRulesetsFromQRcode(qrcode: String?): Boolean {
AlertDialog.Builder(this).setMessage(R.string.routing_settings_import_rulesets_tip)
.setPositiveButton(android.R.string.ok) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) {
val result = SettingsManager.resetRoutingRulesets(qrcode)
withContext(Dispatchers.Main) {
if (result) {
refreshData()
toast(R.string.toast_success)
} else {
toast(R.string.toast_failure)
}
}
}
}
.setNegativeButton(android.R.string.no) { _, _ ->
//do nothing
}
.show()
return true
}
fun refreshData() {
rulesets.clear()
rulesets.addAll(MmkvManager.decodeRoutingRulesets() ?: mutableListOf())

View File

@@ -26,6 +26,7 @@ import com.v2ray.ang.R
import com.v2ray.ang.dto.EConfigType
import com.v2ray.ang.dto.NetworkType
import com.v2ray.ang.dto.ProfileItem
import com.v2ray.ang.extension.isNotNullEmpty
import com.v2ray.ang.extension.toast
import com.v2ray.ang.handler.MmkvManager
import com.v2ray.ang.util.JsonUtil
@@ -112,6 +113,7 @@ class ServerActivity : BaseActivity() {
private val sp_stream_alpn: Spinner? by lazy { findViewById(R.id.sp_stream_alpn) } //uTLS
private val container_alpn: LinearLayout? by lazy { findViewById(R.id.lay_stream_alpn) }
private val et_public_key: EditText? by lazy { findViewById(R.id.et_public_key) }
private val et_preshared_key: EditText? by lazy { findViewById(R.id.et_preshared_key) }
private val container_public_key: LinearLayout? by lazy { findViewById(R.id.lay_public_key) }
private val et_short_id: EditText? by lazy { findViewById(R.id.et_short_id) }
private val container_short_id: LinearLayout? by lazy { findViewById(R.id.lay_short_id) }
@@ -149,7 +151,7 @@ class ServerActivity : BaseActivity() {
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
id: Long,
) {
val types = transportTypes(networks[position])
sp_header_type?.isEnabled = types.size > 1
@@ -168,7 +170,7 @@ class ServerActivity : BaseActivity() {
types,
when (networks[position]) {
NetworkType.GRPC.type -> config?.mode
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> config?.xhttpMode
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> config?.xhttpMode
else -> config?.headerType
}.orEmpty()
)
@@ -221,7 +223,7 @@ class ServerActivity : BaseActivity() {
)
et_extra?.text = Utils.getEditable(
when (networks[position]) {
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> JsonUtil.toJsonPretty(JsonUtil.parseString(config?.xhttpExtra))
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> config?.xhttpExtra
else -> null
}.orEmpty()
)
@@ -242,7 +244,7 @@ class ServerActivity : BaseActivity() {
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
id: Long,
) {
val isBlank = streamSecuritys[position].isBlank()
val isTLS = streamSecuritys[position] == TLS
@@ -320,29 +322,21 @@ class ServerActivity : BaseActivity() {
} else if (config.configType == EConfigType.WIREGUARD) {
et_id.text = Utils.getEditable(config.secretKey.orEmpty())
et_public_key?.text = Utils.getEditable(config.publicKey.orEmpty())
if (config.reserved == null) {
et_reserved1?.text = Utils.getEditable("0,0,0")
} else {
et_reserved1?.text = Utils.getEditable(config.reserved?.toString())
}
if (config.localAddress == null) {
et_local_address?.text = Utils.getEditable("${WIREGUARD_LOCAL_ADDRESS_V4},${WIREGUARD_LOCAL_ADDRESS_V6}")
} else {
et_local_address?.text = Utils.getEditable(config.localAddress)
}
if (config.mtu == null) {
et_local_mtu?.text = Utils.getEditable(WIREGUARD_LOCAL_MTU)
} else {
et_local_mtu?.text = Utils.getEditable(config.mtu.toString())
}
et_preshared_key?.visibility = View.VISIBLE
et_preshared_key?.text = Utils.getEditable(config.preSharedKey.orEmpty())
et_reserved1?.text = Utils.getEditable(config.reserved ?: "0,0,0")
et_local_address?.text = Utils.getEditable(
config.localAddress ?: "$WIREGUARD_LOCAL_ADDRESS_V4,$WIREGUARD_LOCAL_ADDRESS_V6"
)
et_local_mtu?.text = Utils.getEditable(config.mtu?.toString() ?: WIREGUARD_LOCAL_MTU)
} else if (config.configType == EConfigType.HYSTERIA2) {
et_obfs_password?.text = Utils.getEditable(config.obfsPassword)
et_port_hop?.text = Utils.getEditable(config.portHopping)
et_port_hop_interval?.text = Utils.getEditable(config.portHoppingInterval)
et_pinsha256?.text = Utils.getEditable(config.pinSHA256)
}
val securityEncryptions = if (config.configType == EConfigType.SHADOWSOCKS) shadowsocksSecuritys else securitys
val securityEncryptions =
if (config.configType == EConfigType.SHADOWSOCKS) shadowsocksSecuritys else securitys
val security = Utils.arrayFind(securityEncryptions, config.method.orEmpty())
if (security >= 0) {
sp_security?.setSelection(security)
@@ -373,7 +367,7 @@ class ServerActivity : BaseActivity() {
container_public_key?.visibility = View.GONE
container_short_id?.visibility = View.GONE
container_spider_x?.visibility = View.GONE
} else if (config.security == REALITY) { // reality settings
} else if (config.security == REALITY) {
container_public_key?.visibility = View.VISIBLE
et_public_key?.text = Utils.getEditable(config.publicKey.orEmpty())
container_short_id?.visibility = View.VISIBLE
@@ -393,7 +387,6 @@ class ServerActivity : BaseActivity() {
container_short_id?.visibility = View.GONE
container_spider_x?.visibility = View.GONE
}
val network = Utils.arrayFind(networks, config.network.orEmpty())
if (network >= 0) {
sp_network?.setSelection(network)
@@ -447,7 +440,8 @@ class ServerActivity : BaseActivity() {
return false
}
}
val config = MmkvManager.decodeServerConfig(editGuid) ?: ProfileItem.create(createConfigType)
val config =
MmkvManager.decodeServerConfig(editGuid) ?: ProfileItem.create(createConfigType)
if (config.configType != EConfigType.SOCKS
&& config.configType != EConfigType.HTTP
&& TextUtils.isEmpty(et_id.text.toString())
@@ -468,6 +462,12 @@ class ServerActivity : BaseActivity() {
return false
}
}
if (et_extra?.text?.toString().isNotNullEmpty()) {
if (JsonUtil.parseString(et_extra?.text?.toString()) == null) {
toast(R.string.server_lab_xhttp_extra)
return false
}
}
saveCommon(config)
saveStreamSettings(config)
@@ -504,6 +504,7 @@ class ServerActivity : BaseActivity() {
} else if (config.configType == EConfigType.WIREGUARD) {
config.secretKey = et_id.text.toString().trim()
config.publicKey = et_public_key?.text.toString().trim()
config.preSharedKey = et_preshared_key?.text.toString().trim()
config.reserved = et_reserved1?.text.toString().trim()
config.localAddress = et_local_address?.text.toString().trim()
config.mtu = Utils.parseInt(et_local_mtu?.text.toString())
@@ -548,7 +549,7 @@ class ServerActivity : BaseActivity() {
val allowInsecure =
if (allowInsecureField == null || allowinsecures[allowInsecureField].isBlank()) {
MmkvManager.decodeSettingsBool(PREF_ALLOW_INSECURE) == true
MmkvManager.decodeSettingsBool(PREF_ALLOW_INSECURE)
} else {
allowinsecures[allowInsecureField].toBoolean()
}
@@ -577,7 +578,7 @@ class ServerActivity : BaseActivity() {
grpcModes
}
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> {
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> {
xhttpMode
}

View File

@@ -42,7 +42,11 @@ object JsonUtil {
fun parseString(src: String?): JsonObject? {
if (src == null)
return null
return JsonParser.parseString(src).getAsJsonObject()
try {
return JsonParser.parseString(src).getAsJsonObject()
} catch (e: Exception) {
e.printStackTrace()
return null
}
}
}

View File

@@ -51,6 +51,25 @@
android:layout_height="@dimen/edit_height"
android:inputType="text" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_margin_top_height"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/server_lab_preshared_key" />
<EditText
android:id="@+id/et_preshared_key"
android:layout_width="match_parent"
android:layout_height="@dimen/edit_height"
android:inputType="text" />
</LinearLayout>
<LinearLayout

View File

@@ -11,13 +11,17 @@
android:icon="@drawable/ic_file_24dp"
android:title="@string/title_user_asset_setting" />
<item
android:id="@+id/import_rulesets"
android:title="@string/routing_settings_import_rulesets"
android:id="@+id/import_predefined_rulesets"
android:title="@string/routing_settings_import_predefined_rulesets"
app:showAsAction="never" />
<item
android:id="@+id/import_rulesets_from_clipboard"
android:title="@string/routing_settings_import_rulesets_from_clipboard"
app:showAsAction="never" />
<item
android:id="@+id/import_rulesets_from_qrcode"
android:title="@string/routing_settings_import_rulesets_from_qrcode"
app:showAsAction="never" />
<item
android:id="@+id/export_rulesets_to_clipboard"
android:title="@string/routing_settings_export_rulesets_to_clipboard"

View File

@@ -267,9 +267,10 @@
<string name="routing_settings_delete">مسح</string>
<string name="routing_settings_rule_title">Routing Rule Settings</string>
<string name="routing_settings_add_rule">Add rule</string>
<string name="routing_settings_import_rulesets">Import ruleset</string>
<string name="routing_settings_import_predefined_rulesets">استيراد مجموعات قواعد محددة مسبقاً</string>
<string name="routing_settings_import_rulesets_tip">Existing rulesets will be deleted, are you sure to continue?</string>
<string name="routing_settings_import_rulesets_from_clipboard">Import ruleset from clipboard</string>
<string name="routing_settings_import_rulesets_from_qrcode">استيراد مجموعة قواعد من رمز الاستجابة السريعة</string>
<string name="routing_settings_export_rulesets_to_clipboard">Export ruleset to clipboard</string>
<string name="routing_settings_locked">Locked, keep this rule when import presets</string>

View File

@@ -265,9 +265,10 @@
<string name="routing_settings_delete">মুছে ফেলুন</string>
<string name="routing_settings_rule_title">Routing Rule Settings</string>
<string name="routing_settings_add_rule">Add rule</string>
<string name="routing_settings_import_rulesets">Import ruleset</string>
<string name="routing_settings_import_predefined_rulesets">পূর্বনির্ধারিত নিয়মাবলী আমদানি করুন</string>
<string name="routing_settings_import_rulesets_tip">Existing rulesets will be deleted, are you sure to continue?</string>
<string name="routing_settings_import_rulesets_from_clipboard">Import ruleset from clipboard</string>
<string name="routing_settings_import_rulesets_from_qrcode">QRcode থেকে রুলসেট আমদানি করুন</string>
<string name="routing_settings_export_rulesets_to_clipboard">Export ruleset to clipboard</string>
<string name="routing_settings_locked">Locked, keep this rule when import presets</string>

View File

@@ -80,12 +80,12 @@
<string name="server_lab_security4">نوم من توری (اختیاری)</string>
<string name="server_lab_encryption">رزم نگاری</string>
<string name="server_lab_flow">جریان</string>
<string name="server_lab_public_key">PublicKey</string>
<string name="server_lab_public_key">کیلیت پوی وولاتی</string>
<string name="server_lab_short_id">ShortId</string>
<string name="server_lab_spider_x">SpiderX</string>
<string name="server_lab_secret_key">SecretKey</string>
<string name="server_lab_reserved">Reserved(اختیاری, وا کاما ز یک جوڌا ابۊن)</string>
<string name="server_lab_local_address">آدرس مهلی (اختیاری IPv4/IPv6, وا کاما ز یک جوڌا ابۊن)</string>
<string name="server_lab_secret_key">کیلیت سیخومی</string>
<string name="server_lab_reserved">Reserved(اختیاری، وا کاما ز یک جوڌا ابۊن)</string>
<string name="server_lab_local_address">آدرس مهلی (اختیاری IPv4/IPv6، وا کاما ز یک جوڌا ابۊن)</string>
<string name="server_lab_local_mtu">Mtu(اختیاری، خوتکار 1420)</string>
<string name="toast_success">وا مووفقیت ٱنجوم وابی</string>
<string name="toast_failure">شکست خرد</string>
@@ -217,8 +217,8 @@
<string name="title_configuration_restore">وورگندن کانفیگ</string>
<string name="title_configuration_share">یک رسۊوی کانفیگ</string>
<string name="title_pref_promotion">تبلیغات</string>
<string name="summary_pref_promotion">تبلیغات، سی نیشتن جوزیات بیشتر کیلیک کۊنین. (هیاری مالی کۊنین تا پاک بۊ)</string>
<string name="title_pref_promotion">تبلیقات</string>
<string name="summary_pref_promotion">تبلیقات، سی نیشتن جوزیات بیشتر کیلیک کۊنین. (هیاری مالی کۊنین تا پاک بۊ)</string>
<string name="title_pref_auto_update_subscription">ورۊ کردن خوتکار اشتراکا</string>
<string name="summary_pref_auto_update_subscription">اشتراکا خوتۉ ن و تۉر خوتکار وا فاسله زمۊوی من پس زمینه ورۊ کۊنین. ای ویژیی من پوی دسگایل گاشڌ همیشه کار نکونه</string>
@@ -262,14 +262,15 @@
<string name="routing_settings_domain_strategy">نشقه دامنه</string>
<string name="routing_settings_title">سامووا تور جوستن</string>
<string name="routing_settings_tips">وا کاما ز یک جوڌا ابۊن (,) پسند دامنه یا آی پی</string>
<string name="routing_settings_tips">وا کاما ز یک جوڌا ابۊن (،) پسند دامنه یا آی پی</string>
<string name="routing_settings_save">زفت کردن</string>
<string name="routing_settings_delete">روفتن</string>
<string name="routing_settings_rule_title">سامووا قانۉݩ تور جوستن</string>
<string name="routing_settings_add_rule">ازاف کردن قانۉݩ</string>
<string name="routing_settings_import_rulesets">و من ٱووردن قانووا</string>
<string name="routing_settings_import_predefined_rulesets">و من ٱووردن قانووا</string>
<string name="routing_settings_import_rulesets_tip">قانووایی ک هیم سکو هڌسۉݩ پاک ابۊن، هنی هم اخۊی پاکسۉݩ کۊنی؟</string>
<string name="routing_settings_import_rulesets_from_clipboard">و من ٱووردن قانووا ز کلیپ بورد</string>
<string name="routing_settings_import_rulesets_from_qrcode">و من ٱووردن قانووا ز QRcode</string>
<string name="routing_settings_export_rulesets_to_clipboard">و در کشیڌن قانووا وو زفت من کلیپ بورد</string>
<string name="routing_settings_locked">چفت هڌ، ای قانؤنن مجال و من ٱووردن ز پؽش سامووا زفت کۊنین</string>
<string name="routing_settings_domain" translatable="false">domain</string>

View File

@@ -79,10 +79,11 @@
<string name="server_lab_security4">نام‌ کاربری (اختیاری)</string>
<string name="server_lab_encryption">رمزنگاری</string>
<string name="server_lab_flow">جریان</string>
<string name="server_lab_public_key">PublicKey</string>
<string name="server_lab_public_key">کلید عمومی</string>
<string name="server_lab_preshared_key">کلید رمزگذاری اضافی (اختیاری)</string>
<string name="server_lab_short_id">ShortId</string>
<string name="server_lab_spider_x">SpiderX</string>
<string name="server_lab_secret_key">SecretKey</string>
<string name="server_lab_secret_key">کلید خصوصی</string>
<string name="server_lab_reserved">Reserved (اختیاری)</string>
<string name="server_lab_local_address">آدرس محلی IPv4(اختیاری)</string>
<string name="server_lab_local_mtu">Mtu(optional, default 1420)</string>
@@ -96,7 +97,7 @@
<string name="server_customize_config">کانفیگ سفارشی</string>
<string name="toast_config_file_invalid">کانفیگ معتبر نیست</string>
<string name="server_lab_content">محتوا</string>
<string name="toast_none_data_clipboard">هیچ داده‌ای در کلیپ ‌بورد وجود ندارد</string>
<string name="toast_none_data_clipboard">هیچ داده‌ ای در کلیپ ‌بورد وجود ندارد</string>
<string name="toast_invalid_url">نشانی اینترنتی معتبر نیست</string>
<string name="toast_insecure_url_protocol">لطفاً از آدرس اشتراک پروتکل HTTP ناامن استفاده نکنید</string>
<string name="server_lab_need_inbound">اطمینان حاصل کنید که پورت ورودی با تنظیمات مطابقت دارد</string>
@@ -263,9 +264,10 @@
<string name="routing_settings_delete">حذف</string>
<string name="routing_settings_rule_title">تنظیمات قانون مسیریابی</string>
<string name="routing_settings_add_rule">اضافه کردن قانون</string>
<string name="routing_settings_import_rulesets">وارد کردن مجموعه قوانین</string>
<string name="routing_settings_import_predefined_rulesets">وارد کردن مجموعه قوانین از پیش تعریف شده</string>
<string name="routing_settings_import_rulesets_tip">مجموعه قوانین موجود حذف خواهند شد، آیا مطمئن هستید که ادامه می دهید؟</string>
<string name="routing_settings_import_rulesets_from_clipboard">وارد کردن مجموعه قوانین از کلیپ بورد</string>
<string name="routing_settings_import_rulesets_from_qrcode">وارد کردن مجموعه قوانین از QRcode</string>
<string name="routing_settings_export_rulesets_to_clipboard">صادر کردن مجموعه قوانین به کلیپ بورد</string>
<string name="routing_settings_locked">قفل است، این قانون را هنگام وارد کردن از پیش تنظیم‌ها حفظ کنید</string>

View File

@@ -54,14 +54,14 @@
<string name="server_lab_request_host_http">Узел HTTP</string>
<string name="server_lab_request_host_ws">Узел WS</string>
<string name="server_lab_request_host_httpupgrade">Узел HTTPUpgrade</string>
<string name="server_lab_request_host_xhttp">Узел SplitHTTP</string>
<string name="server_lab_request_host_xhttp">Узел XHTTP</string>
<string name="server_lab_request_host_h2">Узел H2</string>
<string name="server_lab_request_host_quic">Шифрование QUIC</string>
<string name="server_lab_request_host_grpc">Полномочия gRPC</string>
<string name="server_lab_path">Путь</string>
<string name="server_lab_path_ws">Путь WS</string>
<string name="server_lab_path_httpupgrade">Путь HTTPUpgrade</string>
<string name="server_lab_path_xhttp">Путь SplitHTTP</string>
<string name="server_lab_path_xhttp">Путь XHTTP</string>
<string name="server_lab_path_h2">Путь H2</string>
<string name="server_lab_path_quic">Ключ QUIC</string>
<string name="server_lab_path_kcp">Сид KCP</string>
@@ -80,10 +80,11 @@
<string name="server_lab_encryption">Шифрование</string>
<string name="server_lab_flow">Поток</string>
<string name="server_lab_public_key">Открытый ключ</string>
<string name="server_lab_preshared_key">Дополнительный ключ шифрования (необязательно)</string>
<string name="server_lab_short_id">ShortID</string>
<string name="server_lab_spider_x">SpiderX</string>
<string name="server_lab_secret_key">Закрытый ключ</string>
<string name="server_lab_reserved">Reserved (необязательно)</string>
<string name="server_lab_reserved">Reserved (необязательно, через запятую)</string>
<string name="server_lab_local_address">Локальный адрес (необязательно, IPv4/IPv6 через запятую)</string>
<string name="server_lab_local_mtu">MTU (необязательно, по умолчанию 1420)</string>
<string name="toast_success">Успешно</string>
@@ -106,7 +107,7 @@
<string name="menu_item_add_asset">Добавить ресурс</string>
<string name="menu_item_add_file">Добавить файлы</string>
<string name="menu_item_add_url">Добавить URL</string>
<string name="menu_item_scan_qrcode">Сканирование QR-кода</string>
<string name="menu_item_scan_qrcode">Сканировать QR-код</string>
<string name="title_url">URL</string>
<string name="menu_item_download_file">Загрузить файлы</string>
<string name="title_user_asset_add_url">Добавить URL ресурса</string>
@@ -114,11 +115,11 @@
<string name="msg_remark_is_duplicate">Название уже существует</string>
<string name="toast_action_not_allowed">Это действие запрещено</string>
<string name="server_obfs_password">Пароль obfs</string>
<string name="server_lab_port_hop">Переключение портов</string>
<string name="server_lab_port_hop_interval">Интервал переключения портов</string>
<string name="server_lab_port_hop">Смена портов (переопределяет порт)</string>
<string name="server_lab_port_hop_interval">Интервал смены портов</string>
<string name="server_lab_stream_pinsha256">pinSHA256</string>
<string name="server_lab_xhttp_mode">XHTTP Mode</string>
<string name="server_lab_xhttp_extra">XHTTP Extra raw JSON, format: { XHTTPObject }</string>
<string name="server_lab_xhttp_mode">Режим XHTTP</string>
<string name="server_lab_xhttp_extra">Необработанный JSON XHTTP Extra, формат: { XHTTPObject }</string>
<!-- PerAppProxyActivity -->
<string name="msg_dialog_progress">Загрузка…</string>
@@ -266,9 +267,10 @@
<string name="routing_settings_delete">Очистить</string>
<string name="routing_settings_rule_title">Настройка правил маршрутизации</string>
<string name="routing_settings_add_rule">Добавить правило</string>
<string name="routing_settings_import_rulesets">Импорт правил</string>
<string name="routing_settings_import_predefined_rulesets">Импорт набора правил</string>
<string name="routing_settings_import_rulesets_tip">Существующие правила будут удалены. Продолжить?</string>
<string name="routing_settings_import_rulesets_from_clipboard">Импорт правил из буфера обмена</string>
<string name="routing_settings_import_rulesets_from_qrcode">Импорт правил из QR-кода</string>
<string name="routing_settings_export_rulesets_to_clipboard">Экспорт правил в буфер обмена</string>
<string name="routing_settings_locked">Постоянное (сохранится при импорте правил)</string>
<string name="routing_settings_domain">Домен</string>

View File

@@ -266,9 +266,10 @@
<string name="routing_settings_delete">Xoá</string>
<string name="routing_settings_rule_title">Routing Rule Settings</string>
<string name="routing_settings_add_rule">Add rule</string>
<string name="routing_settings_import_rulesets">Import ruleset</string>
<string name="routing_settings_import_predefined_rulesets">Nhập các bộ quy tắc được xác định trước</string>
<string name="routing_settings_import_rulesets_tip">Existing rulesets will be deleted, are you sure to continue?</string>
<string name="routing_settings_import_rulesets_from_clipboard">Import ruleset from clipboard</string>
<string name="routing_settings_import_rulesets_from_qrcode">Nhập bộ quy tắc từ QRcode</string>
<string name="routing_settings_export_rulesets_to_clipboard">Export ruleset to clipboard</string>
<string name="routing_settings_locked">Locked, keep this rule when import presets</string>

View File

@@ -263,9 +263,10 @@
<string name="routing_settings_delete">清空</string>
<string name="routing_settings_rule_title">路由规则设置</string>
<string name="routing_settings_add_rule">添加规则</string>
<string name="routing_settings_import_rulesets">导入预规则集</string>
<string name="routing_settings_import_predefined_rulesets">导入预定义规则集</string>
<string name="routing_settings_import_rulesets_tip">将删除现有的规则集,是否确定继续?</string>
<string name="routing_settings_import_rulesets_from_clipboard">从剪贴板导入规则集</string>
<string name="routing_settings_import_rulesets_from_qrcode">从 QRcode 导入规则集</string>
<string name="routing_settings_export_rulesets_to_clipboard">导出规则集至剪贴板</string>
<string name="routing_settings_locked">锁定中,导入预设时不删除此规则</string>

View File

@@ -265,9 +265,10 @@
<string name="routing_settings_delete">清除</string>
<string name="routing_settings_rule_title">路由規則設定</string>
<string name="routing_settings_add_rule">新增規則</string>
<string name="routing_settings_import_rulesets">匯入預規則集</string>
<string name="routing_settings_import_predefined_rulesets">匯入預先定義的規則集</string>
<string name="routing_settings_import_rulesets_tip">將刪除現有的規則集,是否確定繼續? </string>
<string name="routing_settings_import_rulesets_from_clipboard">從剪貼簿匯入規則集</string>
<string name="routing_settings_import_rulesets_from_qrcode">從 QRcode 匯入規則集</string>
<string name="routing_settings_export_rulesets_to_clipboard">匯出規則集至剪貼簿</string>
<string name="routing_settings_locked">鎖定中,匯入預設時不刪除此規則</string>

View File

@@ -81,6 +81,7 @@
<string name="server_lab_encryption">encryption</string>
<string name="server_lab_flow">flow</string>
<string name="server_lab_public_key">PublicKey</string>
<string name="server_lab_preshared_key">PreSharedKey(optional)</string>
<string name="server_lab_short_id">ShortId</string>
<string name="server_lab_spider_x">SpiderX</string>
<string name="server_lab_secret_key">SecretKey</string>
@@ -269,9 +270,10 @@
<string name="routing_settings_delete">Clear</string>
<string name="routing_settings_rule_title">Routing Rule Settings</string>
<string name="routing_settings_add_rule">Add rule</string>
<string name="routing_settings_import_rulesets">Import ruleset</string>
<string name="routing_settings_import_predefined_rulesets">Import predefined rulesets</string>
<string name="routing_settings_import_rulesets_tip">Existing rulesets will be deleted, are you sure to continue?</string>
<string name="routing_settings_import_rulesets_from_clipboard">Import ruleset from clipboard</string>
<string name="routing_settings_import_rulesets_from_qrcode">Import ruleset from QRcode</string>
<string name="routing_settings_export_rulesets_to_clipboard">Export ruleset to clipboard</string>
<string name="routing_settings_locked">Locked, keep this rule when import presets</string>
<string name="routing_settings_domain" translatable="false">domain</string>