diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt index e54812cd..26d8c378 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt @@ -11,6 +11,7 @@ class AngApplication : Application() { const val PREF_LAST_VERSION = "pref_last_version" } + var curIndex = -1 //Current proxy that is opened. (Used to implement restart feature) var firstRun = false private set diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt index ada2cbc1..3dfd15fc 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt @@ -64,7 +64,6 @@ class V2RayVpnService : VpnService() { private var mNotificationManager: NotificationManager? = null - /** * Unfortunately registerDefaultNetworkCallback is going to return our VPN interface: https://android.googlesource.com/platform/frameworks/base/+/dda156ab0c5d66ad82bdcf76cda07cbc0a9c8a2e * @@ -282,12 +281,19 @@ class V2RayVpnService : VpnService() { unregisterReceiver(mMsgReceive) } catch (e: Exception) { } + + //stopSelf has to be called ahead of mInterface.close(). otherwise v2ray core cannot be stooped + //It's strage but true. + //This can be verified by putting stopself() behind and call stopLoop and startLoop + //in a row for several times. You will find that later created v2ray core report port in use + //which means the first v2ray core somehow failed to stop and release the port. + stopSelf() + try { mInterface.close() } catch (ignored: Exception) { } - stopSelf() } } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt index 7c717baa..045f681e 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt @@ -232,7 +232,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList R.id.export_all -> { if (AngConfigManager.shareAll2Clipboard() == 0) { - toast(R.string.toast_success) + //remove toast, otherwise it will block previous warning message } else { toast(R.string.toast_failure) } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt index 583ae76a..f83ae661 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt @@ -4,10 +4,8 @@ import android.content.Intent import android.content.SharedPreferences import android.net.Uri import android.os.Bundle -import android.preference.CheckBoxPreference -import android.preference.EditTextPreference -import android.preference.Preference -import android.preference.PreferenceFragment +import android.preference.* +import com.v2ray.ang.AngApplication import com.v2ray.ang.BuildConfig //import com.v2ray.ang.InappBuyActivity import com.v2ray.ang.R @@ -29,6 +27,7 @@ class SettingsActivity : BaseActivity() { // const val PREF_MUX_ENAimport libv2ray.Libv2rayBLED = "pref_mux_enabled" const val PREF_SPEED_ENABLED = "pref_speed_enabled" const val PREF_SNIFFING_ENABLED = "pref_sniffing_enabled" + const val PREF_PROXY_SHARING = "pref_proxy_sharing_enabled" const val PREF_LOCAL_DNS_ENABLED = "pref_local_dns_enabled" const val PREF_REMOTE_DNS = "pref_remote_dns" const val PREF_DOMESTIC_DNS = "pref_domestic_dns" @@ -59,12 +58,19 @@ class SettingsActivity : BaseActivity() { class SettingsFragment : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener { val perAppProxy by lazy { findPreference(PREF_PER_APP_PROXY) as CheckBoxPreference } - // val autoRestart by lazy { findPreference(PREF_AUTO_RESTART) as CheckBoxPreference } - val remoteDns by lazy { findPreference(PREF_REMOTE_DNS) as EditTextPreference } - val domesticDns by lazy { findPreference(PREF_DOMESTIC_DNS) as EditTextPreference } + val sppedEnabled by lazy { findPreference(PREF_SPEED_ENABLED) as CheckBoxPreference } + val sniffingEnabled by lazy { findPreference(PREF_SNIFFING_ENABLED) as CheckBoxPreference } + val proxySharing by lazy { findPreference(PREF_PROXY_SHARING) as CheckBoxPreference } + val domainStrategy by lazy { findPreference(PREF_ROUTING_DOMAIN_STRATEGY) as ListPreference } + val routingMode by lazy { findPreference(PREF_ROUTING_MODE) as ListPreference } - val enableLocalDns by lazy { findPreference(PREF_LOCAL_DNS_ENABLED) as CheckBoxPreference } val forwardIpv6 by lazy { findPreference(PREF_FORWARD_IPV6) as CheckBoxPreference } + val enableLocalDns by lazy { findPreference(PREF_LOCAL_DNS_ENABLED) as CheckBoxPreference } + val domesticDns by lazy { findPreference(PREF_DOMESTIC_DNS) as EditTextPreference } + val remoteDns by lazy { findPreference(PREF_REMOTE_DNS) as EditTextPreference } + + // val autoRestart by lazy { findPreference(PREF_AUTO_RESTART) as CheckBoxPreference } + // val socksPort by lazy { findPreference(PREF_SOCKS_PORT) as EditTextPreference } // val httpPort by lazy { findPreference(PREF_HTTP_PORT) as EditTextPreference } @@ -76,14 +82,95 @@ class SettingsActivity : BaseActivity() { // val tgGroup: Preference by lazy { findPreference(PREF_TG_GROUP) } val version: Preference by lazy { findPreference(PREF_VERSION) } + private fun restartProxy() { + Utils.stopVService(activity) + Utils.startVService(activity) + } + + private fun isRunning(): Boolean { + return Utils.isServiceRun(activity, "com.v2ray.ang.service.V2RayVpnService") + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) addPreferencesFromResource(R.xml.pref_settings) + var app = activity.application as AngApplication + + perAppProxy.setOnPreferenceClickListener { + if (isRunning()) { + Utils.stopVService(activity) + } + startActivity() + perAppProxy.isChecked = true + true + } + sppedEnabled.setOnPreferenceClickListener { + if (isRunning()) + restartProxy() + true + } + sniffingEnabled.setOnPreferenceClickListener { + if (isRunning()) + restartProxy() + true + } + + proxySharing.setOnPreferenceClickListener { + if (proxySharing.isChecked) + toast(R.string.toast_warning_pref_proxysharing) + if (isRunning()) + restartProxy() + true + } + + domainStrategy.setOnPreferenceChangeListener { _, _ -> + if (isRunning()) + restartProxy() + true + } + routingMode.setOnPreferenceChangeListener { _, _ -> + if (isRunning()) + restartProxy() + true + } routingCustom.onClick { + if (isRunning()) + Utils.stopVService(activity) startActivity() } + forwardIpv6.setOnPreferenceClickListener { + if (isRunning()) + restartProxy() + true + } + + enableLocalDns.setOnPreferenceClickListener { + if (isRunning()) + restartProxy() + true + } + + + domesticDns.setOnPreferenceChangeListener { preference, any -> + // domesticDns.summary = any as String + val nval = any as String + domesticDns.summary = if (nval == "") AppConfig.DNS_DIRECT else nval + if (isRunning()) + restartProxy() + true + } + + remoteDns.setOnPreferenceChangeListener { preference, any -> + // remoteDns.summary = any as String + val nval = any as String + remoteDns.summary = if (nval == "") AppConfig.DNS_AGENT else nval + if (isRunning()) + restartProxy() + true + } + // donate.onClick { // startActivity() // } @@ -110,24 +197,7 @@ class SettingsActivity : BaseActivity() { // } // } - perAppProxy.setOnPreferenceClickListener { - startActivity() - perAppProxy.isChecked = true - false - } - remoteDns.setOnPreferenceChangeListener { preference, any -> - // remoteDns.summary = any as String - val nval = any as String - remoteDns.summary = if (nval == "") AppConfig.DNS_AGENT else nval - true - } - domesticDns.setOnPreferenceChangeListener { preference, any -> - // domesticDns.summary = any as String - val nval = any as String - domesticDns.summary = if (nval == "") AppConfig.DNS_DIRECT else nval - true - } // socksPort.setOnPreferenceChangeListener { preference, any -> // socksPort.summary = any as String // true diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt index b7cef52c..217e3573 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt @@ -147,13 +147,15 @@ object AngConfigManager { fun setActiveServer(index: Int): Int { try { if (index < 0 || index > angConfig.vmess.count() - 1) { + app.curIndex = -1 return -1 } angConfig.index = index - + app.curIndex = index storeConfigFile() } catch (e: Exception) { e.printStackTrace() + app.curIndex = -1 return -1 } return 0 diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt index 34313790..b986add4 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt @@ -27,6 +27,7 @@ import com.v2ray.ang.AngApplication import com.v2ray.ang.AppConfig import com.v2ray.ang.R import com.v2ray.ang.extension.responseLength +import com.v2ray.ang.extension.v2RayApplication import com.v2ray.ang.service.V2RayVpnService import com.v2ray.ang.ui.SettingsActivity import kotlinx.android.synthetic.main.activity_logcat.* @@ -311,7 +312,11 @@ object Utils { * startVService */ fun startVService(context: Context): Boolean { - context.toast(R.string.toast_services_start) + if (context.v2RayApplication.defaultDPreference.getPrefBoolean(SettingsActivity.PREF_PROXY_SHARING, false)) { + context.toast(R.string.toast_warning_pref_proxysharing_short) + }else{ + context.toast(R.string.toast_services_start) + } if (AngConfigManager.genStoreV2rayConfig(-1)) { val configContent = AngConfigManager.currGeneratedV2rayConfig() val configType = AngConfigManager.currConfigType() @@ -335,6 +340,7 @@ object Utils { */ fun startVService(context: Context, guid: String): Boolean { val index = AngConfigManager.getIndexViaGuid(guid) + context.v2RayApplication.curIndex=index return startVService(context, index) } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt index ca3deb78..559efc4a 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt @@ -129,6 +129,12 @@ object V2rayConfigUtil { */ private fun inbounds(vmess: VmessBean, v2rayConfig: V2rayConfig, app: AngApplication): Boolean { try { + v2rayConfig.inbounds.forEach { curInbound -> + if (!app.defaultDPreference.getPrefBoolean(SettingsActivity.PREF_PROXY_SHARING, false)) { + //bind all inbounds to localhost if the user requests + curInbound.listen = "127.0.0.1" + } + } v2rayConfig.inbounds[0].port = 10808 // val socksPort = Utils.parseInt(app.defaultDPreference.getPrefString(SettingsActivity.PREF_SOCKS_PORT, "10808")) // val lanconnPort = Utils.parseInt(app.defaultDPreference.getPrefString(SettingsActivity.PREF_HTTP_PORT, "")) @@ -547,7 +553,7 @@ object V2rayConfigUtil { mux = null)) } - // DNS routing + // DNS routing v2rayConfig.routing.rules.add(0, V2rayConfig.RoutingBean.RulesBean( type = "field", outboundTag = AppConfig.TAG_DIRECT, diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index c6e3216d..6fe69c1c 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -180,5 +180,9 @@ 绕过大陆地址 绕过局域网及大陆地址 + 代理共享 + 绑定代理入口ip到0.0.0.0 + 其他设备可以使用socks/http协议通过您的IP地址连接到代理\nHttp 代理: http://您的ip:10809\nSocks 代理: socks(4/5)://您的ip:10808\n仅在受信任的网络中启用以避免未经授权的连接 + 代理共享已启用,请确保处于受信网络 diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index e9c6587e..8c5a3fd8 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -182,4 +182,8 @@ 略過中國大陸 略過局域網及中國大陸 + 代理共享 + 綁定代理入口ip到0.0.0.0 + 其他設備可以使用socks/http協議通過您的IP地址連接到代理\nHttp 代理: http://您的ip:10809\nSocks 代理: socks(4/5)://您的ip:10808\n僅在受信任的網絡中啟用以避免未經授權的連接 + 代理共享已啟用,請確保處於受信網絡 diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 8eb7a93d..ac4c9254 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -181,5 +181,9 @@ Bypass mainland address Bypassing LAN and mainland address + Proxy sharing + Bind inbound to 0.0.0.0 + Other devices can connect to proxy by your ip address through socks/http protocol\nHttp Proxy: http://yourIP:10809\nSocks Proxy: socks(4/5)://yourIP:10808\nOnly enable in trusted network to avoid unauthorized connection + Proxy sharing enabled\nMake sure you are in a trusted network diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml index 2b42580c..6dcf3c16 100644 --- a/V2rayNG/app/src/main/res/xml/pref_settings.xml +++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml @@ -22,6 +22,13 @@ android:summary="@string/summary_pref_sniffing_enabled" android:title="@string/title_pref_sniffing_enabled" /> + +