From fa7da3be10d3f267d201ba3137627818d7acda4f Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 22 Sep 2024 14:30:27 +0800 Subject: [PATCH] Optimize Storage --- .../ang/ui/ServerCustomConfigActivity.kt | 5 +- .../com/v2ray/ang/ui/SubEditActivity.kt | 16 +-- .../kotlin/com/v2ray/ang/ui/TaskerActivity.kt | 2 +- .../com/v2ray/ang/ui/UserAssetActivity.kt | 4 +- .../com/v2ray/ang/ui/UserAssetUrlActivity.kt | 17 +-- .../com/v2ray/ang/util/AngConfigManager.kt | 40 +------ .../kotlin/com/v2ray/ang/util/MmkvManager.kt | 107 +++++++++++------- .../com/v2ray/ang/util/SettingsManager.kt | 19 +++- .../com/v2ray/ang/util/V2rayConfigUtil.kt | 6 +- .../com/v2ray/ang/viewmodel/MainViewModel.kt | 2 +- 10 files changed, 104 insertions(+), 114 deletions(-) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt index 4ef16bb6..4dba5343 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt @@ -16,7 +16,6 @@ import com.v2ray.ang.dto.ServerConfig import com.v2ray.ang.dto.V2rayConfig import com.v2ray.ang.extension.toast import com.v2ray.ang.util.MmkvManager -import com.v2ray.ang.util.MmkvManager.serverRawStorage import com.v2ray.ang.util.Utils import me.drakeet.support.toast.ToastCompat @@ -52,7 +51,7 @@ class ServerCustomConfigActivity : BaseActivity() { */ private fun bindingServer(config: ServerConfig): Boolean { binding.etRemarks.text = Utils.getEditable(config.remarks) - val raw = serverRawStorage?.decodeString(editGuid) + val raw = MmkvManager.decodeServerRaw(editGuid) if (raw.isNullOrBlank()) { binding.editor.setTextContent(Utils.getEditable(config.fullConfig?.toPrettyPrinting().orEmpty())) } else { @@ -91,7 +90,7 @@ class ServerCustomConfigActivity : BaseActivity() { config.fullConfig = v2rayConfig MmkvManager.encodeServerConfig(editGuid, config) - serverRawStorage?.encode(editGuid, binding.editor.text.toString()) + MmkvManager.encodeServerRaw(editGuid, binding.editor.text.toString()) toast(R.string.toast_success) finish() return true diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt index 8c5fbb13..76a43330 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt @@ -6,13 +6,11 @@ import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope -import com.google.gson.Gson import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivitySubEditBinding import com.v2ray.ang.dto.SubscriptionItem import com.v2ray.ang.extension.toast import com.v2ray.ang.util.MmkvManager -import com.v2ray.ang.util.MmkvManager.subStorage import com.v2ray.ang.util.Utils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -30,9 +28,9 @@ class SubEditActivity : BaseActivity() { setContentView(binding.root) title = getString(R.string.title_sub_setting) - val json = subStorage?.decodeString(editSubId) - if (!json.isNullOrBlank()) { - bindingServer(Gson().fromJson(json, SubscriptionItem::class.java)) + val subItem = MmkvManager.decodeSubscription(editSubId) + if (subItem != null) { + bindingServer(subItem) } else { clearServer() } @@ -67,13 +65,7 @@ class SubEditActivity : BaseActivity() { * save server config */ private fun saveServer(): Boolean { - val subItem: SubscriptionItem - val json = subStorage?.decodeString(editSubId) - if (!json.isNullOrBlank()) { - subItem = Gson().fromJson(json, SubscriptionItem::class.java) - } else { - subItem = SubscriptionItem() - } + val subItem = MmkvManager.decodeSubscription(editSubId)?:SubscriptionItem() subItem.remarks = binding.etRemarks.text.toString() subItem.url = binding.etUrl.text.toString() diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt index 3c8b0f1d..9e660ff8 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt @@ -28,7 +28,7 @@ class TaskerActivity : BaseActivity() { lstData.add("Default") lstGuid.add(AppConfig.TASKER_DEFAULT_GUID) - MmkvManager.serverStorage?.allKeys()?.forEach { key -> + MmkvManager.decodeServerList()?.forEach { key -> MmkvManager.decodeServerConfig(key)?.let { config -> lstData.add(config.remarks) lstGuid.add(key) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt index be5e4052..3cfa7c4e 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt @@ -19,7 +19,6 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.google.gson.Gson import com.tbruyelle.rxpermissions3.RxPermissions import com.v2ray.ang.AppConfig import com.v2ray.ang.R @@ -30,7 +29,6 @@ import com.v2ray.ang.dto.AssetUrlItem import com.v2ray.ang.extension.toTrafficString import com.v2ray.ang.extension.toast import com.v2ray.ang.util.MmkvManager -import com.v2ray.ang.util.MmkvManager.assetStorage import com.v2ray.ang.util.MmkvManager.settingsStorage import com.v2ray.ang.util.Utils import kotlinx.coroutines.Dispatchers @@ -137,7 +135,7 @@ class UserAssetActivity : BaseActivity() { toast(R.string.msg_remark_is_duplicate) return@registerForActivityResult } - assetStorage?.encode(assetId, Gson().toJson(assetItem)) + MmkvManager.encodeAsset(assetId, assetItem) copyFile(uri) } catch (e: Exception) { toast(R.string.toast_asset_copy_failed) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetUrlActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetUrlActivity.kt index 83603a15..5db6b1df 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetUrlActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetUrlActivity.kt @@ -5,13 +5,11 @@ import android.text.TextUtils import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AlertDialog -import com.google.gson.Gson import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivityUserAssetUrlBinding import com.v2ray.ang.dto.AssetUrlItem import com.v2ray.ang.extension.toast import com.v2ray.ang.util.MmkvManager -import com.v2ray.ang.util.MmkvManager.assetStorage import com.v2ray.ang.util.Utils import java.io.File @@ -29,9 +27,9 @@ class UserAssetUrlActivity : BaseActivity() { setContentView(binding.root) title = getString(R.string.title_user_asset_add_url) - val json = assetStorage?.decodeString(editAssetId) - if (!json.isNullOrBlank()) { - bindingAsset(Gson().fromJson(json, AssetUrlItem::class.java)) + val assetItem = MmkvManager.decodeAsset(editAssetId) + if (assetItem != null) { + bindingAsset(assetItem) } else { clearAsset() } @@ -59,12 +57,9 @@ class UserAssetUrlActivity : BaseActivity() { * save asset config */ private fun saveServer(): Boolean { - val assetItem: AssetUrlItem - val json = assetStorage?.decodeString(editAssetId) + var assetItem = MmkvManager.decodeAsset(editAssetId) var assetId = editAssetId - if (!json.isNullOrBlank()) { - assetItem = Gson().fromJson(json, AssetUrlItem::class.java) - + if (assetItem != null) { // remove file associated with the asset val file = extDir.resolve(assetItem.remarks) if (file.exists()) { @@ -95,7 +90,7 @@ class UserAssetUrlActivity : BaseActivity() { return false } - assetStorage?.encode(assetId, Gson().toJson(assetItem)) + MmkvManager.encodeAsset(assetId, assetItem) toast(R.string.toast_success) finish() return 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 5301df10..f937b4cc 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 @@ -13,7 +13,6 @@ import com.google.gson.reflect.TypeToken import com.v2ray.ang.AppConfig import com.v2ray.ang.R import com.v2ray.ang.dto.* -import com.v2ray.ang.util.MmkvManager.serverRawStorage import com.v2ray.ang.util.MmkvManager.settingsStorage import com.v2ray.ang.util.fmt.ShadowsocksFmt import com.v2ray.ang.util.fmt.SocksFmt @@ -178,39 +177,6 @@ object AngConfigManager { return 0 } -// /** -// * upgrade -// */ -// private fun upgradeServerVersion(vmess: AngConfig.VmessBean): Int { -// try { -// if (vmess.configVersion == 2) { -// return 0 -// } -// -// when (vmess.network) { -// "ws", "h2" -> { -// var path = "" -// var host = "" -// val lstParameter = vmess.requestHost.split(";") -// if (lstParameter.isNotEmpty()) { -// path = lstParameter[0].trim() -// } -// if (lstParameter.size > 1) { -// path = lstParameter[0].trim() -// host = lstParameter[1].trim() -// } -// vmess.path = path -// vmess.requestHost = host -// } -// } -// vmess.configVersion = 2 -// return 0 -// } catch (e: Exception) { -// e.printStackTrace() -// return -1 -// } -// } - fun importBatchConfig(server: String?, subid: String, append: Boolean): Pair { var count = parseBatchConfig(Utils.decode(server), subid, append) if (count <= 0) { @@ -325,7 +291,7 @@ object AngConfigManager { .toString()) config.subscriptionId = subid val key = MmkvManager.encodeServerConfig("", config) - serverRawStorage?.encode(key, gson.toJson(srv)) + MmkvManager.encodeServerRaw(key, gson.toJson(srv)) count += 1 } return count @@ -340,14 +306,14 @@ object AngConfigManager { config.fullConfig = Gson().fromJson(server, V2rayConfig::class.java) config.remarks = config.fullConfig?.remarks ?: System.currentTimeMillis().toString() val key = MmkvManager.encodeServerConfig("", config) - serverRawStorage?.encode(key, server) + MmkvManager.encodeServerRaw(key, server) return 1 } else if (server.startsWith("[Interface]") && server.contains("[Peer]")) { val config = WireguardFmt.parseWireguardConfFile(server) ?: return R.string.toast_incorrect_protocol config.fullConfig?.remarks ?: System.currentTimeMillis().toString() val key = MmkvManager.encodeServerConfig("", config) - serverRawStorage?.encode(key, server) + MmkvManager.encodeServerRaw(key, server) return 1 } else { return 0 diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt index b634d87f..1eae4ebf 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt @@ -11,6 +11,9 @@ import com.v2ray.ang.dto.ServerConfig import com.v2ray.ang.dto.SubscriptionItem object MmkvManager { + + //region private + private const val ID_MAIN = "MAIN" private const val ID_SERVER_CONFIG = "SERVER_CONFIG" private const val ID_PROFILE_CONFIG = "PROFILE_CONFIG" @@ -25,12 +28,16 @@ object MmkvManager { private val mainStorage by lazy { MMKV.mmkvWithID(ID_MAIN, MMKV.MULTI_PROCESS_MODE) } val settingsStorage by lazy { MMKV.mmkvWithID(ID_SETTING, MMKV.MULTI_PROCESS_MODE) } - val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) } + private val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) } private val profileStorage by lazy { MMKV.mmkvWithID(ID_PROFILE_CONFIG, MMKV.MULTI_PROCESS_MODE) } private val serverAffStorage by lazy { MMKV.mmkvWithID(ID_SERVER_AFF, MMKV.MULTI_PROCESS_MODE) } - val subStorage by lazy { MMKV.mmkvWithID(ID_SUB, MMKV.MULTI_PROCESS_MODE) } - val assetStorage by lazy { MMKV.mmkvWithID(ID_ASSET, MMKV.MULTI_PROCESS_MODE) } - val serverRawStorage by lazy { MMKV.mmkvWithID(ID_SERVER_RAW, MMKV.MULTI_PROCESS_MODE) } + private val subStorage by lazy { MMKV.mmkvWithID(ID_SUB, MMKV.MULTI_PROCESS_MODE) } + private val assetStorage by lazy { MMKV.mmkvWithID(ID_ASSET, MMKV.MULTI_PROCESS_MODE) } + private val serverRawStorage by lazy { MMKV.mmkvWithID(ID_SERVER_RAW, MMKV.MULTI_PROCESS_MODE) } + + //endregion + + //region Server fun getSelectServer(): String? { return mainStorage.decodeString(KEY_SELECTED_SERVER) @@ -82,7 +89,7 @@ object MmkvManager { if (!serverList.contains(key)) { serverList.add(0, key) encodeServerList(serverList) - if (MmkvManager.getSelectServer().isNullOrBlank()) { + if (getSelectServer().isNullOrBlank()) { mainStorage.encode(KEY_SELECTED_SERVER, key) } } @@ -101,7 +108,7 @@ object MmkvManager { if (guid.isBlank()) { return } - if (MmkvManager.getSelectServer() == guid) { + if (getSelectServer() == guid) { mainStorage.remove(KEY_SELECTED_SERVER) } val serverList = decodeServerList() @@ -154,7 +161,44 @@ object MmkvManager { } } - fun initSubsList() { + fun removeAllServer() { + mainStorage.clearAll() + serverStorage.clearAll() + profileStorage.clearAll() + serverAffStorage.clearAll() + } + + fun removeInvalidServer(guid: String) { + if (guid.isNotEmpty()) { + decodeServerAffiliationInfo(guid)?.let { aff -> + if (aff.testDelayMillis < 0L) { + removeServer(guid) + } + } + } else { + serverAffStorage.allKeys()?.forEach { key -> + decodeServerAffiliationInfo(key)?.let { aff -> + if (aff.testDelayMillis < 0L) { + removeServer(key) + } + } + } + } + } + + fun encodeServerRaw(guid: String, config: String) { + serverRawStorage.encode(guid, config) + } + + fun decodeServerRaw(guid: String): String? { + return serverRawStorage.decodeString(guid) ?: return null + } + + //endregion + + //region Subscriptions + + private fun initSubsList() { val subsList = decodeSubsList() if (subsList.isNotEmpty()) { return @@ -216,6 +260,10 @@ object MmkvManager { } } + //endregion + + //region Asset + fun decodeAssetUrls(): List> { val assetUrlItems = mutableListOf>() assetStorage.allKeys()?.forEach { key -> @@ -231,44 +279,19 @@ object MmkvManager { assetStorage.remove(assetid) } - fun removeAllServer() { - mainStorage.clearAll() - serverStorage.clearAll() - profileStorage.clearAll() - serverAffStorage.clearAll() + fun encodeAsset(assetid: String, assetItem: AssetUrlItem) { + val key = assetid.ifBlank { Utils.getUuid() } + assetStorage.encode(key, Gson().toJson(assetItem)) } - fun removeInvalidServer(guid: String) { - if (guid.isNotEmpty()) { - decodeServerAffiliationInfo(guid)?.let { aff -> - if (aff.testDelayMillis < 0L) { - removeServer(guid) - } - } - } else { - serverAffStorage.allKeys()?.forEach { key -> - decodeServerAffiliationInfo(key)?.let { aff -> - if (aff.testDelayMillis < 0L) { - removeServer(key) - } - } - } - } + fun decodeAsset(assetid: String): AssetUrlItem? { + val json = assetStorage.decodeString(assetid) ?: return null + return Gson().fromJson(json, AssetUrlItem::class.java) } - fun getServerViaRemarks(remarks: String?): ServerConfig? { - if (remarks == null) { - return null - } - val serverList = decodeServerList() - for (guid in serverList) { - val profile = decodeProfileConfig(guid) - if (profile != null && profile.remarks == remarks) { - return decodeServerConfig(guid) - } - } - return null - } + //endregion + + //region Routing fun decodeRoutingRulesets(): MutableList? { val ruleset = settingsStorage.decodeString(PREF_ROUTING_RULESET) @@ -282,4 +305,6 @@ object MmkvManager { else settingsStorage.encode(PREF_ROUTING_RULESET, Gson().toJson(rulesetList)) } + + //endregion } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/SettingsManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/SettingsManager.kt index de86e58e..be56c7f3 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/SettingsManager.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/SettingsManager.kt @@ -2,10 +2,12 @@ package com.v2ray.ang.util import android.content.Context import android.text.TextUtils -import android.util.Log import com.google.gson.Gson import com.v2ray.ang.dto.RulesetItem -import com.v2ray.ang.util.MmkvManager.subStorage +import com.v2ray.ang.dto.ServerConfig +import com.v2ray.ang.util.MmkvManager.decodeProfileConfig +import com.v2ray.ang.util.MmkvManager.decodeServerConfig +import com.v2ray.ang.util.MmkvManager.decodeServerList import java.util.Collections object SettingsManager { @@ -90,5 +92,18 @@ object SettingsManager { MmkvManager.encodeSubsList(subsList) } + fun getServerViaRemarks(remarks: String?): ServerConfig? { + if (remarks == null) { + return null + } + val serverList = decodeServerList() + for (guid in serverList) { + val profile = decodeProfileConfig(guid) + if (profile != null && profile.remarks == remarks) { + return decodeServerConfig(guid) + } + } + return null + } } 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 a3387874..7e1c030b 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 @@ -30,7 +30,7 @@ object V2rayConfigUtil { try { val config = MmkvManager.decodeServerConfig(guid) ?: return Result(false) if (config.configType == EConfigType.CUSTOM) { - val raw = MmkvManager.serverRawStorage?.decodeString(guid) + val raw = MmkvManager.decodeServerRaw(guid) val customConfig = if (raw.isNullOrBlank()) { config.fullConfig?.toPrettyPrinting() ?: return Result(false) } else { @@ -526,7 +526,7 @@ object V2rayConfigUtil { val outbound = v2rayConfig.outbounds[0] //Previous proxy - val prevNode = MmkvManager.getServerViaRemarks(subItem.prevProfile) + val prevNode = SettingsManager.getServerViaRemarks(subItem.prevProfile) if (prevNode != null) { val prevOutbound = prevNode.getProxyOutbound() if (prevOutbound != null) { @@ -542,7 +542,7 @@ object V2rayConfigUtil { } //Next proxy - val nextNode = MmkvManager.getServerViaRemarks(subItem.nextProfile) + val nextNode = SettingsManager.getServerViaRemarks(subItem.nextProfile) if (nextNode != null) { val nextOutbound = nextNode.getProxyOutbound() if (nextOutbound != null) { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt index fe9c692a..28705490 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -101,7 +101,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { config.fullConfig = Gson().fromJson(server, V2rayConfig::class.java) config.remarks = config.fullConfig?.remarks ?: System.currentTimeMillis().toString() val key = MmkvManager.encodeServerConfig("", config) - MmkvManager.serverRawStorage?.encode(key, server) + MmkvManager.encodeServerRaw(key, server) serverList.add(0, key) val profile = ProfileItem( configType = config.configType,