diff --git a/app/src/main/java/io/nekohasekai/sagernet/Constants.kt b/app/src/main/java/io/nekohasekai/sagernet/Constants.kt index d44293e..74df77d 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/Constants.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/Constants.kt @@ -50,7 +50,7 @@ object Key { const val TCP_KEEP_ALIVE_INTERVAL = "tcpKeepAliveInterval" const val RULES_PROVIDER = "rulesProvider" - const val ENABLE_LOG = "enableLog" + const val LOG_LEVEL = "logLevel" const val LOG_BUF_SIZE = "logBufSize" const val MTU = "mtu" const val ALWAYS_SHOW_ADDRESS = "alwaysShowAddress" diff --git a/app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt b/app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt index 62a1d12..b8cc86b 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt @@ -77,7 +77,7 @@ class SagerNet : Application(), filesDir.absolutePath + "/", externalAssets.absolutePath + "/", DataStore.logBufSize, - DataStore.enableLog, + DataStore.logLevel > 0, this ) diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt index 0826578..d59b1d2 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt @@ -185,7 +185,7 @@ abstract class BoxInstance( "--config", configFile.absolutePath, "--log-level", - if (DataStore.enableLog) "trace" else "warn", + if (DataStore.logLevel > 0) "trace" else "warn", "client" ) diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt b/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt index 45fa8e6..6f67739 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt @@ -106,7 +106,7 @@ object DataStore : OnPreferenceDataStoreChangeListener { var dnsNetwork by configurationStore.stringSet(Key.DNS_NETWORK) var rulesProvider by configurationStore.stringToInt(Key.RULES_PROVIDER) - var enableLog by configurationStore.boolean(Key.ENABLE_LOG) + var logLevel by configurationStore.stringToInt(Key.LOG_LEVEL) var logBufSize by configurationStore.int(Key.LOG_BUF_SIZE) { 0 } var acquireWakeLock by configurationStore.boolean(Key.ACQUIRE_WAKE_LOCK) 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 f43b43f..c0191ba 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt @@ -146,6 +146,17 @@ fun buildConfig( } } + log = LogOptions().apply { + level = when (DataStore.logLevel) { + 0 -> "panic" + 1 -> "warn" + 2 -> "info" + 3 -> "debug" + 4 -> "trace" + else -> "info" + } + } + dns = DNSOptions().apply { // TODO nb4a hosts? // hosts = DataStore.hosts.split("\n") diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveFmt.kt index 5eb7a62..cab350e 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveFmt.kt @@ -80,7 +80,7 @@ fun NaiveBean.buildNaiveConfig(port: Int): String { if (extraHeaders.isNotBlank()) { put("extra-headers", extraHeaders.split("\n").joinToString("\r\n")) } - if (DataStore.enableLog) { + if (DataStore.logLevel > 0) { put("log", "") } if (insecureConcurrency > 0) { diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan_go/TrojanGoFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan_go/TrojanGoFmt.kt index 195ba84..cb02357 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan_go/TrojanGoFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan_go/TrojanGoFmt.kt @@ -91,7 +91,7 @@ fun TrojanGoBean.buildTrojanGoConfig(port: Int): String { put("password", JSONArray().apply { put(password) }) - put("log_level", if (DataStore.enableLog) 0 else 2) + put("log_level", if (DataStore.logLevel > 0) 0 else 2) if (Protocols.shouldEnableMux("trojan-go")) put("mux", JSONObject().apply { put("enabled", true) put("concurrency", DataStore.muxConcurrency) diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/tuic/TuicFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/tuic/TuicFmt.kt index a74e1b2..ce31363 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/tuic/TuicFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/tuic/TuicFmt.kt @@ -59,6 +59,6 @@ fun TuicBean.buildTuicConfig(port: Int, cacheFile: (() -> File)?): String { put("ip", LOCALHOST) put("port", port) }) - put("log_level", if (DataStore.enableLog) "debug" else "info") + put("log_level", if (DataStore.logLevel > 0) "debug" else "info") }.toStringPretty() } diff --git a/app/src/main/java/io/nekohasekai/sagernet/ktx/Utils.kt b/app/src/main/java/io/nekohasekai/sagernet/ktx/Utils.kt index 23e06e9..0aa311f 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ktx/Utils.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ktx/Utils.kt @@ -31,10 +31,7 @@ import io.nekohasekai.sagernet.bg.Executable import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.ui.MainActivity import io.nekohasekai.sagernet.ui.ThemedActivity -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.* import moe.matsuri.nb4a.utils.NGUtil import java.io.FileDescriptor import java.net.* @@ -241,10 +238,13 @@ fun Fragment.needReload() { fun Fragment.needRestart() { snackbar("Restart APP to apply changes.").setAction(R.string.apply) { - Executable.killAll(true) - ProcessPhoenix.triggerRebirth( - requireContext(), Intent(requireContext(), MainActivity::class.java) - ) + SagerNet.stopService() + val ctx = requireContext() + runOnDefaultDispatcher { + delay(500) + Executable.killAll(true) + ProcessPhoenix.triggerRebirth(ctx, Intent(ctx, MainActivity::class.java)) + } }.show() } diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt index 19b80b2..7a0fe34 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt @@ -24,6 +24,7 @@ import io.nekohasekai.sagernet.utils.Theme import io.nekohasekai.sagernet.widget.AppListPreference import moe.matsuri.nb4a.Protocols import moe.matsuri.nb4a.ui.ColorPickerPreference +import moe.matsuri.nb4a.ui.LongClickMenuPreference import moe.matsuri.nb4a.ui.LongClickSwitchPreference import moe.matsuri.nb4a.ui.MTUPreference @@ -117,14 +118,14 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() { val requireTransproxy = findPreference(Key.REQUIRE_TRANSPROXY)!! val transproxyPort = findPreference(Key.TRANSPROXY_PORT)!! val transproxyMode = findPreference(Key.TRANSPROXY_MODE)!! - val enableLog = findPreference(Key.ENABLE_LOG)!! + val logLevel = findPreference(Key.LOG_LEVEL)!! val mtu = findPreference(Key.MTU)!! - enableLog.setOnPreferenceChangeListener { _, _ -> + logLevel.setOnPreferenceChangeListener { _, _ -> needRestart() true } - enableLog.setOnLongClickListener { + logLevel.setOnLongClickListener { if (context == null) return@setOnLongClickListener true val view = EditText(context).apply { diff --git a/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt b/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt new file mode 100644 index 0000000..a0e7ab8 --- /dev/null +++ b/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt @@ -0,0 +1,33 @@ +package moe.matsuri.nb4a.ui + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.preference.PreferenceViewHolder +import com.takisoft.preferencex.SimpleMenuPreference +import io.nekohasekai.sagernet.R + +class LongClickMenuPreference +@JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = com.takisoft.preferencex.simplemenu.R.attr.simpleMenuPreferenceStyle, + defStyleRes: Int = R.style.Preference_SimpleMenuPreference +) : SimpleMenuPreference( + context, attrs, defStyleAttr, defStyleRes +) { + private var mLongClickListener: View.OnLongClickListener? = null + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + val itemView: View = holder.itemView + itemView.setOnLongClickListener { + mLongClickListener?.onLongClick(it) ?: true + } + } + + fun setOnLongClickListener(longClickListener: View.OnLongClickListener) { + this.mLongClickListener = longClickListener + } + +} diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index abb598d..56af5c8 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,5 +1,32 @@ + + + 0 + 1 + + + + 0 + 1 + 2 + + + + 0 + 1 + 2 + 3 + + + + 0 + 1 + 2 + 3 + 4 + + 1.0.0.0/8 2.0.0.0/7 @@ -294,10 +321,6 @@ TPROXY - - 0 - 1 - HTTPS @@ -315,13 +338,6 @@ @string/disable @string/auto - - 0 - 1 - 2 - 3 - - @string/disable @string/enable @@ -348,11 +364,6 @@ leastPing - - 0 - 1 - 2 - @string/group_basic @@ -478,4 +489,12 @@ v2ray-plugin + + none + warn + info + debug + trace + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e22758..e28dac9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -524,5 +524,6 @@ Anyone can write advanced plugins, which can control NekoBox. please download an Enable Clash API Flow (VLESS Sub-protocol) + Log Level \ No newline at end of file diff --git a/app/src/main/res/xml/global_preferences.xml b/app/src/main/res/xml/global_preferences.xml index 38d279a..9fa1257 100644 --- a/app/src/main/res/xml/global_preferences.xml +++ b/app/src/main/res/xml/global_preferences.xml @@ -71,11 +71,14 @@ app:summary="@string/show_direct_speed_sum" app:title="@string/show_direct_speed" app:useSimpleSummaryProvider="true" /> - + app:key="logLevel" + app:title="@string/log_level" + app:useSimpleSummaryProvider="true" />