From 9d2cdabd581a1e6346f462fa7d85acc51e928a0e Mon Sep 17 00:00:00 2001 From: purofle Date: Sat, 17 Feb 2024 17:21:55 +0800 Subject: [PATCH] feat: Use ruleSet instead of geoip and geosite --- .../nekohasekai/sagernet/fmt/ConfigBuilder.kt | 5 ++++- .../nekohasekai/sagernet/utils/GeoipUtils.kt | 17 +++++++++++++++-- .../sagernet/utils/GeositeUtils.kt | 16 ++++++++++++---- .../moe/matsuri/nb4a/SingBoxOptionsUtil.kt | 19 ++++++++++++++++--- 4 files changed, 47 insertions(+), 10 deletions(-) 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 17157659..c589054b 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt @@ -256,6 +256,7 @@ fun buildConfig( route = RouteOptions().apply { auto_detect_interface = true rules = mutableListOf() + rule_set = mutableListOf() } // returns outbound tag @@ -518,6 +519,7 @@ fun buildConfig( } PackageCache[it]?.takeIf { uid -> uid >= 1000 } }.toHashSet().filterNotNull() + val ruleSets = mutableListOf() val ruleObj = Rule_DefaultOptions().apply { if (uidList.isNotEmpty()) { @@ -533,7 +535,7 @@ fun buildConfig( makeSingBoxRule(rule.ip.listByLineOrComma(), true) } - generateRuleSet() + generateRuleSet(ruleSets) if (rule.port.isNotBlank()) { port = mutableListOf() @@ -614,6 +616,7 @@ fun buildConfig( ).show() } else { route.rules.add(ruleObj) + route.rule_set.addAll(ruleSets) } } } diff --git a/app/src/main/java/io/nekohasekai/sagernet/utils/GeoipUtils.kt b/app/src/main/java/io/nekohasekai/sagernet/utils/GeoipUtils.kt index 519c9c92..c14f2104 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/utils/GeoipUtils.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/utils/GeoipUtils.kt @@ -6,12 +6,23 @@ import libcore.Libcore import java.io.File object GeoipUtils { - fun generateRuleSet(context: Context = app.applicationContext, country: String) { + /** + * Generate a rule set for a specific country + * @param context the context to use + * @param country the country code to generate the rule set for + * @return the path to the generated rule set + */ + fun generateRuleSet(context: Context = app.applicationContext, country: String): String { val filesDir = context.getExternalFilesDir(null) ?: context.filesDir val ruleSetDir = filesDir.resolve("ruleSets") ruleSetDir.mkdirs() + val output = ruleSetDir.resolve("geoip-$country.srs") + + if (output.isFile) { + return output.absolutePath + } val geositeFile = File(filesDir, "geoip.db") @@ -20,6 +31,8 @@ object GeoipUtils { error("open geoip failed") } - geoip.convertGeoip(country, ruleSetDir.resolve("geoip-$country.srs").absolutePath) + geoip.convertGeoip(country, output.absolutePath) + + return output.absolutePath } } \ No newline at end of file diff --git a/app/src/main/java/io/nekohasekai/sagernet/utils/GeositeUtils.kt b/app/src/main/java/io/nekohasekai/sagernet/utils/GeositeUtils.kt index 740170c7..3190b834 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/utils/GeositeUtils.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/utils/GeositeUtils.kt @@ -6,20 +6,28 @@ import libcore.Geosite import java.io.File object GeositeUtils { - fun generateRuleSet(context: Context = app.applicationContext, code: String) { + /** + * Generate a rule set for a specific geosite code + * @param context the context to use + * @param code the geosite code to generate the rule set for + * @return the path to the generated rule set + */ + fun generateRuleSet(context: Context = app.applicationContext, code: String): String { val filesDir = context.getExternalFilesDir(null) ?: context.filesDir - + val geositeFile = File(filesDir, "geosite.db") val ruleSetDir = filesDir.resolve("ruleSets") ruleSetDir.mkdirs() - val geositeFile = File(filesDir, "geosite.db") + val output = ruleSetDir.resolve("geosite-$code.srs") val geosite = Geosite() if (!geosite.checkGeositeCode(geositeFile.absolutePath, code)) { error("code $code not found in geosite") } - geosite.convertGeosite(code, ruleSetDir.resolve("geosite-$code.srs").absolutePath) + geosite.convertGeosite(code, output.absolutePath) + + return output.absolutePath } } \ No newline at end of file diff --git a/app/src/main/java/moe/matsuri/nb4a/SingBoxOptionsUtil.kt b/app/src/main/java/moe/matsuri/nb4a/SingBoxOptionsUtil.kt index 80375c5d..d6a5b207 100644 --- a/app/src/main/java/moe/matsuri/nb4a/SingBoxOptionsUtil.kt +++ b/app/src/main/java/moe/matsuri/nb4a/SingBoxOptionsUtil.kt @@ -3,6 +3,7 @@ package moe.matsuri.nb4a import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.utils.GeoipUtils import io.nekohasekai.sagernet.utils.GeositeUtils +import moe.matsuri.nb4a.SingBoxOptions.RuleSet object SingBoxOptionsUtil { @@ -72,15 +73,27 @@ fun SingBoxOptions.DNSRule_DefaultOptions.checkEmpty(): Boolean { return true } -fun SingBoxOptions.Rule_DefaultOptions.generateRuleSet() { +fun SingBoxOptions.Rule_DefaultOptions.generateRuleSet(ruleSet: MutableList) { rule_set.forEach { when { it.startsWith("geoip") -> { - GeoipUtils.generateRuleSet(country = it.removePrefix("geoip:")) + val geoipPath = GeoipUtils.generateRuleSet(country = it.removePrefix("geoip:")) + ruleSet.add(RuleSet().apply { + type = "local" + tag = it + format = "binary" + path = geoipPath + }) } it.startsWith("geosite") -> { - GeositeUtils.generateRuleSet(code = it.removePrefix("geosite:")) + val geositePath = GeositeUtils.generateRuleSet(code = it.removePrefix("geosite:")) + ruleSet.add(RuleSet().apply { + type = "local" + tag = it + format = "binary" + path = geositePath + }) } } }