improve selector

This commit is contained in:
arm64v8a 2023-03-18 17:18:02 +09:00
parent bb51a38474
commit 1f04d35e94
6 changed files with 46 additions and 24 deletions

View File

@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"

View File

@ -149,23 +149,14 @@ class BaseService {
stopRunner(false, (this as Context).getString(R.string.profile_empty))
}
if (canReloadSelector()) {
var tag = ""
var ent: ProxyEntity? = null
data.proxy!!.config.trafficMap.forEach { (t, list) ->
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)
}
}
}

View File

@ -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()
}

View File

@ -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()

View File

@ -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<IndexEntity>,
var mainEntId: Long,
var trafficMap: Map<String, List<ProxyEntity>>,
var profileTagMap: Map<Long, String>,
val alerts: List<Pair<Int, String>>,
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<String, MutableList<ProxyEntity>>()
val tagMap = HashMap<Long, String>()
val globalOutbounds = ArrayList<Long>()
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<Int>()
val uidListDNSDirect = mutableListOf<Int>()
@ -261,8 +265,9 @@ fun buildConfig(
// returns outbound tag
fun buildChain(
chainId: Long, profileList: List<ProxyEntity>
chainId: Long, entity: ProxyEntity
): String {
val profileList = entity.resolveChain()
var currentOutbound = mutableMapOf<String, Any>()
lateinit var pastOutbound: MutableMap<String, Any>
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<Long, String>()
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
)

View File

@ -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<String>(POST_NOTIFICATIONS), 0
)
}
}
}
override fun onNewIntent(intent: Intent) {