mirror of
https://github.com/2dust/v2rayNG.git
synced 2025-06-28 12:19:52 +00:00
Using AI to improve function documentation
This commit is contained in:
parent
899e4c1b14
commit
ef4145787b
6 changed files with 508 additions and 20 deletions
|
@ -23,8 +23,15 @@ import com.v2ray.ang.util.Utils
|
|||
import java.net.URI
|
||||
|
||||
object AngConfigManager {
|
||||
|
||||
/**
|
||||
* parse config form qrcode or...
|
||||
* Parses the configuration from a QR code or string.
|
||||
*
|
||||
* @param str The configuration string.
|
||||
* @param subid The subscription ID.
|
||||
* @param subItem The subscription item.
|
||||
* @param removedSelectedServer The removed selected server.
|
||||
* @return The result code.
|
||||
*/
|
||||
private fun parseConfig(
|
||||
str: String?,
|
||||
|
@ -80,7 +87,10 @@ object AngConfigManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* share config
|
||||
* Shares the configuration.
|
||||
*
|
||||
* @param guid The GUID of the configuration.
|
||||
* @return The configuration string.
|
||||
*/
|
||||
private fun shareConfig(guid: String): String {
|
||||
try {
|
||||
|
@ -104,7 +114,11 @@ object AngConfigManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* share2Clipboard
|
||||
* Shares the configuration to the clipboard.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param guid The GUID of the configuration.
|
||||
* @return The result code.
|
||||
*/
|
||||
fun share2Clipboard(context: Context, guid: String): Int {
|
||||
try {
|
||||
|
@ -123,7 +137,11 @@ object AngConfigManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* share2Clipboard
|
||||
* Shares non-custom configurations to the clipboard.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param serverList The list of server GUIDs.
|
||||
* @return The number of configurations shared.
|
||||
*/
|
||||
fun shareNonCustomConfigsToClipboard(context: Context, serverList: List<String>): Int {
|
||||
try {
|
||||
|
@ -147,7 +165,10 @@ object AngConfigManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* share2QRCode
|
||||
* Shares the configuration as a QR code.
|
||||
*
|
||||
* @param guid The GUID of the configuration.
|
||||
* @return The QR code bitmap.
|
||||
*/
|
||||
fun share2QRCode(guid: String): Bitmap? {
|
||||
try {
|
||||
|
@ -164,7 +185,11 @@ object AngConfigManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* shareFullContent2Clipboard
|
||||
* Shares the full content of the configuration to the clipboard.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param guid The GUID of the configuration.
|
||||
* @return The result code.
|
||||
*/
|
||||
fun shareFullContent2Clipboard(context: Context, guid: String?): Int {
|
||||
try {
|
||||
|
@ -189,6 +214,14 @@ object AngConfigManager {
|
|||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a batch of configurations.
|
||||
*
|
||||
* @param server The server string.
|
||||
* @param subid The subscription ID.
|
||||
* @param append Whether to append the configurations.
|
||||
* @return A pair containing the number of configurations and subscriptions imported.
|
||||
*/
|
||||
fun importBatchConfig(server: String?, subid: String, append: Boolean): Pair<Int, Int> {
|
||||
var count = parseBatchConfig(Utils.decode(server), subid, append)
|
||||
if (count <= 0) {
|
||||
|
@ -209,6 +242,12 @@ object AngConfigManager {
|
|||
return count to countSub
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a batch of subscriptions.
|
||||
*
|
||||
* @param servers The servers string.
|
||||
* @return The number of subscriptions parsed.
|
||||
*/
|
||||
fun parseBatchSubscription(servers: String?): Int {
|
||||
try {
|
||||
if (servers == null) {
|
||||
|
@ -230,6 +269,14 @@ object AngConfigManager {
|
|||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a batch of configurations.
|
||||
*
|
||||
* @param servers The servers string.
|
||||
* @param subid The subscription ID.
|
||||
* @param append Whether to append the configurations.
|
||||
* @return The number of configurations parsed.
|
||||
*/
|
||||
fun parseBatchConfig(servers: String?, subid: String, append: Boolean): Int {
|
||||
try {
|
||||
if (servers == null) {
|
||||
|
@ -270,6 +317,13 @@ object AngConfigManager {
|
|||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a custom configuration server.
|
||||
*
|
||||
* @param server The server string.
|
||||
* @param subid The subscription ID.
|
||||
* @return The number of configurations parsed.
|
||||
*/
|
||||
fun parseCustomConfigServer(server: String?, subid: String): Int {
|
||||
if (server == null) {
|
||||
return 0
|
||||
|
@ -323,6 +377,11 @@ object AngConfigManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the configuration via all subscriptions.
|
||||
*
|
||||
* @return The number of configurations updated.
|
||||
*/
|
||||
fun updateConfigViaSubAll(): Int {
|
||||
var count = 0
|
||||
try {
|
||||
|
@ -336,6 +395,12 @@ object AngConfigManager {
|
|||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the configuration via a subscription.
|
||||
*
|
||||
* @param it The subscription item.
|
||||
* @return The number of configurations updated.
|
||||
*/
|
||||
fun updateConfigViaSub(it: Pair<String, SubscriptionItem>): Int {
|
||||
try {
|
||||
if (TextUtils.isEmpty(it.first)
|
||||
|
@ -379,6 +444,14 @@ object AngConfigManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the configuration via a subscription.
|
||||
*
|
||||
* @param server The server string.
|
||||
* @param subid The subscription ID.
|
||||
* @param append Whether to append the configurations.
|
||||
* @return The number of configurations parsed.
|
||||
*/
|
||||
private fun parseConfigViaSub(server: String?, subid: String, append: Boolean): Int {
|
||||
var count = parseBatchConfig(Utils.decode(server), subid, append)
|
||||
if (count <= 0) {
|
||||
|
@ -390,6 +463,12 @@ object AngConfigManager {
|
|||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a URL as a subscription.
|
||||
*
|
||||
* @param url The URL.
|
||||
* @return The number of subscriptions imported.
|
||||
*/
|
||||
private fun importUrlAsSubscription(url: String): Int {
|
||||
val subscriptions = MmkvManager.decodeSubscriptions()
|
||||
subscriptions.forEach {
|
||||
|
|
|
@ -16,6 +16,11 @@ object MigrateManager {
|
|||
private const val ID_SERVER_CONFIG = "SERVER_CONFIG"
|
||||
private val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) }
|
||||
|
||||
/**
|
||||
* Migrates server configurations to profile items.
|
||||
*
|
||||
* @return True if migration was successful, false otherwise.
|
||||
*/
|
||||
fun migrateServerConfig2Profile(): Boolean {
|
||||
if (serverStorage.count().toInt() == 0) {
|
||||
return false
|
||||
|
@ -44,6 +49,12 @@ object MigrateManager {
|
|||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrateServerConfig2ProfileSub(configOld: ServerConfig): ProfileItem? {
|
||||
return when (configOld.getProxyOutbound()?.protocol) {
|
||||
EConfigType.VMESS.name.lowercase() -> migrate2ProfileCommon(configOld)
|
||||
|
@ -62,6 +73,12 @@ object MigrateManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a common server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrate2ProfileCommon(configOld: ServerConfig): ProfileItem? {
|
||||
val config = ProfileItem.create(configOld.configType)
|
||||
|
||||
|
@ -101,6 +118,12 @@ object MigrateManager {
|
|||
return config
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a SOCKS server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrate2ProfileSocks(configOld: ServerConfig): ProfileItem? {
|
||||
val config = ProfileItem.create(EConfigType.SOCKS)
|
||||
|
||||
|
@ -114,6 +137,12 @@ object MigrateManager {
|
|||
return config
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates an HTTP server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrate2ProfileHttp(configOld: ServerConfig): ProfileItem? {
|
||||
val config = ProfileItem.create(EConfigType.HTTP)
|
||||
|
||||
|
@ -127,6 +156,12 @@ object MigrateManager {
|
|||
return config
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a WireGuard server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrate2ProfileWireguard(configOld: ServerConfig): ProfileItem? {
|
||||
val config = ProfileItem.create(EConfigType.WIREGUARD)
|
||||
|
||||
|
@ -145,6 +180,12 @@ object MigrateManager {
|
|||
return config
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a Hysteria2 server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrate2ProfileHysteria2(configOld: ServerConfig): ProfileItem? {
|
||||
val config = ProfileItem.create(EConfigType.HYSTERIA2)
|
||||
|
||||
|
@ -166,6 +207,12 @@ object MigrateManager {
|
|||
return config
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a custom server configuration to a profile item.
|
||||
*
|
||||
* @param configOld The old server configuration.
|
||||
* @return The profile item.
|
||||
*/
|
||||
private fun migrate2ProfileCustom(configOld: ServerConfig): ProfileItem? {
|
||||
val config = ProfileItem.create(EConfigType.CUSTOM)
|
||||
|
||||
|
@ -177,7 +224,12 @@ object MigrateManager {
|
|||
return config
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes the old server configuration.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @return The old server configuration.
|
||||
*/
|
||||
private fun decodeServerConfigOld(guid: String): ServerConfig? {
|
||||
if (guid.isBlank()) {
|
||||
return null
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.v2ray.ang.handler
|
||||
|
||||
|
||||
import com.tencent.mmkv.MMKV
|
||||
import com.v2ray.ang.AppConfig.PREF_IS_BOOTED
|
||||
import com.v2ray.ang.AppConfig.PREF_ROUTING_RULESET
|
||||
|
@ -41,18 +40,38 @@ object MmkvManager {
|
|||
|
||||
//region Server
|
||||
|
||||
/**
|
||||
* Gets the selected server GUID.
|
||||
*
|
||||
* @return The selected server GUID.
|
||||
*/
|
||||
fun getSelectServer(): String? {
|
||||
return mainStorage.decodeString(KEY_SELECTED_SERVER)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected server GUID.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
*/
|
||||
fun setSelectServer(guid: String) {
|
||||
mainStorage.encode(KEY_SELECTED_SERVER, guid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the server list.
|
||||
*
|
||||
* @param serverList The list of server GUIDs.
|
||||
*/
|
||||
fun encodeServerList(serverList: MutableList<String>) {
|
||||
mainStorage.encode(KEY_ANG_CONFIGS, JsonUtil.toJson(serverList))
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the server list.
|
||||
*
|
||||
* @return The list of server GUIDs.
|
||||
*/
|
||||
fun decodeServerList(): MutableList<String> {
|
||||
val json = mainStorage.decodeString(KEY_ANG_CONFIGS)
|
||||
return if (json.isNullOrBlank()) {
|
||||
|
@ -62,7 +81,12 @@ object MmkvManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes the server configuration.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @return The server configuration.
|
||||
*/
|
||||
fun decodeServerConfig(guid: String): ProfileItem? {
|
||||
if (guid.isBlank()) {
|
||||
return null
|
||||
|
@ -85,6 +109,13 @@ object MmkvManager {
|
|||
// return JsonUtil.fromJson(json, ProfileLiteItem::class.java)
|
||||
// }
|
||||
|
||||
/**
|
||||
* Encodes the server configuration.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @param config The server configuration.
|
||||
* @return The server GUID.
|
||||
*/
|
||||
fun encodeServerConfig(guid: String, config: ProfileItem): String {
|
||||
val key = guid.ifBlank { Utils.getUuid() }
|
||||
profileFullStorage.encode(key, JsonUtil.toJson(config))
|
||||
|
@ -107,6 +138,11 @@ object MmkvManager {
|
|||
return key
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the server configuration.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
*/
|
||||
fun removeServer(guid: String) {
|
||||
if (guid.isBlank()) {
|
||||
return
|
||||
|
@ -122,6 +158,11 @@ object MmkvManager {
|
|||
serverAffStorage.remove(guid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the server configurations via subscription ID.
|
||||
*
|
||||
* @param subid The subscription ID.
|
||||
*/
|
||||
fun removeServerViaSubid(subid: String) {
|
||||
if (subid.isBlank()) {
|
||||
return
|
||||
|
@ -135,6 +176,12 @@ object MmkvManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the server affiliation information.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @return The server affiliation information.
|
||||
*/
|
||||
fun decodeServerAffiliationInfo(guid: String): ServerAffiliationInfo? {
|
||||
if (guid.isBlank()) {
|
||||
return null
|
||||
|
@ -146,6 +193,12 @@ object MmkvManager {
|
|||
return JsonUtil.fromJson(json, ServerAffiliationInfo::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the server test delay in milliseconds.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @param testResult The test delay in milliseconds.
|
||||
*/
|
||||
fun encodeServerTestDelayMillis(guid: String, testResult: Long) {
|
||||
if (guid.isBlank()) {
|
||||
return
|
||||
|
@ -155,6 +208,11 @@ object MmkvManager {
|
|||
serverAffStorage.encode(guid, JsonUtil.toJson(aff))
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all test delay results.
|
||||
*
|
||||
* @param keys The list of server GUIDs.
|
||||
*/
|
||||
fun clearAllTestDelayResults(keys: List<String>?) {
|
||||
keys?.forEach { key ->
|
||||
decodeServerAffiliationInfo(key)?.let { aff ->
|
||||
|
@ -164,6 +222,11 @@ object MmkvManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all server configurations.
|
||||
*
|
||||
* @return The number of server configurations removed.
|
||||
*/
|
||||
fun removeAllServer(): Int {
|
||||
val count = profileFullStorage.allKeys()?.count() ?: 0
|
||||
mainStorage.clearAll()
|
||||
|
@ -173,6 +236,12 @@ object MmkvManager {
|
|||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes invalid server configurations.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @return The number of server configurations removed.
|
||||
*/
|
||||
fun removeInvalidServer(guid: String): Int {
|
||||
var count = 0
|
||||
if (guid.isNotEmpty()) {
|
||||
|
@ -195,10 +264,22 @@ object MmkvManager {
|
|||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the raw server configuration.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @param config The raw server configuration.
|
||||
*/
|
||||
fun encodeServerRaw(guid: String, config: String) {
|
||||
serverRawStorage.encode(guid, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the raw server configuration.
|
||||
*
|
||||
* @param guid The server GUID.
|
||||
* @return The raw server configuration.
|
||||
*/
|
||||
fun decodeServerRaw(guid: String): String? {
|
||||
return serverRawStorage.decodeString(guid)
|
||||
}
|
||||
|
@ -207,6 +288,9 @@ object MmkvManager {
|
|||
|
||||
//region Subscriptions
|
||||
|
||||
/**
|
||||
* Initializes the subscription list.
|
||||
*/
|
||||
private fun initSubsList() {
|
||||
val subsList = decodeSubsList()
|
||||
if (subsList.isNotEmpty()) {
|
||||
|
@ -218,6 +302,11 @@ object MmkvManager {
|
|||
encodeSubsList(subsList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the subscriptions.
|
||||
*
|
||||
* @return The list of subscriptions.
|
||||
*/
|
||||
fun decodeSubscriptions(): List<Pair<String, SubscriptionItem>> {
|
||||
initSubsList()
|
||||
|
||||
|
@ -231,6 +320,11 @@ object MmkvManager {
|
|||
return subscriptions
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the subscription.
|
||||
*
|
||||
* @param subid The subscription ID.
|
||||
*/
|
||||
fun removeSubscription(subid: String) {
|
||||
subStorage.remove(subid)
|
||||
val subsList = decodeSubsList()
|
||||
|
@ -240,6 +334,12 @@ object MmkvManager {
|
|||
removeServerViaSubid(subid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the subscription.
|
||||
*
|
||||
* @param guid The subscription GUID.
|
||||
* @param subItem The subscription item.
|
||||
*/
|
||||
fun encodeSubscription(guid: String, subItem: SubscriptionItem) {
|
||||
val key = guid.ifBlank { Utils.getUuid() }
|
||||
subStorage.encode(key, JsonUtil.toJson(subItem))
|
||||
|
@ -251,15 +351,31 @@ object MmkvManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the subscription.
|
||||
*
|
||||
* @param subscriptionId The subscription ID.
|
||||
* @return The subscription item.
|
||||
*/
|
||||
fun decodeSubscription(subscriptionId: String): SubscriptionItem? {
|
||||
val json = subStorage.decodeString(subscriptionId) ?: return null
|
||||
return JsonUtil.fromJson(json, SubscriptionItem::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the subscription list.
|
||||
*
|
||||
* @param subsList The list of subscription IDs.
|
||||
*/
|
||||
fun encodeSubsList(subsList: MutableList<String>) {
|
||||
mainStorage.encode(KEY_SUB_IDS, JsonUtil.toJson(subsList))
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the subscription list.
|
||||
*
|
||||
* @return The list of subscription IDs.
|
||||
*/
|
||||
fun decodeSubsList(): MutableList<String> {
|
||||
val json = mainStorage.decodeString(KEY_SUB_IDS)
|
||||
return if (json.isNullOrBlank()) {
|
||||
|
@ -273,6 +389,11 @@ object MmkvManager {
|
|||
|
||||
//region Asset
|
||||
|
||||
/**
|
||||
* Decodes the asset URLs.
|
||||
*
|
||||
* @return The list of asset URLs.
|
||||
*/
|
||||
fun decodeAssetUrls(): List<Pair<String, AssetUrlItem>> {
|
||||
val assetUrlItems = mutableListOf<Pair<String, AssetUrlItem>>()
|
||||
assetStorage.allKeys()?.forEach { key ->
|
||||
|
@ -284,15 +405,32 @@ object MmkvManager {
|
|||
return assetUrlItems.sortedBy { (_, value) -> value.addedTime }
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the asset URL.
|
||||
*
|
||||
* @param assetid The asset ID.
|
||||
*/
|
||||
fun removeAssetUrl(assetid: String) {
|
||||
assetStorage.remove(assetid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the asset.
|
||||
*
|
||||
* @param assetid The asset ID.
|
||||
* @param assetItem The asset item.
|
||||
*/
|
||||
fun encodeAsset(assetid: String, assetItem: AssetUrlItem) {
|
||||
val key = assetid.ifBlank { Utils.getUuid() }
|
||||
assetStorage.encode(key, JsonUtil.toJson(assetItem))
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the asset.
|
||||
*
|
||||
* @param assetid The asset ID.
|
||||
* @return The asset item.
|
||||
*/
|
||||
fun decodeAsset(assetid: String): AssetUrlItem? {
|
||||
val json = assetStorage.decodeString(assetid) ?: return null
|
||||
return JsonUtil.fromJson(json, AssetUrlItem::class.java)
|
||||
|
@ -302,12 +440,22 @@ object MmkvManager {
|
|||
|
||||
//region Routing
|
||||
|
||||
/**
|
||||
* Decodes the routing rulesets.
|
||||
*
|
||||
* @return The list of routing rulesets.
|
||||
*/
|
||||
fun decodeRoutingRulesets(): MutableList<RulesetItem>? {
|
||||
val ruleset = settingsStorage.decodeString(PREF_ROUTING_RULESET)
|
||||
if (ruleset.isNullOrEmpty()) return null
|
||||
return JsonUtil.fromJson(ruleset, Array<RulesetItem>::class.java).toMutableList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the routing rulesets.
|
||||
*
|
||||
* @param rulesetList The list of routing rulesets.
|
||||
*/
|
||||
fun encodeRoutingRulesets(rulesetList: MutableList<RulesetItem>?) {
|
||||
if (rulesetList.isNullOrEmpty())
|
||||
encodeSettings(PREF_ROUTING_RULESET, "")
|
||||
|
@ -316,39 +464,99 @@ object MmkvManager {
|
|||
}
|
||||
|
||||
//endregion
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param value The settings value.
|
||||
* @return Whether the encoding was successful.
|
||||
*/
|
||||
fun encodeSettings(key: String, value: String?): Boolean {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param value The settings value.
|
||||
* @return Whether the encoding was successful.
|
||||
*/
|
||||
fun encodeSettings(key: String, value: Int): Boolean {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param value The settings value.
|
||||
* @return Whether the encoding was successful.
|
||||
*/
|
||||
fun encodeSettings(key: String, value: Boolean): Boolean {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param value The settings value.
|
||||
* @return Whether the encoding was successful.
|
||||
*/
|
||||
fun encodeSettings(key: String, value: MutableSet<String>): Boolean {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes the settings string.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsString(key: String): String? {
|
||||
return settingsStorage.decodeString(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings string.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param defaultValue The default value.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsString(key: String, defaultValue: String?): String? {
|
||||
return settingsStorage.decodeString(key, defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings boolean.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsBool(key: String): Boolean {
|
||||
return settingsStorage.decodeBool(key, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings boolean.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param defaultValue The default value.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsBool(key: String, defaultValue: Boolean): Boolean {
|
||||
return settingsStorage.decodeBool(key, defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings string set.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsStringSet(key: String): MutableSet<String>? {
|
||||
return settingsStorage.decodeStringSet(key)
|
||||
}
|
||||
|
@ -357,10 +565,20 @@ object MmkvManager {
|
|||
|
||||
//region Others
|
||||
|
||||
/**
|
||||
* Encodes the start on boot setting.
|
||||
*
|
||||
* @param startOnBoot Whether to start on boot.
|
||||
*/
|
||||
fun encodeStartOnBoot(startOnBoot: Boolean) {
|
||||
MmkvManager.encodeSettings(PREF_IS_BOOTED, startOnBoot)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the start on boot setting.
|
||||
*
|
||||
* @return Whether to start on boot.
|
||||
*/
|
||||
fun decodeStartOnBoot(): Boolean {
|
||||
return decodeSettingsBool(PREF_IS_BOOTED, false)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,10 @@ import java.util.Locale
|
|||
|
||||
object SettingsManager {
|
||||
|
||||
/**
|
||||
* Initialize routing rulesets.
|
||||
* @param context The application context.
|
||||
*/
|
||||
fun initRoutingRulesets(context: Context) {
|
||||
val exist = MmkvManager.decodeRoutingRulesets()
|
||||
if (exist.isNullOrEmpty()) {
|
||||
|
@ -35,6 +39,12 @@ object SettingsManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preset routing rulesets.
|
||||
* @param context The application context.
|
||||
* @param index The index of the routing type.
|
||||
* @return A mutable list of RulesetItem.
|
||||
*/
|
||||
private fun getPresetRoutingRulesets(context: Context, index: Int = 0): MutableList<RulesetItem>? {
|
||||
val fileName = RoutingType.fromIndex(index).fileName
|
||||
val assets = Utils.readTextFromAssets(context, fileName)
|
||||
|
@ -45,12 +55,21 @@ object SettingsManager {
|
|||
return JsonUtil.fromJson(assets, Array<RulesetItem>::class.java).toMutableList()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset routing rulesets from presets.
|
||||
* @param context The application context.
|
||||
* @param index The index of the routing type.
|
||||
*/
|
||||
fun resetRoutingRulesetsFromPresets(context: Context, index: Int) {
|
||||
val rulesetList = getPresetRoutingRulesets(context, index) ?: return
|
||||
resetRoutingRulesetsCommon(rulesetList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset routing rulesets.
|
||||
* @param content The content of the rulesets.
|
||||
* @return True if successful, false otherwise.
|
||||
*/
|
||||
fun resetRoutingRulesets(content: String?): Boolean {
|
||||
if (content.isNullOrEmpty()) {
|
||||
return false
|
||||
|
@ -70,6 +89,10 @@ object SettingsManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common method to reset routing rulesets.
|
||||
* @param rulesetList The list of rulesets.
|
||||
*/
|
||||
private fun resetRoutingRulesetsCommon(rulesetList: MutableList<RulesetItem>) {
|
||||
val rulesetNew: MutableList<RulesetItem> = mutableListOf()
|
||||
MmkvManager.decodeRoutingRulesets()?.forEach { key ->
|
||||
|
@ -82,6 +105,11 @@ object SettingsManager {
|
|||
MmkvManager.encodeRoutingRulesets(rulesetNew)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a routing ruleset by index.
|
||||
* @param index The index of the ruleset.
|
||||
* @return The RulesetItem.
|
||||
*/
|
||||
fun getRoutingRuleset(index: Int): RulesetItem? {
|
||||
if (index < 0) return null
|
||||
|
||||
|
@ -91,6 +119,11 @@ object SettingsManager {
|
|||
return rulesetList[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a routing ruleset.
|
||||
* @param index The index of the ruleset.
|
||||
* @param ruleset The RulesetItem to save.
|
||||
*/
|
||||
fun saveRoutingRuleset(index: Int, ruleset: RulesetItem?) {
|
||||
if (ruleset == null) return
|
||||
|
||||
|
@ -107,6 +140,10 @@ object SettingsManager {
|
|||
MmkvManager.encodeRoutingRulesets(rulesetList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a routing ruleset by index.
|
||||
* @param index The index of the ruleset.
|
||||
*/
|
||||
fun removeRoutingRuleset(index: Int) {
|
||||
if (index < 0) return
|
||||
|
||||
|
@ -117,6 +154,10 @@ object SettingsManager {
|
|||
MmkvManager.encodeRoutingRulesets(rulesetList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if routing rulesets bypass LAN.
|
||||
* @return True if bypassing LAN, false otherwise.
|
||||
*/
|
||||
fun routingRulesetsBypassLan(): Boolean {
|
||||
val vpnBypassLan = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_BYPASS_LAN) ?: "0"
|
||||
if (vpnBypassLan == "1") {
|
||||
|
@ -125,7 +166,6 @@ object SettingsManager {
|
|||
return false
|
||||
}
|
||||
|
||||
//Follow config
|
||||
val guid = MmkvManager.getSelectServer() ?: return false
|
||||
val config = MmkvManager.decodeServerConfig(guid) ?: return false
|
||||
if (config.configType == EConfigType.CUSTOM) {
|
||||
|
@ -144,6 +184,11 @@ object SettingsManager {
|
|||
return exist == true
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap routing rulesets.
|
||||
* @param fromPosition The position to swap from.
|
||||
* @param toPosition The position to swap to.
|
||||
*/
|
||||
fun swapRoutingRuleset(fromPosition: Int, toPosition: Int) {
|
||||
val rulesetList = MmkvManager.decodeRoutingRulesets()
|
||||
if (rulesetList.isNullOrEmpty()) return
|
||||
|
@ -152,6 +197,11 @@ object SettingsManager {
|
|||
MmkvManager.encodeRoutingRulesets(rulesetList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap subscriptions.
|
||||
* @param fromPosition The position to swap from.
|
||||
* @param toPosition The position to swap to.
|
||||
*/
|
||||
fun swapSubscriptions(fromPosition: Int, toPosition: Int) {
|
||||
val subsList = MmkvManager.decodeSubsList()
|
||||
if (subsList.isNullOrEmpty()) return
|
||||
|
@ -160,6 +210,11 @@ object SettingsManager {
|
|||
MmkvManager.encodeSubsList(subsList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server via remarks.
|
||||
* @param remarks The remarks of the server.
|
||||
* @return The ProfileItem.
|
||||
*/
|
||||
fun getServerViaRemarks(remarks: String?): ProfileItem? {
|
||||
if (remarks == null) {
|
||||
return null
|
||||
|
@ -174,14 +229,27 @@ object SettingsManager {
|
|||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SOCKS port.
|
||||
* @return The SOCKS port.
|
||||
*/
|
||||
fun getSocksPort(): Int {
|
||||
return Utils.parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT), AppConfig.PORT_SOCKS.toInt())
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP port.
|
||||
* @return The HTTP port.
|
||||
*/
|
||||
fun getHttpPort(): Int {
|
||||
return getSocksPort() + (if (Utils.isXray()) 0 else 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize assets.
|
||||
* @param context The application context.
|
||||
* @param assets The AssetManager.
|
||||
*/
|
||||
fun initAssets(context: Context, assets: AssetManager) {
|
||||
val extFolder = Utils.userAssetPath(context)
|
||||
|
||||
|
@ -205,11 +273,11 @@ object SettingsManager {
|
|||
} catch (e: Exception) {
|
||||
Log.e(ANG_PACKAGE, "asset copy failed", e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get domestic dns servers from preference
|
||||
* Get domestic DNS servers from preference.
|
||||
* @return A list of domestic DNS servers.
|
||||
*/
|
||||
fun getDomesticDnsServers(): List<String> {
|
||||
val domesticDns =
|
||||
|
@ -222,7 +290,8 @@ object SettingsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* get remote dns servers from preference
|
||||
* Get remote DNS servers from preference.
|
||||
* @return A list of remote DNS servers.
|
||||
*/
|
||||
fun getRemoteDnsServers(): List<String> {
|
||||
val remoteDns =
|
||||
|
@ -235,15 +304,19 @@ object SettingsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* get vpn dns servers from preference
|
||||
* Get VPN DNS servers from preference.
|
||||
* @return A list of VPN DNS servers.
|
||||
*/
|
||||
fun getVpnDnsServers(): List<String> {
|
||||
val vpnDns = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_DNS) ?: AppConfig.DNS_VPN
|
||||
return vpnDns.split(",").filter { Utils.isPureIpAddress(it) }
|
||||
// allow empty, in that case dns will use system default
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get delay test URL.
|
||||
* @param second Whether to use the second URL.
|
||||
* @return The delay test URL.
|
||||
*/
|
||||
fun getDelayTestUrl(second: Boolean = false): String {
|
||||
return if (second) {
|
||||
AppConfig.DelayTestUrl2
|
||||
|
@ -253,6 +326,10 @@ object SettingsManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale.
|
||||
* @return The locale.
|
||||
*/
|
||||
fun getLocale(): Locale {
|
||||
val langCode =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_LANGUAGE) ?: Language.AUTO.code
|
||||
|
@ -271,6 +348,9 @@ object SettingsManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set night mode.
|
||||
*/
|
||||
fun setNightMode() {
|
||||
when (MmkvManager.decodeSettingsString(AppConfig.PREF_UI_MODE_NIGHT, "0")) {
|
||||
"0" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
|
|
|
@ -20,6 +20,13 @@ object SpeedtestManager {
|
|||
|
||||
private val tcpTestingSockets = ArrayList<Socket?>()
|
||||
|
||||
/**
|
||||
* Measures the TCP connection time to a given URL and port.
|
||||
*
|
||||
* @param url The URL to connect to.
|
||||
* @param port The port to connect to.
|
||||
* @return The connection time in milliseconds, or -1 if the connection failed.
|
||||
*/
|
||||
suspend fun tcping(url: String, port: Int): Long {
|
||||
var time = -1L
|
||||
for (k in 0 until 2) {
|
||||
|
@ -34,6 +41,12 @@ object SpeedtestManager {
|
|||
return time
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the real ping time using the V2Ray library.
|
||||
*
|
||||
* @param config The configuration string for the V2Ray library.
|
||||
* @return The ping time in milliseconds, or -1 if the ping failed.
|
||||
*/
|
||||
fun realPing(config: String): Long {
|
||||
return try {
|
||||
Libv2ray.measureOutboundDelay(config, SettingsManager.getDelayTestUrl())
|
||||
|
@ -43,6 +56,12 @@ object SpeedtestManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the ping time to a given URL using the system ping command.
|
||||
*
|
||||
* @param url The URL to ping.
|
||||
* @return The ping time in milliseconds as a string, or "-1ms" if the ping failed.
|
||||
*/
|
||||
fun ping(url: String): String {
|
||||
try {
|
||||
val command = "/system/bin/ping -c 3 $url"
|
||||
|
@ -62,6 +81,13 @@ object SpeedtestManager {
|
|||
return "-1ms"
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the time taken to establish a TCP connection to a given URL and port.
|
||||
*
|
||||
* @param url The URL to connect to.
|
||||
* @param port The port to connect to.
|
||||
* @return The connection time in milliseconds, or -1 if the connection failed.
|
||||
*/
|
||||
fun socketConnectTime(url: String, port: Int): Long {
|
||||
try {
|
||||
val socket = Socket()
|
||||
|
@ -86,6 +112,9 @@ object SpeedtestManager {
|
|||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all TCP sockets that are currently being tested.
|
||||
*/
|
||||
fun closeAllTcpSockets() {
|
||||
synchronized(this) {
|
||||
tcpTestingSockets.forEach {
|
||||
|
@ -95,6 +124,13 @@ object SpeedtestManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the connection to a given URL and port.
|
||||
*
|
||||
* @param context The Context in which the test is running.
|
||||
* @param port The port to connect to.
|
||||
* @return A pair containing the elapsed time in milliseconds and the result message.
|
||||
*/
|
||||
fun testConnection(context: Context, port: Int): Pair<Long, String> {
|
||||
var result: String
|
||||
var elapsed = -1L
|
||||
|
@ -116,11 +152,9 @@ object SpeedtestManager {
|
|||
)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
// network exception
|
||||
Log.d(AppConfig.ANG_PACKAGE, "testConnection IOException: " + Log.getStackTraceString(e))
|
||||
result = context.getString(R.string.connection_test_error, e.message)
|
||||
} catch (e: Exception) {
|
||||
// library exception, eg sumsung
|
||||
Log.d(AppConfig.ANG_PACKAGE, "testConnection Exception: " + Log.getStackTraceString(e))
|
||||
result = context.getString(R.string.connection_test_error, e.message)
|
||||
} finally {
|
||||
|
@ -130,6 +164,11 @@ object SpeedtestManager {
|
|||
return Pair(elapsed, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version of the V2Ray library.
|
||||
*
|
||||
* @return The version of the V2Ray library.
|
||||
*/
|
||||
fun getLibVersion(): String {
|
||||
return Libv2ray.checkVersionX()
|
||||
}
|
||||
|
|
|
@ -53,6 +53,13 @@ import com.v2ray.ang.util.Utils
|
|||
|
||||
object V2rayConfigManager {
|
||||
|
||||
/**
|
||||
* Retrieves the V2ray configuration for the given GUID.
|
||||
*
|
||||
* @param context The context of the caller.
|
||||
* @param guid The unique identifier for the V2ray configuration.
|
||||
* @return A ConfigResult object containing the configuration details or indicating failure.
|
||||
*/
|
||||
fun getV2rayConfig(context: Context, guid: String): ConfigResult {
|
||||
try {
|
||||
val config = MmkvManager.decodeServerConfig(guid) ?: return ConfigResult(false)
|
||||
|
@ -72,6 +79,13 @@ object V2rayConfigManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the non-custom V2ray configuration.
|
||||
*
|
||||
* @param context The context in which the function is called.
|
||||
* @param config The profile item containing the configuration details.
|
||||
* @return A ConfigResult object containing the result of the configuration retrieval.
|
||||
*/
|
||||
private fun getV2rayNonCustomConfig(context: Context, config: ProfileItem): ConfigResult {
|
||||
val result = ConfigResult(false)
|
||||
|
||||
|
@ -630,6 +644,12 @@ object V2rayConfigManager {
|
|||
return returnPair
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the proxy outbound configuration for the given profile item.
|
||||
*
|
||||
* @param profileItem The profile item for which to get the proxy outbound configuration.
|
||||
* @return The proxy outbound configuration as a V2rayConfig.OutboundBean, or null if not found.
|
||||
*/
|
||||
fun getProxyOutbound(profileItem: ProfileItem): V2rayConfig.OutboundBean? {
|
||||
return when (profileItem.configType) {
|
||||
EConfigType.VMESS -> VmessFmt.toOutbound(profileItem)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue