From ac7eb28e91432b619f9a44bd46a1aafdd568fd6e Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:06:27 +0800 Subject: [PATCH] Auto update subscriptions when adding a url --- .../v2ray/ang/service/SubscriptionUpdater.kt | 14 +- .../kotlin/com/v2ray/ang/ui/MainActivity.kt | 6 +- .../com/v2ray/ang/ui/SubSettingActivity.kt | 6 +- .../com/v2ray/ang/util/AngConfigManager.kt | 139 +++++++++++++++--- .../com/v2ray/ang/viewmodel/SubViewModel.kt | 93 ------------ 5 files changed, 121 insertions(+), 137 deletions(-) delete mode 100644 V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SubViewModel.kt diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/SubscriptionUpdater.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/SubscriptionUpdater.kt index 2ba506b39..e7a29308b 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/SubscriptionUpdater.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/SubscriptionUpdater.kt @@ -58,23 +58,11 @@ object SubscriptionUpdater { "subscription automatic update: ---${subscription.remarks}" ) val configs = Utils.getUrlContentWithCustomUserAgent(subscription.url) - importBatchConfig(configs, i.first) + AngConfigManager.importBatchConfig(configs, i.first, false) notification.setContentText("Updating ${subscription.remarks}") } notificationManager.cancel(3) return Result.success() } } - - fun importBatchConfig(server: String?, subid: String = "") { - val append = false - - val count = AngConfigManager.importBatchConfig(server, subid, append) - if (count <= 0) { - AngConfigManager.importBatchConfig(Utils.decode(server), subid, append) - } - if (count <= 0) { - AngConfigManager.appendCustomConfigServer(server, subid) - } - } } \ No newline at end of file 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 e0668a3c1..4c3f81466 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 @@ -40,7 +40,6 @@ import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.MmkvManager import com.v2ray.ang.util.Utils import com.v2ray.ang.viewmodel.MainViewModel -import com.v2ray.ang.viewmodel.SubViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -64,7 +63,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } private var mItemTouchHelper: ItemTouchHelper? = null val mainViewModel: MainViewModel by viewModels() - val subViewModel: SubViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -429,7 +427,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList .show() lifecycleScope.launch(Dispatchers.IO) { - val count = subViewModel.importBatchConfig(server, mainViewModel.subscriptionId, true) + val count = AngConfigManager.importBatchConfig(server, mainViewModel.subscriptionId, true) delay(500L) launch(Dispatchers.Main) { if (count > 0) { @@ -524,7 +522,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList .show() lifecycleScope.launch(Dispatchers.IO) { - val count = subViewModel.updateConfigViaSubAll() + val count = AngConfigManager.updateConfigViaSubAll() delay(500L) launch(Dispatchers.Main) { if (count > 0) { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt index 18c9ed773..09aca34f7 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt @@ -4,7 +4,6 @@ import android.content.Intent import android.os.Bundle import android.view.Menu import android.view.MenuItem -import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager @@ -13,8 +12,8 @@ import com.v2ray.ang.databinding.ActivitySubSettingBinding import com.v2ray.ang.databinding.LayoutProgressBinding import com.v2ray.ang.dto.SubscriptionItem import com.v2ray.ang.extension.toast +import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.MmkvManager -import com.v2ray.ang.viewmodel.SubViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -24,7 +23,6 @@ class SubSettingActivity : BaseActivity() { var subscriptions: List> = listOf() private val adapter by lazy { SubSettingRecyclerAdapter(this) } - val subViewModel: SubViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -63,7 +61,7 @@ class SubSettingActivity : BaseActivity() { .show() lifecycleScope.launch(Dispatchers.IO) { - val count = subViewModel.updateConfigViaSubAll() + val count = AngConfigManager.updateConfigViaSubAll() delay(500L) launch(Dispatchers.Main) { if (count > 0) { 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 31c980cd6..a5458edc5 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 @@ -3,6 +3,7 @@ package com.v2ray.ang.util import android.content.Context import android.graphics.Bitmap import android.text.TextUtils +import android.util.Log import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.JsonPrimitive @@ -10,8 +11,7 @@ import com.google.gson.JsonSerializationContext import com.google.gson.JsonSerializer import com.google.gson.reflect.TypeToken import com.tencent.mmkv.MMKV -import com.v2ray.ang.AppConfig.PROTOCOL_HTTP -import com.v2ray.ang.AppConfig.PROTOCOL_HTTPS +import com.v2ray.ang.AppConfig import com.v2ray.ang.R import com.v2ray.ang.dto.* import com.v2ray.ang.util.MmkvManager.KEY_SELECTED_SERVER @@ -202,9 +202,9 @@ object AngConfigManager { // } /** - * import config form qrcode or... + * parse config form qrcode or... */ - private fun importConfig( + private fun parseConfig( str: String?, subid: String, removedSelectedServer: ServerConfig? @@ -214,13 +214,6 @@ object AngConfigManager { return R.string.toast_none_data } - //maybe Subscription - if ((str.startsWith(PROTOCOL_HTTP) || str.startsWith(PROTOCOL_HTTPS)) - ) { - MmkvManager.importUrlAsSubscription(str) - return 0 - } - val config = if (str.startsWith(EConfigType.VMESS.protocolScheme)) { VmessFmt.parseVmess(str) } else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) { @@ -259,21 +252,20 @@ object AngConfigManager { return 0 } - /** * share config */ private fun shareConfig(guid: String): String { try { val config = MmkvManager.decodeServerConfig(guid) ?: return "" - + return config.configType.protocolScheme + when (config.configType) { EConfigType.VMESS -> VmessFmt.toUri(config) EConfigType.CUSTOM -> "" - EConfigType.SHADOWSOCKS -> ShadowsocksFmt.toUri(config) + EConfigType.SHADOWSOCKS -> ShadowsocksFmt.toUri(config) EConfigType.SOCKS -> SocksFmt.toUri(config) - EConfigType.VLESS-> VlessFmt.toUri(config) - EConfigType.TROJAN-> TrojanFmt.toUri(config) + EConfigType.VLESS -> VlessFmt.toUri(config) + EConfigType.TROJAN -> TrojanFmt.toUri(config) EConfigType.WIREGUARD -> WireguardFmt.toUri(config) } } catch (e: Exception) { @@ -394,7 +386,44 @@ object AngConfigManager { // } // } - fun importBatchConfig(servers: String?, subid: String, append: Boolean): Int { + fun importBatchConfig(server: String?, subid: String, append: Boolean): Int { + var count = parseBatchConfig(server, subid, append) + if (count <= 0) { + count = parseBatchConfig(Utils.decode(server), subid, append) + } + if (count <= 0) { + count = parseCustomConfigServer(server, subid) + } + + if (parseBatchSubscription(server, subid) > 0) { + updateConfigViaSubAll() + return 1 + } + return count + } + + fun parseBatchSubscription(servers: String?, subid: String): Int { + try { + if (servers == null) { + return 0 + } + + var count = 0 + servers.lines() + .reversed() + .forEach { str -> + if (str.startsWith(AppConfig.PROTOCOL_HTTP) || str.startsWith(AppConfig.PROTOCOL_HTTPS)) { + count += MmkvManager.importUrlAsSubscription(str) + } + } + return count + } catch (e: Exception) { + e.printStackTrace() + } + return 0 + } + + fun parseBatchConfig(servers: String?, subid: String, append: Boolean): Int { try { if (servers == null) { return 0 @@ -415,16 +444,12 @@ object AngConfigManager { if (!append) { MmkvManager.removeServerViaSubid(subid) } -// var servers = server -// if (server.indexOf("vmess") >= 0 && server.indexOf("vmess") == server.lastIndexOf("vmess")) { -// servers = server.replace("\n", "") -// } var count = 0 servers.lines() .reversed() .forEach { - val resId = importConfig(it, subid, removedSelectedServer) + val resId = parseConfig(it, subid, removedSelectedServer) if (resId == 0) { count++ } @@ -436,7 +461,7 @@ object AngConfigManager { return 0 } - fun appendCustomConfigServer(server: String?, subid: String): Int { + fun parseCustomConfigServer(server: String?, subid: String): Int { if (server == null) { return 0 } @@ -493,4 +518,72 @@ object AngConfigManager { return 0 } } + + fun updateConfigViaSubAll(): Int { + var count = 0 + try { + MmkvManager.decodeSubscriptions().forEach { + count += updateConfigViaSub(it) + } + } catch (e: Exception) { + e.printStackTrace() + return 0 + } + return count + } + + private fun updateConfigViaSub(it: Pair): Int { + try { + if (TextUtils.isEmpty(it.first) + || TextUtils.isEmpty(it.second.remarks) + || TextUtils.isEmpty(it.second.url) + ) { + return 0 + } + if (!it.second.enabled) { + return 0 + } + val url = Utils.idnToASCII(it.second.url) + if (!Utils.isValidUrl(url)) { + return 0 + } + Log.d(AppConfig.ANG_PACKAGE, url) + var configText = try { + Utils.getUrlContentWithCustomUserAgent(url) + } catch (e: Exception) { + e.printStackTrace() + "" + } + if (configText.isEmpty()) { + configText = try { + val httpPort = Utils.parseInt( + settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT), + AppConfig.PORT_HTTP.toInt() + ) + Utils.getUrlContentWithCustomUserAgent(url, httpPort) + } catch (e: Exception) { + e.printStackTrace() + "" + } + } + if (configText.isEmpty()) { + return 0 + } + return parseConfigViaSub(configText, it.first, false) + } catch (e: Exception) { + e.printStackTrace() + return 0 + } + } + + private fun parseConfigViaSub(server: String?, subid: String, append: Boolean): Int { + var count = parseBatchConfig(server, subid, append) + if (count <= 0) { + count = parseBatchConfig(Utils.decode(server), subid, append) + } + if (count <= 0) { + count = parseCustomConfigServer(server, subid) + } + return count + } } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SubViewModel.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SubViewModel.kt deleted file mode 100644 index 67ad1ee3c..000000000 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SubViewModel.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.v2ray.ang.viewmodel - -import android.app.Application -import android.text.TextUtils -import android.util.Log -import androidx.lifecycle.AndroidViewModel -import com.tencent.mmkv.MMKV -import com.v2ray.ang.AppConfig -import com.v2ray.ang.dto.SubscriptionItem -import com.v2ray.ang.util.AngConfigManager -import com.v2ray.ang.util.MmkvManager -import com.v2ray.ang.util.Utils -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers - -class SubViewModel(application: Application) : AndroidViewModel(application) { - private val settingsStorage by lazy { - MMKV.mmkvWithID( - MmkvManager.ID_SETTING, - MMKV.MULTI_PROCESS_MODE - ) - } - - private val tcpingTestScope by lazy { CoroutineScope(Dispatchers.IO) } - - fun updateConfigViaSubAll(): Int { - var count = 0 - try { - MmkvManager.decodeSubscriptions().forEach { - count += updateConfigViaSub(it) - } - } catch (e: Exception) { - e.printStackTrace() - return 0 - } - return count - } - - fun updateConfigViaSub(it: Pair): Int { - try { - if (TextUtils.isEmpty(it.first) - || TextUtils.isEmpty(it.second.remarks) - || TextUtils.isEmpty(it.second.url) - ) { - return 0 - } - if (!it.second.enabled) { - return 0 - } - val url = Utils.idnToASCII(it.second.url) - if (!Utils.isValidUrl(url)) { - return 0 - } - Log.d(AppConfig.ANG_PACKAGE, url) - var configText = try { - Utils.getUrlContentWithCustomUserAgent(url) - } catch (e: Exception) { - e.printStackTrace() - "" - } - if (configText.isEmpty()) { - configText = try { - val httpPort = Utils.parseInt( - settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT), - AppConfig.PORT_HTTP.toInt() - ) - Utils.getUrlContentWithCustomUserAgent(url, httpPort) - } catch (e: Exception) { - e.printStackTrace() - "" - } - } - if (configText.isEmpty()) { - return 0 - } - return importBatchConfig(configText, it.first, false) - } catch (e: Exception) { - e.printStackTrace() - return 0 - } - } - - fun importBatchConfig(server: String?, subid: String = "", append: Boolean): Int { - var count = AngConfigManager.importBatchConfig(server, subid, append) - if (count <= 0) { - count = AngConfigManager.importBatchConfig(Utils.decode(server), subid, append) - } - if (count <= 0) { - count = AngConfigManager.appendCustomConfigServer(server, subid) - } - return count - } -}