mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-18 22:20:06 +08:00
feat: clash api selector callback
This commit is contained in:
parent
46526560d8
commit
dd648447eb
@ -9,4 +9,5 @@ oneway interface ISagerNetServiceCallback {
|
||||
void routeAlert(int type, String routeName);
|
||||
void cbSpeedUpdate(in SpeedDisplayData stats);
|
||||
void cbTrafficUpdate(in TrafficData stats);
|
||||
void cbSelectorUpdate(long id);
|
||||
}
|
||||
|
||||
@ -20,7 +20,9 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import go.Seq
|
||||
import io.nekohasekai.sagernet.bg.SagerConnection
|
||||
import io.nekohasekai.sagernet.bg.ServiceNotification
|
||||
import io.nekohasekai.sagernet.database.DataStore
|
||||
import io.nekohasekai.sagernet.database.SagerDatabase
|
||||
import io.nekohasekai.sagernet.ktx.Logs
|
||||
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
|
||||
import io.nekohasekai.sagernet.ui.MainActivity
|
||||
@ -266,4 +268,22 @@ class SagerNet : Application(),
|
||||
return DataStore.rulesProvider == 0
|
||||
}
|
||||
|
||||
override fun selector_OnProxySelected(tag: String) {
|
||||
DataStore.baseService?.apply {
|
||||
runOnDefaultDispatcher {
|
||||
val id = data.proxy!!.config.profileTagMap
|
||||
.filterValues { it == tag }.keys.firstOrNull() ?: -1
|
||||
val ent = SagerDatabase.proxyDao.getById(id) ?: return@runOnDefaultDispatcher
|
||||
// traffic & title
|
||||
data.proxy!!.looper?.selectMain(id)
|
||||
val title = ServiceNotification.genTitle(ent)
|
||||
data.notification?.postNotificationTitle(title)
|
||||
// post MainActivity animation
|
||||
data.binder.broadcast { b ->
|
||||
b.cbSelectorUpdate(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ class BaseService {
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
else -> service.stopRunner()
|
||||
}
|
||||
}
|
||||
@ -165,12 +166,10 @@ class BaseService {
|
||||
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)
|
||||
if (success) runOnDefaultDispatcher {
|
||||
data.proxy!!.looper?.selectMain(ent.id)
|
||||
val title = ServiceNotification.genTitle(ent)
|
||||
data.notification?.postNotificationTitle(title)
|
||||
}
|
||||
// select from GUI
|
||||
data.proxy!!.box.selectOutbound(tag)
|
||||
// or select from webui
|
||||
// => selector_OnProxySelected
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ class SagerConnection(
|
||||
|
||||
fun cbSpeedUpdate(stats: SpeedDisplayData) {}
|
||||
fun cbTrafficUpdate(data: TrafficData) {}
|
||||
fun cbSelectorUpdate(id: Long) {}
|
||||
|
||||
fun stateChanged(state: BaseService.State, profileName: String?, msg: String?)
|
||||
|
||||
@ -83,6 +84,13 @@ class SagerConnection(
|
||||
}
|
||||
}
|
||||
|
||||
override fun cbSelectorUpdate(id: Long) {
|
||||
val callback = callback ?: return
|
||||
runOnMainDispatcher {
|
||||
callback.cbSelectorUpdate(id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun missingPlugin(profileName: String, pluginName: String) {
|
||||
val callback = callback ?: return
|
||||
runOnMainDispatcher {
|
||||
|
||||
@ -9,6 +9,7 @@ import io.nekohasekai.sagernet.database.ProfileManager
|
||||
import io.nekohasekai.sagernet.fmt.TAG_BYPASS
|
||||
import io.nekohasekai.sagernet.fmt.TAG_PROXY
|
||||
import io.nekohasekai.sagernet.ktx.Logs
|
||||
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
class TrafficLooper
|
||||
@ -55,14 +56,22 @@ class TrafficLooper
|
||||
fun selectMain(id: Long) {
|
||||
Logs.d("select traffic count $TAG_PROXY to $id, old id is $selectorNowId")
|
||||
val oldData = items[selectorNowId]
|
||||
val data = items[id] ?: return
|
||||
val newData = items[id] ?: return
|
||||
oldData?.apply {
|
||||
tag = selectorNowFakeTag
|
||||
ignore = true
|
||||
// post traffic when switch
|
||||
data.proxy?.config?.trafficMap?.get(tag)?.firstOrNull()?.let {
|
||||
it.rx = rx
|
||||
it.tx = tx
|
||||
runOnDefaultDispatcher {
|
||||
ProfileManager.updateProfile(it) // update DB
|
||||
}
|
||||
}
|
||||
}
|
||||
selectorNowFakeTag = data.tag
|
||||
selectorNowFakeTag = newData.tag
|
||||
selectorNowId = id
|
||||
data.apply {
|
||||
newData.apply {
|
||||
tag = TAG_PROXY
|
||||
ignore = false
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ object ProfileManager {
|
||||
interface Listener {
|
||||
suspend fun onAdd(profile: ProxyEntity)
|
||||
suspend fun onUpdated(data: TrafficData)
|
||||
suspend fun onUpdated(profile: ProxyEntity)
|
||||
suspend fun onUpdated(profile: ProxyEntity, noTraffic: Boolean)
|
||||
suspend fun onRemoved(groupId: Long, profileId: Long)
|
||||
}
|
||||
|
||||
@ -87,13 +87,13 @@ object ProfileManager {
|
||||
|
||||
suspend fun updateProfile(profile: ProxyEntity) {
|
||||
SagerDatabase.proxyDao.updateProxy(profile)
|
||||
iterator { onUpdated(profile) }
|
||||
iterator { onUpdated(profile, false) }
|
||||
}
|
||||
|
||||
suspend fun updateProfile(profiles: List<ProxyEntity>) {
|
||||
SagerDatabase.proxyDao.updateProxy(profiles)
|
||||
profiles.forEach {
|
||||
iterator { onUpdated(it) }
|
||||
iterator { onUpdated(it, false) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,12 +141,12 @@ object ProfileManager {
|
||||
|
||||
// postUpdate: post to listeners, don't change the DB
|
||||
|
||||
suspend fun postUpdate(profileId: Long) {
|
||||
postUpdate(getProfile(profileId) ?: return)
|
||||
suspend fun postUpdate(profileId: Long, noTraffic: Boolean = false) {
|
||||
postUpdate(getProfile(profileId) ?: return, noTraffic)
|
||||
}
|
||||
|
||||
suspend fun postUpdate(profile: ProxyEntity) {
|
||||
iterator { onUpdated(profile) }
|
||||
suspend fun postUpdate(profile: ProxyEntity, noTraffic: Boolean = false) {
|
||||
iterator { onUpdated(profile, noTraffic) }
|
||||
}
|
||||
|
||||
suspend fun postUpdate(data: TrafficData) {
|
||||
|
||||
@ -293,6 +293,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
R.id.action_scan_qr_code -> {
|
||||
startActivity(Intent(context, ScannerActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_import_clipboard -> {
|
||||
val text = SagerNet.getClipboardText()
|
||||
if (text.isBlank()) {
|
||||
@ -314,56 +315,73 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_import_file -> {
|
||||
startFilesForResult(importFile, "*/*")
|
||||
}
|
||||
|
||||
R.id.action_new_socks -> {
|
||||
startActivity(Intent(requireActivity(), SocksSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_http -> {
|
||||
startActivity(Intent(requireActivity(), HttpSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_ss -> {
|
||||
startActivity(Intent(requireActivity(), ShadowsocksSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_vmess -> {
|
||||
startActivity(Intent(requireActivity(), VMessSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_vless -> {
|
||||
startActivity(Intent(requireActivity(), VMessSettingsActivity::class.java).apply {
|
||||
putExtra("vless", true)
|
||||
})
|
||||
}
|
||||
|
||||
R.id.action_new_trojan -> {
|
||||
startActivity(Intent(requireActivity(), TrojanSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_trojan_go -> {
|
||||
startActivity(Intent(requireActivity(), TrojanGoSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_naive -> {
|
||||
startActivity(Intent(requireActivity(), NaiveSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_hysteria -> {
|
||||
startActivity(Intent(requireActivity(), HysteriaSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_tuic -> {
|
||||
startActivity(Intent(requireActivity(), TuicSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_ssh -> {
|
||||
startActivity(Intent(requireActivity(), SSHSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_wg -> {
|
||||
startActivity(Intent(requireActivity(), WireGuardSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_shadowtls -> {
|
||||
startActivity(Intent(requireActivity(), ShadowTLSSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_config -> {
|
||||
startActivity(Intent(requireActivity(), ConfigSettingActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_chain -> {
|
||||
startActivity(Intent(requireActivity(), ChainSettingsActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.action_new_neko -> {
|
||||
val context = requireContext()
|
||||
lateinit var dialog: AlertDialog
|
||||
@ -395,6 +413,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
.setView(linearLayout)
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.action_clear_traffic_statistics -> {
|
||||
runOnDefaultDispatcher {
|
||||
val profiles = SagerDatabase.proxyDao.getByGroup(DataStore.currentGroupId())
|
||||
@ -411,6 +430,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_connection_test_clear_results -> {
|
||||
runOnDefaultDispatcher {
|
||||
val profiles = SagerDatabase.proxyDao.getByGroup(DataStore.currentGroupId())
|
||||
@ -428,6 +448,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_connection_test_delete_unavailable -> {
|
||||
runOnDefaultDispatcher {
|
||||
val profiles = SagerDatabase.proxyDao.getByGroup(DataStore.currentGroupId())
|
||||
@ -466,6 +487,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_remove_duplicate -> {
|
||||
runOnDefaultDispatcher {
|
||||
val profiles = SagerDatabase.proxyDao.getByGroup(DataStore.currentGroupId())
|
||||
@ -517,9 +539,11 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_connection_tcp_ping -> {
|
||||
pingTest(false)
|
||||
}
|
||||
|
||||
R.id.action_connection_url_test -> {
|
||||
urlTest()
|
||||
}
|
||||
@ -561,18 +585,22 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
profileStatusText = profile.error
|
||||
profileStatusColor = context.getColorAttr(android.R.attr.textColorSecondary)
|
||||
}
|
||||
|
||||
0 -> {
|
||||
profileStatusText = getString(R.string.connection_test_testing)
|
||||
profileStatusColor = context.getColorAttr(android.R.attr.textColorSecondary)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
profileStatusText = getString(R.string.available, profile.ping)
|
||||
profileStatusColor = context.getColour(R.color.material_green_500)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
profileStatusText = profile.error
|
||||
profileStatusColor = context.getColour(R.color.material_red_500)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
val err = profile.error ?: ""
|
||||
val msg = Protocols.genFriendlyMsg(err)
|
||||
@ -705,15 +733,18 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
when {
|
||||
!message.contains("failed:") -> profile.error =
|
||||
getString(R.string.connection_test_timeout)
|
||||
|
||||
else -> when {
|
||||
message.contains("ECONNREFUSED") -> {
|
||||
profile.error =
|
||||
getString(R.string.connection_test_refused)
|
||||
}
|
||||
|
||||
message.contains("ENETUNREACH") -> {
|
||||
profile.error =
|
||||
getString(R.string.connection_test_unreachable)
|
||||
}
|
||||
|
||||
else -> {
|
||||
profile.status = 3
|
||||
profile.error = message
|
||||
@ -939,7 +970,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
|
||||
override suspend fun onUpdated(data: TrafficData) = Unit
|
||||
|
||||
override suspend fun onUpdated(profile: ProxyEntity) = Unit
|
||||
override suspend fun onUpdated(profile: ProxyEntity, noTraffic: Boolean) = Unit
|
||||
|
||||
override suspend fun onRemoved(groupId: Long, profileId: Long) {
|
||||
val group = groupList.find { it.id == groupId } ?: return
|
||||
@ -1034,9 +1065,11 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
GroupOrder.ORIGIN -> {
|
||||
origin.isChecked = true
|
||||
}
|
||||
|
||||
GroupOrder.BY_NAME -> {
|
||||
byName.isChecked = true
|
||||
}
|
||||
|
||||
GroupOrder.BY_DELAY -> {
|
||||
byDelay.isChecked = true
|
||||
}
|
||||
@ -1267,7 +1300,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun onUpdated(profile: ProxyEntity) {
|
||||
override suspend fun onUpdated(profile: ProxyEntity, noTraffic: Boolean) {
|
||||
if (profile.groupId != proxyGroup.id) return
|
||||
val index = configurationIdList.indexOf(profile.id)
|
||||
if (index < 0) return
|
||||
@ -1275,9 +1308,21 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
if (::undoManager.isInitialized) {
|
||||
undoManager.flush()
|
||||
}
|
||||
val oldProfile = configurationList[profile.id]
|
||||
configurationList[profile.id] = profile
|
||||
notifyItemChanged(index)
|
||||
//
|
||||
val oldProfile = configurationList[profile.id]
|
||||
if (noTraffic && oldProfile != null) {
|
||||
runOnDefaultDispatcher {
|
||||
onUpdated(
|
||||
TrafficData(
|
||||
id = profile.id,
|
||||
rx = oldProfile.rx,
|
||||
tx = oldProfile.tx
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1333,6 +1378,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
newProfiles = newProfiles.sortedBy { it.displayName() }
|
||||
|
||||
}
|
||||
|
||||
GroupOrder.BY_DELAY -> {
|
||||
newProfiles =
|
||||
newProfiles.sortedBy { if (it.status == 1) it.ping else 114514 }
|
||||
@ -1538,6 +1584,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
R.id.action_standard_clipboard
|
||||
)
|
||||
}
|
||||
|
||||
!proxyEntity.haveLink() -> {
|
||||
popup.menu.removeItem(R.id.action_group_qr)
|
||||
popup.menu.removeItem(R.id.action_group_clipboard)
|
||||
@ -1589,6 +1636,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
||||
R.id.action_universal_clipboard -> export(
|
||||
entity.requireBean().toUniversalLink()
|
||||
)
|
||||
|
||||
R.id.action_config_export_clipboard -> export(entity.exportConfig().first)
|
||||
R.id.action_config_export_file -> {
|
||||
val cfg = entity.exportConfig()
|
||||
|
||||
@ -300,6 +300,7 @@ class MainActivity : ThemedActivity(),
|
||||
R.id.nav_configuration -> {
|
||||
displayFragment(ConfigurationFragment())
|
||||
}
|
||||
|
||||
R.id.nav_group -> displayFragment(GroupFragment())
|
||||
R.id.nav_route -> displayFragment(RouteFragment())
|
||||
R.id.nav_settings -> displayFragment(SettingsFragment())
|
||||
@ -310,11 +311,13 @@ class MainActivity : ThemedActivity(),
|
||||
launchCustomTab("https://matsuridayo.github.io/")
|
||||
return false
|
||||
}
|
||||
|
||||
R.id.nav_about -> displayFragment(AboutFragment())
|
||||
R.id.nav_tuiguang -> {
|
||||
launchCustomTab("https://matsuricom.github.io/")
|
||||
return false
|
||||
}
|
||||
|
||||
else -> return false
|
||||
}
|
||||
navigation.menu.findItem(id).isChecked = true
|
||||
@ -352,6 +355,7 @@ class MainActivity : ThemedActivity(),
|
||||
ProfileManager.postUpdate(DataStore.currentProfile)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@ -412,6 +416,16 @@ class MainActivity : ThemedActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun cbSelectorUpdate(id: Long) {
|
||||
val old = DataStore.selectedProxy
|
||||
DataStore.selectedProxy = id
|
||||
DataStore.currentProfile = id
|
||||
runOnDefaultDispatcher {
|
||||
ProfileManager.postUpdate(old, true)
|
||||
ProfileManager.postUpdate(id, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceDataStoreChanged(store: PreferenceDataStore, key: String) {
|
||||
when (key) {
|
||||
Key.SERVICE_MODE -> onBinderDied()
|
||||
@ -449,6 +463,7 @@ class MainActivity : ThemedActivity(),
|
||||
binding.drawerLayout.open()
|
||||
navigation.requestFocus()
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||
if (binding.drawerLayout.isOpen) {
|
||||
binding.drawerLayout.close()
|
||||
|
||||
@ -16,7 +16,10 @@ class SwitchActivity : ThemedActivity(R.layout.layout_empty),
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_holder, ConfigurationFragment(true, null, R.string.action_switch))
|
||||
.replace(
|
||||
R.id.fragment_holder,
|
||||
ConfigurationFragment(true, null, R.string.action_switch)
|
||||
)
|
||||
.commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
@ -24,8 +27,8 @@ class SwitchActivity : ThemedActivity(R.layout.layout_empty),
|
||||
val old = DataStore.selectedProxy
|
||||
DataStore.selectedProxy = profileId
|
||||
runOnMainDispatcher {
|
||||
ProfileManager.postUpdate(old)
|
||||
ProfileManager.postUpdate(profileId)
|
||||
ProfileManager.postUpdate(old, true)
|
||||
ProfileManager.postUpdate(profileId, true)
|
||||
}
|
||||
SagerNet.reloadService()
|
||||
finish()
|
||||
|
||||
@ -9,9 +9,9 @@ export PATH=$golang/go/bin:$GOPATH/bin:$PATH
|
||||
source buildScript/init/env_ndk.sh
|
||||
|
||||
if [[ "$OSTYPE" =~ ^darwin ]]; then
|
||||
export PROJECT=$PWD
|
||||
export SRC_ROOT=$PWD
|
||||
else
|
||||
export PROJECT=$(realpath .)
|
||||
export SRC_ROOT=$(realpath .)
|
||||
fi
|
||||
|
||||
DEPS=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
|
||||
|
||||
26
buildScript/lib/core/get_source.sh
Executable file
26
buildScript/lib/core/get_source.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "buildScript/init/env.sh"
|
||||
ENV_NB4A=1
|
||||
source "buildScript/lib/core/get_source_env.sh"
|
||||
pushd ..
|
||||
|
||||
######
|
||||
## From nekoray/libs/get_source.sh
|
||||
######
|
||||
|
||||
####
|
||||
if [ ! -d "sing-box-extra" ]; then
|
||||
git clone --no-checkout https://github.com/MatsuriDayo/sing-box-extra.git
|
||||
fi
|
||||
pushd sing-box-extra
|
||||
git checkout "$COMMIT_SING_BOX_EXTRA"
|
||||
|
||||
ENV_SING_BOX_EXTRA=1
|
||||
source $SRC_ROOT/buildScript/lib/core/get_source_env.sh
|
||||
NO_ENV=1 ./libs/get_source.sh
|
||||
|
||||
popd
|
||||
|
||||
popd
|
||||
8
buildScript/lib/core/get_source_env.sh
Normal file
8
buildScript/lib/core/get_source_env.sh
Normal file
@ -0,0 +1,8 @@
|
||||
if [ ! -z $ENV_NB4A ]; then
|
||||
export COMMIT_SING_BOX_EXTRA="a4eacbd0e54b6ec0a42096c42b6137a5be91a0bc"
|
||||
fi
|
||||
|
||||
if [ ! -z $ENV_SING_BOX_EXTRA ]; then
|
||||
source libs/get_source_env.sh
|
||||
export COMMIT_SING_BOX="91495e813068294aae506fdd769437c41dd8d3a3"
|
||||
fi
|
||||
@ -2,6 +2,9 @@
|
||||
|
||||
source "buildScript/init/env.sh"
|
||||
|
||||
# fetch soucre
|
||||
bash buildScript/lib/core/get_source.sh
|
||||
|
||||
[ -f libcore/go.mod ] || exit 1
|
||||
cd libcore
|
||||
|
||||
|
||||
@ -4,12 +4,12 @@ go 1.18
|
||||
|
||||
require (
|
||||
github.com/codeclysm/extract v2.2.0+incompatible
|
||||
github.com/matsuridayo/libneko v0.0.0-20230315005352-9d7e3f3a79d1
|
||||
github.com/matsuridayo/sing-box-extra v0.0.0-20230417014110-39b3adb5f93f
|
||||
github.com/matsuridayo/libneko v1.0.0 // replaced
|
||||
github.com/matsuridayo/sing-box-extra v1.0.0 // replaced
|
||||
github.com/miekg/dns v1.1.53
|
||||
github.com/sagernet/sing v0.2.3
|
||||
github.com/sagernet/sing-box v1.2.4
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc
|
||||
github.com/sagernet/sing-box v1.0.0 // replaced
|
||||
github.com/sagernet/sing-dns v1.0.0 // replaced
|
||||
github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab
|
||||
github.com/ulikunitz/xz v0.5.10
|
||||
golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105
|
||||
@ -93,10 +93,10 @@ require (
|
||||
lukechampine.com/blake3 v1.1.7 // indirect
|
||||
)
|
||||
|
||||
// replace github.com/matsuridayo/libneko => ../../libneko
|
||||
replace github.com/matsuridayo/libneko v1.0.0 => ../../libneko
|
||||
|
||||
// replace github.com/matsuridayo/sing-box-extra => ../../sing-box-extra
|
||||
replace github.com/matsuridayo/sing-box-extra v1.0.0 => ../../sing-box-extra
|
||||
|
||||
replace github.com/sagernet/sing-dns => github.com/matsuridayo/sing-dns v0.0.0-20230420050318-63790a1843f8
|
||||
replace github.com/sagernet/sing-box v1.0.0 => ../../sing-box
|
||||
|
||||
replace github.com/sagernet/sing-box => github.com/matsuridayo/sing-box v0.0.0-20230419123417-eaa058f8a077
|
||||
replace github.com/sagernet/sing-dns v1.0.0 => ../../sing-dns
|
||||
|
||||
@ -76,14 +76,6 @@ github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/matsuridayo/libneko v0.0.0-20230315005352-9d7e3f3a79d1 h1:+FflyEuq2hn++MENFuT1/qFHz0KITKK/F6ZHxs23mrg=
|
||||
github.com/matsuridayo/libneko v0.0.0-20230315005352-9d7e3f3a79d1/go.mod h1:IRO07Queptz/rGFvEW+3Hmwpx7MCup6WiDs4p5jMt4g=
|
||||
github.com/matsuridayo/sing-box v0.0.0-20230419123417-eaa058f8a077 h1:k2glJShoEN6l1aBVkxETzlspS9Q+/MEJR9B8z5kirhA=
|
||||
github.com/matsuridayo/sing-box v0.0.0-20230419123417-eaa058f8a077/go.mod h1:LDW5ZOuWURxSWz+auElryalxCBlGbA0zvsC8XSy8Sp0=
|
||||
github.com/matsuridayo/sing-box-extra v0.0.0-20230417014110-39b3adb5f93f h1:x0UjjMoYh5WSDGhIuRkmZUhGoxXnK++wyvuPnURhz6Q=
|
||||
github.com/matsuridayo/sing-box-extra v0.0.0-20230417014110-39b3adb5f93f/go.mod h1:NfCwDELPcVFo8rp0d/P7M2OPmegGCGcwF4GSpgZu8Rs=
|
||||
github.com/matsuridayo/sing-dns v0.0.0-20230420050318-63790a1843f8 h1:eEXScrFlYLiXp2n6G6nnRQVPH81TFF1DGu0xqCFcPHY=
|
||||
github.com/matsuridayo/sing-dns v0.0.0-20230420050318-63790a1843f8/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY=
|
||||
github.com/mholt/acmez v1.1.0 h1:IQ9CGHKOHokorxnffsqDvmmE30mDenO1lptYZ1AYkHY=
|
||||
github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs=
|
||||
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
"github.com/matsuridayo/libneko/neko_log"
|
||||
"github.com/matsuridayo/sing-box-extra/boxmain"
|
||||
"github.com/sagernet/sing-box/nekoutils"
|
||||
)
|
||||
|
||||
//go:linkname resourcePaths github.com/sagernet/sing-box/constant.resourcePaths
|
||||
@ -62,6 +63,9 @@ func InitCore(process, cachePath, internalAssets, externalAssets string,
|
||||
neko_log.SetupLog(int(maxLogSizeKb)*1024, filepath.Join(cachePath, "neko.log"))
|
||||
boxmain.DisableColor()
|
||||
|
||||
// nekoutils
|
||||
nekoutils.Selector_OnProxySelected = iif.Selector_OnProxySelected
|
||||
|
||||
// Set up some component
|
||||
go func() {
|
||||
defer device.DeferPanicToError("InitCore-go", func(err error) { log.Println(err) })
|
||||
|
||||
@ -7,6 +7,7 @@ var useProcfs bool
|
||||
|
||||
type NB4AInterface interface {
|
||||
UseOfficialAssets() bool
|
||||
Selector_OnProxySelected(tag string)
|
||||
}
|
||||
|
||||
type LocalResolver interface {
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
go get github.com/sagernet/sing-box@"$1"
|
||||
go mod tidy
|
||||
@ -1,2 +0,0 @@
|
||||
go get github.com/matsuridayo/sing-box-extra@"$1"
|
||||
go mod tidy
|
||||
@ -1,2 +0,0 @@
|
||||
go get github.com/matsuridayo/libneko@"$1"
|
||||
go mod tidy
|
||||
Loading…
Reference in New Issue
Block a user