diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d6373d9..f785528 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,7 @@ + - for (it in list) { - if (it.id == DataStore.selectedProxy) { - ent = it - tag = t - break - } - } - } + val ent = SagerDatabase.proxyDao.getById(DataStore.selectedProxy) + val tag = data.proxy!!.config.profileTagMap[ent?.id] ?: "" if (tag.isNotBlank() && ent != null) { val success = data.proxy!!.box.selectOutbound(tag) Logs.d("selectOutbound $tag $success") runOnDefaultDispatcher { data.binder.broadcast { - it.stateChanged(-1, ent!!.displayName(), null) + it.stateChanged(-1, ent.displayName(), null) } } } diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/ProxyInstance.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/ProxyInstance.kt index d0b4a31..5ea5557 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/ProxyInstance.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/ProxyInstance.kt @@ -12,6 +12,7 @@ class ProxyInstance(profile: ProxyEntity, var service: BaseService.Interface? = BoxInstance(profile) { var lastSelectorGroupId = -1L + var notTmp = true // for TrafficLooper private var looper: TrafficLooper? = null @@ -20,12 +21,13 @@ class ProxyInstance(profile: ProxyEntity, var service: BaseService.Interface? = super.buildConfig() lastSelectorGroupId = super.config.selectorGroupId // - Logs.d(config.config) - if (BuildConfig.DEBUG) Logs.d(JavaUtil.gson.toJson(config.trafficMap)) + if (notTmp) Logs.d(config.config) + if (notTmp && BuildConfig.DEBUG) Logs.d(JavaUtil.gson.toJson(config.trafficMap)) } // only use this in temporary instance fun buildConfigTmp() { + notTmp = false buildConfig() } diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/TrafficLooper.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/TrafficLooper.kt index be4109d..69bca6c 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/TrafficLooper.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/TrafficLooper.kt @@ -5,6 +5,7 @@ import io.nekohasekai.sagernet.aidl.TrafficData import io.nekohasekai.sagernet.bg.BaseService import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.ProfileManager +import io.nekohasekai.sagernet.fmt.TAG_PROXY import io.nekohasekai.sagernet.ktx.Logs import kotlinx.coroutines.* import kotlin.time.DurationUnit @@ -55,6 +56,8 @@ class TrafficLooper var trafficUpdater: TrafficUpdater? = null var proxy: ProxyInstance? + + // for display var itemMain: TrafficUpdater.TrafficLooperData? = null var itemMainBase: TrafficUpdater.TrafficLooperData? = null var itemBypass: TrafficUpdater.TrafficLooperData? = null @@ -77,7 +80,7 @@ class TrafficLooper rx = ent.rx, tx = ent.tx, ) - if (ent.id == proxy.config.mainEntId) { + if (proxy.config.selectorGroupId < 0L && ent.id == proxy.config.mainEntId) { itemMain = item itemMainBase = TrafficUpdater.TrafficLooperData( tag = tag, @@ -91,6 +94,10 @@ class TrafficLooper Logs.d("traffic count $tag to ${ent.id}") } } + if (proxy.config.selectorGroupId >= 0L) { + itemMain = TrafficUpdater.TrafficLooperData(tag = TAG_PROXY) + itemMainBase = TrafficUpdater.TrafficLooperData(tag = TAG_PROXY) + } // trafficUpdater = TrafficUpdater( box = proxy.box, items = items.values.toList() diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt index aa6800a..691a18a 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt @@ -5,6 +5,7 @@ import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.bg.VpnService import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.ProxyEntity +import io.nekohasekai.sagernet.database.ProxyEntity.Companion.TYPE_CHAIN import io.nekohasekai.sagernet.database.ProxyEntity.Companion.TYPE_CONFIG import io.nekohasekai.sagernet.database.SagerDatabase import io.nekohasekai.sagernet.fmt.ConfigBuildResult.IndexEntity @@ -53,6 +54,7 @@ class ConfigBuildResult( var externalIndex: List, var mainEntId: Long, var trafficMap: Map>, + var profileTagMap: Map, val alerts: List>, val selectorGroupId: Long, ) { @@ -85,6 +87,7 @@ fun buildConfig( listOf(), proxy.id, // mapOf(TAG_PROXY to listOf(proxy)), // + mapOf(proxy.id to TAG_PROXY), // listOf(), -1L ) @@ -92,6 +95,7 @@ fun buildConfig( } val trafficMap = HashMap>() + val tagMap = HashMap() val globalOutbounds = ArrayList() val group = SagerDatabase.groupDao.getById(proxy.groupId) var optionsToMerge = "" @@ -126,9 +130,9 @@ fun buildConfig( val extraRules = if (forTest) listOf() else SagerDatabase.rulesDao.enabledRules() val extraProxies = - (if (forTest) mapOf() else SagerDatabase.proxyDao.getEntities(extraRules.mapNotNull { rule -> + if (forTest) mapOf() else SagerDatabase.proxyDao.getEntities(extraRules.mapNotNull { rule -> rule.outbound.takeIf { it > 0 && it != proxy.id } - }.toHashSet().toList()).associate { it.id to it.resolveChain() }).toMutableMap() + }.toHashSet().toList()).associate { it.id to it } val buildSelector = !forTest && group?.isSelector == true val uidListDNSRemote = mutableListOf() val uidListDNSDirect = mutableListOf() @@ -261,8 +265,9 @@ fun buildConfig( // returns outbound tag fun buildChain( - chainId: Long, profileList: List + chainId: Long, entity: ProxyEntity ): String { + val profileList = entity.resolveChain() var currentOutbound = mutableMapOf() lateinit var pastOutbound: MutableMap lateinit var pastInboundTag: String @@ -337,7 +342,7 @@ fun buildConfig( // include g-xx & chain ent val mapList = mutableListOf(proxyEntity) - if (index == 0 && profileList.size > 1) mapList.add(proxy) // chain ent + if (index == 0 && entity.type == TYPE_CHAIN) mapList.add(proxy) // chain ent trafficMap[tagOut] = mapList // Chain outbound @@ -460,11 +465,10 @@ fun buildConfig( } // build outbounds - val tagMap = mutableMapOf() if (buildSelector) { val list = group?.id?.let { SagerDatabase.proxyDao.getByGroup(it) } list?.forEach { - tagMap[it.id] = buildChain(it.id, it.resolveChain()) + tagMap[it.id] = buildChain(it.id, it) } outbounds.add(0, Outbound_SelectorOptions().apply { type = "selector" @@ -473,11 +477,11 @@ fun buildConfig( outbounds = tagMap.values.toList() }.asMap()) } else { - buildChain(0, proxy.resolveChain()) + buildChain(0, proxy) } // build outbounds from route item - extraProxies.forEach { (key, entities) -> - tagMap[key] = buildChain(key, entities) + extraProxies.forEach { (key, p) -> + tagMap[key] = buildChain(key, p) } // apply user rules @@ -756,6 +760,7 @@ fun buildConfig( externalIndexMap, proxy.id, trafficMap, + tagMap, alerts, if (buildSelector) group!!.id else -1L ) diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt index 8f4f8e8..2b1f8f9 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt @@ -1,14 +1,19 @@ package io.nekohasekai.sagernet.ui +import android.Manifest.permission.POST_NOTIFICATIONS import android.annotation.SuppressLint import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri +import android.os.Build import android.os.Bundle import android.os.RemoteException import android.view.KeyEvent import android.view.MenuItem import android.widget.Toast import androidx.annotation.IdRes +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import androidx.preference.PreferenceDataStore import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -82,6 +87,17 @@ class MainActivity : ThemedActivity(), onNewIntent(intent) } + // sdk 33 notification + if (Build.VERSION.SDK_INT >= 33) { + val checkPermission = + ContextCompat.checkSelfPermission(this@MainActivity, POST_NOTIFICATIONS) + if (checkPermission != PackageManager.PERMISSION_GRANTED) { + //动态申请 + ActivityCompat.requestPermissions( + this@MainActivity, arrayOf(POST_NOTIFICATIONS), 0 + ) + } + } } override fun onNewIntent(intent: Intent) {