Add Enable New TUN Feature option
When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks
This commit is contained in:
BIN
V2rayNG/app/libs/arm64-v8a/libhev-socks5-tunnel.so
Normal file
BIN
V2rayNG/app/libs/arm64-v8a/libhev-socks5-tunnel.so
Normal file
Binary file not shown.
BIN
V2rayNG/app/libs/armeabi-v7a/libhev-socks5-tunnel.so
Normal file
BIN
V2rayNG/app/libs/armeabi-v7a/libhev-socks5-tunnel.so
Normal file
Binary file not shown.
BIN
V2rayNG/app/libs/x86/libhev-socks5-tunnel.so
Normal file
BIN
V2rayNG/app/libs/x86/libhev-socks5-tunnel.so
Normal file
Binary file not shown.
BIN
V2rayNG/app/libs/x86_64/libhev-socks5-tunnel.so
Normal file
BIN
V2rayNG/app/libs/x86_64/libhev-socks5-tunnel.so
Normal file
Binary file not shown.
@@ -62,6 +62,7 @@ object AppConfig {
|
|||||||
const val PREF_IS_BOOTED = "pref_is_booted"
|
const val PREF_IS_BOOTED = "pref_is_booted"
|
||||||
const val PREF_CHECK_UPDATE_PRE_RELEASE = "pref_check_update_pre_release"
|
const val PREF_CHECK_UPDATE_PRE_RELEASE = "pref_check_update_pre_release"
|
||||||
const val PREF_GEO_FILES_SOURCES = "pref_geo_files_sources"
|
const val PREF_GEO_FILES_SOURCES = "pref_geo_files_sources"
|
||||||
|
const val PREF_USE_HEV_TUNNEL = "pref_use_hev_tunnel"
|
||||||
|
|
||||||
/** Cache keys. */
|
/** Cache keys. */
|
||||||
const val CACHE_SUBSCRIPTION_ID = "cache_subscription_id"
|
const val CACHE_SUBSCRIPTION_ID = "cache_subscription_id"
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package com.v2ray.ang.service
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.ParcelFileDescriptor
|
||||||
|
import android.util.Log
|
||||||
|
import com.v2ray.ang.AppConfig
|
||||||
|
import com.v2ray.ang.AppConfig.VPN_MTU
|
||||||
|
import com.v2ray.ang.handler.MmkvManager
|
||||||
|
import com.v2ray.ang.handler.SettingsManager
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the tun2socks process that handles VPN traffic
|
||||||
|
*/
|
||||||
|
class TProxyService(
|
||||||
|
private val context: Context,
|
||||||
|
private val vpnInterface: ParcelFileDescriptor,
|
||||||
|
private val isRunningProvider: () -> Boolean,
|
||||||
|
private val restartCallback: () -> Unit
|
||||||
|
) : Tun2SocksControl {
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
private external fun TProxyStartService(configPath: String, fd: Int)
|
||||||
|
@JvmStatic
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
private external fun TProxyStopService()
|
||||||
|
@JvmStatic
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
private external fun TProxyGetStats(): LongArray?
|
||||||
|
|
||||||
|
init {
|
||||||
|
System.loadLibrary("hev-socks5-tunnel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the tun2socks process with the appropriate parameters.
|
||||||
|
*/
|
||||||
|
override fun startTun2Socks() {
|
||||||
|
Log.i(AppConfig.TAG, "Starting HevSocks5Tunnel via JNI")
|
||||||
|
|
||||||
|
val configContent = buildConfig()
|
||||||
|
val configFile = File(context.filesDir, "hev-socks5-tunnel.yaml").apply {
|
||||||
|
writeText(configContent)
|
||||||
|
}
|
||||||
|
Log.i(AppConfig.TAG, "Config file created: ${configFile.absolutePath}")
|
||||||
|
Log.d(AppConfig.TAG, "Config content:\n$configContent")
|
||||||
|
|
||||||
|
try {
|
||||||
|
Log.i(AppConfig.TAG, "TProxyStartService...")
|
||||||
|
TProxyStartService(configFile.absolutePath, vpnInterface.fd)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(AppConfig.TAG, "HevSocks5Tunnel exception: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildConfig(): String {
|
||||||
|
val socksPort = SettingsManager.getSocksPort()
|
||||||
|
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
|
||||||
|
return buildString {
|
||||||
|
appendLine("tunnel:")
|
||||||
|
appendLine(" mtu: $VPN_MTU")
|
||||||
|
appendLine(" ipv4: ${vpnConfig.ipv4Client}")
|
||||||
|
|
||||||
|
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6) == true) {
|
||||||
|
appendLine(" ipv6: '${vpnConfig.ipv6Client}'")
|
||||||
|
}
|
||||||
|
|
||||||
|
appendLine("socks5:")
|
||||||
|
appendLine(" port: ${socksPort}")
|
||||||
|
appendLine(" address: ${AppConfig.LOOPBACK}")
|
||||||
|
appendLine(" udp: 'udp'")
|
||||||
|
|
||||||
|
MmkvManager.decodeSettingsString(AppConfig.PREF_LOGLEVEL)?.let { logPref ->
|
||||||
|
if (logPref != "none") {
|
||||||
|
val logLevel = if (logPref == "warning") "warn" else logPref
|
||||||
|
appendLine("misc:")
|
||||||
|
appendLine(" log-level: $logLevel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the tun2socks process
|
||||||
|
*/
|
||||||
|
override fun stopTun2Socks() {
|
||||||
|
try {
|
||||||
|
Log.i(AppConfig.TAG, "TProxyStopService...")
|
||||||
|
TProxyStopService()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(AppConfig.TAG, "Failed to stop hev-socks5-tunnel", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.v2ray.ang.service
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface that defines the control operations for tun2socks implementations.
|
||||||
|
*
|
||||||
|
* This interface is implemented by different tunnel solutions like:
|
||||||
|
*/
|
||||||
|
interface Tun2SocksControl {
|
||||||
|
/**
|
||||||
|
* Starts the tun2socks process with the appropriate parameters.
|
||||||
|
* This initializes the VPN tunnel and connects it to the SOCKS proxy.
|
||||||
|
*/
|
||||||
|
fun startTun2Socks()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the tun2socks process and cleans up resources.
|
||||||
|
*/
|
||||||
|
fun stopTun2Socks()
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ class Tun2SocksService(
|
|||||||
private val vpnInterface: ParcelFileDescriptor,
|
private val vpnInterface: ParcelFileDescriptor,
|
||||||
private val isRunningProvider: () -> Boolean,
|
private val isRunningProvider: () -> Boolean,
|
||||||
private val restartCallback: () -> Unit
|
private val restartCallback: () -> Unit
|
||||||
) {
|
) : Tun2SocksControl {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TUN2SOCKS = "libtun2socks.so"
|
private const val TUN2SOCKS = "libtun2socks.so"
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ class Tun2SocksService(
|
|||||||
/**
|
/**
|
||||||
* Starts the tun2socks process with the appropriate parameters.
|
* Starts the tun2socks process with the appropriate parameters.
|
||||||
*/
|
*/
|
||||||
fun startTun2Socks() {
|
override fun startTun2Socks() {
|
||||||
Log.i(AppConfig.TAG, "Start run $TUN2SOCKS")
|
Log.i(AppConfig.TAG, "Start run $TUN2SOCKS")
|
||||||
val socksPort = SettingsManager.getSocksPort()
|
val socksPort = SettingsManager.getSocksPort()
|
||||||
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
|
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
|
||||||
@@ -116,7 +116,7 @@ class Tun2SocksService(
|
|||||||
/**
|
/**
|
||||||
* Stops the tun2socks process
|
* Stops the tun2socks process
|
||||||
*/
|
*/
|
||||||
fun stopTun2Socks() {
|
override fun stopTun2Socks() {
|
||||||
try {
|
try {
|
||||||
Log.i(AppConfig.TAG, "$TUN2SOCKS destroy")
|
Log.i(AppConfig.TAG, "$TUN2SOCKS destroy")
|
||||||
if (::process.isInitialized) {
|
if (::process.isInitialized) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import java.lang.ref.SoftReference
|
|||||||
class V2RayVpnService : VpnService(), ServiceControl {
|
class V2RayVpnService : VpnService(), ServiceControl {
|
||||||
private lateinit var mInterface: ParcelFileDescriptor
|
private lateinit var mInterface: ParcelFileDescriptor
|
||||||
private var isRunning = false
|
private var isRunning = false
|
||||||
private var tun2SocksService: Tun2SocksService? = null
|
private var tun2SocksService: Tun2SocksControl? = null
|
||||||
|
|
||||||
/**destroy
|
/**destroy
|
||||||
* Unfortunately registerDefaultNetworkCallback is going to return our VPN interface: https://android.googlesource.com/platform/frameworks/base/+/dda156ab0c5d66ad82bdcf76cda07cbc0a9c8a2e
|
* Unfortunately registerDefaultNetworkCallback is going to return our VPN interface: https://android.googlesource.com/platform/frameworks/base/+/dda156ab0c5d66ad82bdcf76cda07cbc0a9c8a2e
|
||||||
@@ -145,20 +145,20 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
*/
|
*/
|
||||||
private fun configureVpnService(): Boolean {
|
private fun configureVpnService(): Boolean {
|
||||||
val builder = Builder()
|
val builder = Builder()
|
||||||
|
|
||||||
// Configure network settings (addresses, routing and DNS)
|
// Configure network settings (addresses, routing and DNS)
|
||||||
configureNetworkSettings(builder)
|
configureNetworkSettings(builder)
|
||||||
|
|
||||||
// Configure app-specific settings (session name and per-app proxy)
|
// Configure app-specific settings (session name and per-app proxy)
|
||||||
configurePerAppProxy(builder)
|
configurePerAppProxy(builder)
|
||||||
|
|
||||||
// Close the old interface since the parameters have been changed
|
// Close the old interface since the parameters have been changed
|
||||||
try {
|
try {
|
||||||
mInterface.close()
|
mInterface.close()
|
||||||
} catch (ignored: Exception) {
|
} catch (ignored: Exception) {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure platform-specific features
|
// Configure platform-specific features
|
||||||
configurePlatformFeatures(builder)
|
configurePlatformFeatures(builder)
|
||||||
|
|
||||||
@@ -173,21 +173,21 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the basic network settings for the VPN.
|
* Configures the basic network settings for the VPN.
|
||||||
* This includes IP addresses, routing rules, and DNS servers.
|
* This includes IP addresses, routing rules, and DNS servers.
|
||||||
*
|
*
|
||||||
* @param builder The VPN Builder to configure
|
* @param builder The VPN Builder to configure
|
||||||
*/
|
*/
|
||||||
private fun configureNetworkSettings(builder: Builder) {
|
private fun configureNetworkSettings(builder: Builder) {
|
||||||
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
|
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
|
||||||
val bypassLan = SettingsManager.routingRulesetsBypassLan()
|
val bypassLan = SettingsManager.routingRulesetsBypassLan()
|
||||||
|
|
||||||
// Configure IPv4 settings
|
// Configure IPv4 settings
|
||||||
builder.setMtu(VPN_MTU)
|
builder.setMtu(VPN_MTU)
|
||||||
builder.addAddress(vpnConfig.ipv4Client, 30)
|
builder.addAddress(vpnConfig.ipv4Client, 30)
|
||||||
|
|
||||||
// Configure routing rules
|
// Configure routing rules
|
||||||
if (bypassLan) {
|
if (bypassLan) {
|
||||||
AppConfig.ROUTED_IP_LIST.forEach {
|
AppConfig.ROUTED_IP_LIST.forEach {
|
||||||
@@ -197,7 +197,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
} else {
|
} else {
|
||||||
builder.addRoute("0.0.0.0", 0)
|
builder.addRoute("0.0.0.0", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure IPv6 if enabled
|
// Configure IPv6 if enabled
|
||||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6) == true) {
|
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6) == true) {
|
||||||
builder.addAddress(vpnConfig.ipv6Client, 126)
|
builder.addAddress(vpnConfig.ipv6Client, 126)
|
||||||
@@ -208,7 +208,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
builder.addRoute("::", 0)
|
builder.addRoute("::", 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure DNS servers
|
// Configure DNS servers
|
||||||
//if (MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED) == true) {
|
//if (MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED) == true) {
|
||||||
// builder.addDnsServer(PRIVATE_VLAN4_ROUTER)
|
// builder.addDnsServer(PRIVATE_VLAN4_ROUTER)
|
||||||
@@ -218,13 +218,13 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
builder.addDnsServer(it)
|
builder.addDnsServer(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setSession(V2RayServiceManager.getRunningServerName())
|
builder.setSession(V2RayServiceManager.getRunningServerName())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures platform-specific VPN features for different Android versions.
|
* Configures platform-specific VPN features for different Android versions.
|
||||||
*
|
*
|
||||||
* @param builder The VPN Builder to configure
|
* @param builder The VPN Builder to configure
|
||||||
*/
|
*/
|
||||||
private fun configurePlatformFeatures(builder: Builder) {
|
private fun configurePlatformFeatures(builder: Builder) {
|
||||||
@@ -236,7 +236,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
Log.e(AppConfig.TAG, "Failed to request default network", e)
|
Log.e(AppConfig.TAG, "Failed to request default network", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Android Q (API 29) and above: Configure metering and HTTP proxy
|
// Android Q (API 29) and above: Configure metering and HTTP proxy
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
builder.setMetered(false)
|
builder.setMetered(false)
|
||||||
@@ -296,14 +296,23 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
|||||||
* Starts the tun2socks process with the appropriate parameters.
|
* Starts the tun2socks process with the appropriate parameters.
|
||||||
*/
|
*/
|
||||||
private fun runTun2socks() {
|
private fun runTun2socks() {
|
||||||
tun2SocksService = Tun2SocksService(
|
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_USE_HEV_TUNNEL) == true) {
|
||||||
context = applicationContext,
|
tun2SocksService = TProxyService(
|
||||||
vpnInterface = mInterface,
|
context = applicationContext,
|
||||||
isRunningProvider = { isRunning },
|
vpnInterface = mInterface,
|
||||||
restartCallback = { runTun2socks() }
|
isRunningProvider = { isRunning },
|
||||||
).also {
|
restartCallback = { runTun2socks() }
|
||||||
it.startTun2Socks()
|
)
|
||||||
|
} else {
|
||||||
|
tun2SocksService = Tun2SocksService(
|
||||||
|
context = applicationContext,
|
||||||
|
vpnInterface = mInterface,
|
||||||
|
isRunningProvider = { isRunning },
|
||||||
|
restartCallback = { runTun2socks() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tun2SocksService?.startTun2Socks()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -242,7 +242,8 @@ class SettingsActivity : BaseActivity() {
|
|||||||
AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
|
AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
|
||||||
AppConfig.PREF_PREFER_IPV6,
|
AppConfig.PREF_PREFER_IPV6,
|
||||||
AppConfig.PREF_PROXY_SHARING,
|
AppConfig.PREF_PROXY_SHARING,
|
||||||
AppConfig.PREF_ALLOW_INSECURE
|
AppConfig.PREF_ALLOW_INSECURE,
|
||||||
|
AppConfig.PREF_USE_HEV_TUNNEL
|
||||||
).forEach { key ->
|
).forEach { key ->
|
||||||
findPreference<CheckBoxPreference>(key)?.isChecked =
|
findPreference<CheckBoxPreference>(key)?.isChecked =
|
||||||
MmkvManager.decodeSettingsBool(key, false)
|
MmkvManager.decodeSettingsBool(key, false)
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
|||||||
AppConfig.SUBSCRIPTION_AUTO_UPDATE,
|
AppConfig.SUBSCRIPTION_AUTO_UPDATE,
|
||||||
AppConfig.PREF_FRAGMENT_ENABLED,
|
AppConfig.PREF_FRAGMENT_ENABLED,
|
||||||
AppConfig.PREF_MUX_ENABLED,
|
AppConfig.PREF_MUX_ENABLED,
|
||||||
|
AppConfig.PREF_USE_HEV_TUNNEL
|
||||||
-> {
|
-> {
|
||||||
MmkvManager.encodeSettings(key, sharedPreferences.getBoolean(key, false))
|
MmkvManager.encodeSettings(key, sharedPreferences.getBoolean(key, false))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,6 +247,8 @@
|
|||||||
<string name="title_language">اللغة</string>
|
<string name="title_language">اللغة</string>
|
||||||
<string name="title_ui_settings">إعدادات واجهة المستخدم</string>
|
<string name="title_ui_settings">إعدادات واجهة المستخدم</string>
|
||||||
<string name="title_pref_ui_mode_night">إعدادات وضع واجهة المستخدم ليلاً</string>
|
<string name="title_pref_ui_mode_night">إعدادات وضع واجهة المستخدم ليلاً</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">Logcat</string>
|
<string name="title_logcat">Logcat</string>
|
||||||
<string name="logcat_copy">نسخ</string>
|
<string name="logcat_copy">نسخ</string>
|
||||||
|
|||||||
@@ -248,6 +248,8 @@
|
|||||||
<string name="title_language">ভাষা</string>
|
<string name="title_language">ভাষা</string>
|
||||||
<string name="title_ui_settings">ইউআই সেটিংস</string>
|
<string name="title_ui_settings">ইউআই সেটিংস</string>
|
||||||
<string name="title_pref_ui_mode_night">ইউআই মোড সেটিংস</string>
|
<string name="title_pref_ui_mode_night">ইউআই মোড সেটিংস</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">লগক্যাট</string>
|
<string name="title_logcat">লগক্যাট</string>
|
||||||
<string name="logcat_copy">কপি করুন</string>
|
<string name="logcat_copy">কপি করুন</string>
|
||||||
|
|||||||
@@ -248,6 +248,8 @@
|
|||||||
<string name="title_language">زووݩ</string>
|
<string name="title_language">زووݩ</string>
|
||||||
<string name="title_ui_settings">سامووا رابت منتوری</string>
|
<string name="title_ui_settings">سامووا رابت منتوری</string>
|
||||||
<string name="title_pref_ui_mode_night">سامووا هالت رابت منتوری</string>
|
<string name="title_pref_ui_mode_night">سامووا هالت رابت منتوری</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">داسووا</string>
|
<string name="title_logcat">داسووا</string>
|
||||||
<string name="logcat_copy">لف گیری</string>
|
<string name="logcat_copy">لف گیری</string>
|
||||||
|
|||||||
@@ -245,6 +245,8 @@
|
|||||||
<string name="title_language">زبان</string>
|
<string name="title_language">زبان</string>
|
||||||
<string name="title_ui_settings">تنظیمات رابط کاربری</string>
|
<string name="title_ui_settings">تنظیمات رابط کاربری</string>
|
||||||
<string name="title_pref_ui_mode_night">تنظیمات حالت رابط کاربری</string>
|
<string name="title_pref_ui_mode_night">تنظیمات حالت رابط کاربری</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">گزارشات</string>
|
<string name="title_logcat">گزارشات</string>
|
||||||
<string name="logcat_copy">کپی</string>
|
<string name="logcat_copy">کپی</string>
|
||||||
|
|||||||
@@ -247,6 +247,8 @@
|
|||||||
<string name="title_language">Язык</string>
|
<string name="title_language">Язык</string>
|
||||||
<string name="title_ui_settings">Настройки интерфейса</string>
|
<string name="title_ui_settings">Настройки интерфейса</string>
|
||||||
<string name="title_pref_ui_mode_night">Тема интерфейса</string>
|
<string name="title_pref_ui_mode_night">Тема интерфейса</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">Журнал</string>
|
<string name="title_logcat">Журнал</string>
|
||||||
<string name="logcat_copy">Копировать</string>
|
<string name="logcat_copy">Копировать</string>
|
||||||
|
|||||||
@@ -248,6 +248,8 @@
|
|||||||
<string name="title_language">Ngôn ngữ</string>
|
<string name="title_language">Ngôn ngữ</string>
|
||||||
<string name="title_ui_settings">Cài đặt UI</string>
|
<string name="title_ui_settings">Cài đặt UI</string>
|
||||||
<string name="title_pref_ui_mode_night">Cài đặt chế độ UI</string>
|
<string name="title_pref_ui_mode_night">Cài đặt chế độ UI</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">Logcat</string>
|
<string name="title_logcat">Logcat</string>
|
||||||
<string name="logcat_copy">Sao chép</string>
|
<string name="logcat_copy">Sao chép</string>
|
||||||
|
|||||||
@@ -245,6 +245,8 @@
|
|||||||
<string name="title_language">语言</string>
|
<string name="title_language">语言</string>
|
||||||
<string name="title_ui_settings">用户界面设置</string>
|
<string name="title_ui_settings">用户界面设置</string>
|
||||||
<string name="title_pref_ui_mode_night">界面颜色设置</string>
|
<string name="title_pref_ui_mode_night">界面颜色设置</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">启用新的 TUN 功能</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">选择启用后 TUN 将使用 hev-socks5-tunnel 否则使用 badvpn-tun2socks</string>
|
||||||
|
|
||||||
<string name="title_logcat">Logcat</string>
|
<string name="title_logcat">Logcat</string>
|
||||||
<string name="logcat_copy">复制</string>
|
<string name="logcat_copy">复制</string>
|
||||||
|
|||||||
@@ -246,6 +246,8 @@
|
|||||||
<string name="title_language">語言</string>
|
<string name="title_language">語言</string>
|
||||||
<string name="title_ui_settings">介面顏色設定</string>
|
<string name="title_ui_settings">介面顏色設定</string>
|
||||||
<string name="title_pref_ui_mode_night">介面顯示模式</string>
|
<string name="title_pref_ui_mode_night">介面顯示模式</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">啟用新 TUN 功能</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">選擇啟用後,TUN 將使用 hev-socks5-tunnel,否則使用 badvpn-tun2socks。</string>
|
||||||
|
|
||||||
<string name="title_logcat">Logcat</string>
|
<string name="title_logcat">Logcat</string>
|
||||||
<string name="logcat_copy">複製</string>
|
<string name="logcat_copy">複製</string>
|
||||||
|
|||||||
@@ -249,6 +249,8 @@
|
|||||||
<string name="title_language">Language</string>
|
<string name="title_language">Language</string>
|
||||||
<string name="title_ui_settings">UI settings</string>
|
<string name="title_ui_settings">UI settings</string>
|
||||||
<string name="title_pref_ui_mode_night">UI mode settings</string>
|
<string name="title_pref_ui_mode_night">UI mode settings</string>
|
||||||
|
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
|
||||||
|
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
|
||||||
|
|
||||||
<string name="title_logcat">Logcat</string>
|
<string name="title_logcat">Logcat</string>
|
||||||
<string name="logcat_copy">Copy</string>
|
<string name="logcat_copy">Copy</string>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
android:key="pref_route_only_enabled"
|
android:key="pref_route_only_enabled"
|
||||||
android:summary="@string/summary_pref_route_only_enabled"
|
android:summary="@string/summary_pref_route_only_enabled"
|
||||||
android:title="@string/title_pref_route_only_enabled" />
|
android:title="@string/title_pref_route_only_enabled" />
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="pref_is_booted"
|
android:key="pref_is_booted"
|
||||||
android:summary="@string/summary_pref_is_booted"
|
android:summary="@string/summary_pref_is_booted"
|
||||||
@@ -254,6 +255,11 @@
|
|||||||
android:key="pref_mode"
|
android:key="pref_mode"
|
||||||
android:summary="%s"
|
android:summary="%s"
|
||||||
android:title="@string/title_mode" />
|
android:title="@string/title_mode" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="pref_use_hev_tunnel"
|
||||||
|
android:summary="@string/summary_pref_use_hev_tunnel"
|
||||||
|
android:title="@string/title_pref_use_hev_tunnel" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user