diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 74aad4d8..8583e241 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,7 +12,7 @@ android { minSdk = 21 targetSdk = 34 versionCode = 10 - versionName = "1.3.8-beta2" + versionName = "1.3.8-beta3" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/activities/MainActivity.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/activities/MainActivity.kt index 790d1285..73fb715a 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/activities/MainActivity.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/activities/MainActivity.kt @@ -238,8 +238,22 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "Updating status: $status, $mode") val preferences = getPreferences() - val proxyIp = preferences.getStringNotNull("byedpi_proxy_ip", "127.0.0.1") - val proxyPort = preferences.getStringNotNull("byedpi_proxy_port", "1080") + + val cmdEnable = preferences.getBoolean("byedpi_enable_cmd_settings", false) + val cmdArgs = if (cmdEnable) preferences.getStringNotNull("byedpi_cmd_args", "") else null + val args = cmdArgs?.split(" ") ?: emptyList() + val cmdIp = args.let { argsList -> + val ipIndex = argsList.indexOfFirst { it == "-i" || it == "--ip" } + if (ipIndex != -1) argsList[ipIndex + 1] else null + } + val cmdPort = args.let { argsList -> + val portIndex = argsList.indexOfFirst { it == "-p" || it == "--port" } + if (portIndex != -1) argsList[portIndex + 1] else null + } + + val proxyIp = cmdIp ?: preferences.getStringNotNull("byedpi_proxy_ip", "127.0.0.1") + val proxyPort = cmdPort ?: preferences.getStringNotNull("byedpi_proxy_port", "1080") + binding.proxyAddress.text = getString(R.string.proxy_address, proxyIp, proxyPort) when (status) { diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt index 6df4c1c5..1e708bba 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt @@ -1,6 +1,7 @@ package io.github.dovecoteescapee.byedpi.core import android.content.SharedPreferences +import android.util.Log import io.github.dovecoteescapee.byedpi.utility.getStringNotNull import io.github.dovecoteescapee.byedpi.utility.shellSplit @@ -15,20 +16,38 @@ sealed interface ByeDpiProxyPreferences { } class ByeDpiProxyCmdPreferences(val args: Array) : ByeDpiProxyPreferences { - constructor(cmd: String) : this(cmdToArgs(cmd)) - constructor(preferences: SharedPreferences) : this( - preferences.getStringNotNull( - "byedpi_cmd_args", - "" + cmdToArgs( + preferences.getStringNotNull("byedpi_cmd_args", ""), + preferences ) ) companion object { - private fun cmdToArgs(cmd: String): Array { + private fun cmdToArgs(cmd: String, preferences: SharedPreferences): Array { val firstArgIndex = cmd.indexOf("-") - val argsStr = (if (firstArgIndex > 0) cmd.substring(firstArgIndex) else cmd).trim() - return arrayOf("ciadpi") + shellSplit(argsStr) + val args = (if (firstArgIndex > 0) cmd.substring(firstArgIndex) else cmd).trim() + + Log.i("ProxyPref", "Parse args: $args") + + val hasIp = args.contains("-i ") || args.contains("--ip ") + val hasPort = args.contains("-p ") || args.contains("--port ") + + val ip = preferences.getStringNotNull("byedpi_proxy_ip", "127.0.0.1") + val port = preferences.getStringNotNull("byedpi_proxy_port", "1080") + + val prefix = buildString { + if (!hasIp) append("-i $ip ") + if (!hasPort) append("-p $port ") + } + + Log.i("ProxyPref", "Added from settings: $prefix") + + if (prefix.isNotEmpty()) { + return arrayOf("ciadpi") + shellSplit("$prefix$args") + } + + return arrayOf("ciadpi") + shellSplit(args) } } } diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt index 315335c9..c0fd2729 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt @@ -19,8 +19,6 @@ class ByeDpiUISettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.byedpi_ui_settings, rootKey) - setEditTextPreferenceListener("byedpi_proxy_ip") { checkIp(it) } - setEditTestPreferenceListenerPort("byedpi_proxy_port") setEditTestPreferenceListenerInt( "byedpi_max_connections", 1, diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt index 5ca52795..448fb9cd 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt @@ -2,7 +2,6 @@ package io.github.dovecoteescapee.byedpi.fragments import android.content.Intent import android.content.SharedPreferences -import android.content.res.Configuration import android.os.Bundle import android.provider.Settings import android.util.Log @@ -16,7 +15,6 @@ import io.github.dovecoteescapee.byedpi.data.Mode import io.github.dovecoteescapee.byedpi.utility.AccessibilityUtils import io.github.dovecoteescapee.byedpi.services.AutoStartAccessibilityService import io.github.dovecoteescapee.byedpi.utility.* -import java.util.Locale class MainSettingsFragment : PreferenceFragmentCompat() { companion object { @@ -61,6 +59,9 @@ class MainSettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.main_settings, rootKey) + setEditTextPreferenceListener("byedpi_proxy_ip") { checkIp(it) } + setEditTestPreferenceListenerPort("byedpi_proxy_port") + setEditTextPreferenceListener("dns_ip") { it.isBlank() || checkNotLocalIp(it) } @@ -77,7 +78,7 @@ class MainSettingsFragment : PreferenceFragmentCompat() { true } - val accessibilityStatusPref = findPreferenceNotNull("accessibility_service_status") + val accessibilityStatus = findPreferenceNotNull("accessibility_service_status") val switchCommandLineSettings = findPreferenceNotNull("byedpi_enable_cmd_settings") val uiSettings = findPreferenceNotNull("byedpi_ui_settings") @@ -94,10 +95,11 @@ class MainSettingsFragment : PreferenceFragmentCompat() { switchCommandLineSettings.setOnPreferenceChangeListener { _, newValue -> setByeDpiSettingsMode(newValue as Boolean) + updatePreferences() true } - accessibilityStatusPref.setOnPreferenceClickListener { + accessibilityStatus.setOnPreferenceClickListener { val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) startActivity(intent) true @@ -112,13 +114,14 @@ class MainSettingsFragment : PreferenceFragmentCompat() { findPreferenceNotNull("version").summary = BuildConfig.VERSION_NAME - updateAccessibilityStatus(accessibilityStatusPref) + updateAccessibilityStatus() updatePreferences() } override fun onResume() { super.onResume() sharedPreferences?.registerOnSharedPreferenceChangeListener(preferenceListener) + updateAccessibilityStatus() updatePreferences() } @@ -128,35 +131,48 @@ class MainSettingsFragment : PreferenceFragmentCompat() { } private fun updatePreferences() { - val mode = findPreferenceNotNull("byedpi_mode") - .value.let { Mode.fromString(it) } + val mode = findPreferenceNotNull("byedpi_mode").value.let { Mode.fromString(it) } val dns = findPreferenceNotNull("dns_ip") val ipv6 = findPreferenceNotNull("ipv6_enable") - val applist_type = findPreferenceNotNull("applist_type") - val selected_apps = findPreferenceNotNull("selected_apps") - val accessibilityStatusPref = findPreferenceNotNull("accessibility_service_status") + val ip = findPreferenceNotNull("byedpi_proxy_ip") + val port = findPreferenceNotNull("byedpi_proxy_port") + + val applistType = findPreferenceNotNull("applist_type") + val selectedApps = findPreferenceNotNull("selected_apps") - updateAccessibilityStatus(accessibilityStatusPref) + val cmdEnable = sharedPreferences?.getBoolean("byedpi_enable_cmd_settings", false) + + if (cmdEnable == true) { + val cmdArgs = sharedPreferences?.getStringNotNull("byedpi_cmd_args", "")?.split(" ") + val ipIndex = cmdArgs?.indexOfFirst { it == "-i" || it == "--ip" } + val portIndex = cmdArgs?.indexOfFirst { it == "-p" || it == "--port" } + + ip.isEnabled = ipIndex == -1 + port.isEnabled = portIndex == -1 + } else { + ip.isEnabled = true + port.isEnabled = true + } when (mode) { Mode.VPN -> { dns.isVisible = true ipv6.isVisible = true - when (applist_type.value) { + when (applistType.value) { "disable" -> { - applist_type.isVisible = true - selected_apps.isVisible = false + applistType.isVisible = true + selectedApps.isVisible = false } "blacklist", "whitelist" -> { - applist_type.isVisible = true - selected_apps.isVisible = true + applistType.isVisible = true + selectedApps.isVisible = true } else -> { - applist_type.isVisible = true - selected_apps.isVisible = false - Log.w(TAG, "Unexpected applist_type value: ${applist_type.value}") + applistType.isVisible = true + selectedApps.isVisible = false + Log.w(TAG, "Unexpected applistType value: ${applistType.value}") } } } @@ -164,23 +180,22 @@ class MainSettingsFragment : PreferenceFragmentCompat() { Mode.Proxy -> { dns.isVisible = false ipv6.isVisible = false - applist_type.isVisible = false - selected_apps.isVisible = false + applistType.isVisible = false + selectedApps.isVisible = false } } } - private fun updateAccessibilityStatus(preference: Preference?) { - preference?.let { - val isEnabled = AccessibilityUtils.isAccessibilityServiceEnabled( - requireContext(), - AutoStartAccessibilityService::class.java - ) - it.summary = if (isEnabled) { - getString(R.string.accessibility_service_enabled) - } else { - getString(R.string.accessibility_service_disabled) - } + private fun updateAccessibilityStatus() { + val accessibilityStatus = findPreferenceNotNull("accessibility_service_status") + val isEnabled = AccessibilityUtils.isAccessibilityServiceEnabled( + requireContext(), + AutoStartAccessibilityService::class.java + ) + accessibilityStatus.summary = if (isEnabled) { + getString(R.string.accessibility_service_enabled) + } else { + getString(R.string.accessibility_service_disabled) } } } diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt index f37e0664..58beafbe 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt @@ -179,8 +179,22 @@ class ByeDpiVpnService : LifecycleVpnService() { } val sharedPreferences = getPreferences() - val port = sharedPreferences.getString("byedpi_proxy_port", null)?.toInt() ?: 1080 - val dns = sharedPreferences.getStringNotNull("dns_ip", "1.1.1.1") + + val cmdEnable = sharedPreferences.getBoolean("byedpi_enable_cmd_settings", false) + val cmdArgs = if (cmdEnable) sharedPreferences.getStringNotNull("byedpi_cmd_args", "") else null + val args = cmdArgs?.split(" ") ?: emptyList() + val cmdIp = args.let { argsList -> + val ipIndex = argsList.indexOfFirst { it == "-i" || it == "--ip" } + if (ipIndex != -1) argsList[ipIndex + 1] else null + } + val cmdPort = args.let { argsList -> + val portIndex = argsList.indexOfFirst { it == "-p" || it == "--port" } + if (portIndex != -1) argsList[portIndex + 1] else null + } + + val ip = cmdIp ?: sharedPreferences.getStringNotNull("byedpi_proxy_ip", "127.0.0.1") + val port = cmdPort ?: sharedPreferences.getStringNotNull("byedpi_proxy_port", "1080") + val dns = sharedPreferences.getStringNotNull("dns_ip", "8.8.8.8") val ipv6 = sharedPreferences.getBoolean("ipv6_enable", false) val tun2socksConfig = """ @@ -188,7 +202,7 @@ class ByeDpiVpnService : LifecycleVpnService() { | task-stack-size: 81920 | socks5: | mtu: 8500 - | address: 127.0.0.1 + | address: $ip | port: $port | udp: udp """.trimMargin("| ") @@ -209,7 +223,7 @@ class ByeDpiVpnService : LifecycleVpnService() { TProxyService.TProxyStartService(configPath.absolutePath, fd.fd) - Log.i(TAG, "Tun2Socks started") + Log.i(TAG, "Tun2Socks started. ip: $ip port: $port") } private fun stopTun2Socks() { diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index e60e7534..a93ee7b8 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -21,7 +21,7 @@ Theme Mode DNS - Listening address + Address Port Max connections Buffer size diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8c743920..da60488f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,7 +21,7 @@ Тема Режим DNS - Адрес прослушивания + Адрес Порт Максимальное к-во подключений Размер буфера diff --git a/app/src/main/res/xml/byedpi_ui_settings.xml b/app/src/main/res/xml/byedpi_ui_settings.xml index 8c0ff06d..6b74fe70 100644 --- a/app/src/main/res/xml/byedpi_ui_settings.xml +++ b/app/src/main/res/xml/byedpi_ui_settings.xml @@ -15,19 +15,6 @@ - - - - + + + + + + + +