Squashed commit of the following:

commit 574fba87ab733332efa17733a6602a1649e62379
Author: Steve Johnson <stevejohnson1438@proton.me>
Date:   Sun Oct 29 21:31:23 2023 +0800

    support importing local geofile

commit ec410293f3abe29835645233349d026d3a55acc0
Author: Steve Johnson <stevejohnson1438@proton.me>
Date:   Sun Oct 29 17:18:52 2023 +0800

    release assets at runtime

commit 2dfb95bab98ba661a28efe255e2965c35c6580c4
Author: Steve Johnson <stevejohnson1438@proton.me>
Date:   Sun Oct 29 16:43:41 2023 +0800

    remove embedded country.mmdb

commit fb245ed4a3c257284685f3b1bee5d9f7333833ce
Author: Steve Johnson <stevejohnson1438@proton.me>
Date:   Sun Oct 29 16:35:14 2023 +0800

    simplity gradle

commit 2fb75c87a13dea7e5c8f8f4126cc53d2d6926b99
Author: Steve Johnson <stevejohnson1438@proton.me>
Date:   Sun Oct 29 16:06:17 2023 +0800

    add geofiles download
This commit is contained in:
Steve Johnson 2023-10-29 21:38:36 +08:00
parent 4051033d7d
commit ecf03507e6
12 changed files with 227 additions and 1 deletions

3
.gitignore vendored
View File

@ -27,6 +27,9 @@ gradle-app.setting
/core/src/premium/golang/.idea/* /core/src/premium/golang/.idea/*
!/core/src/premium/golang/.idea/codeStyles !/core/src/premium/golang/.idea/codeStyles
# Ignore builtin geofiles
app/src/main/assets
# KeyStore # KeyStore
signing.properties signing.properties
*.keystore *.keystore

View File

@ -1,3 +1,7 @@
import java.net.URL
import java.nio.file.Files
import java.nio.file.StandardCopyOption
plugins { plugins {
kotlin("android") kotlin("android")
kotlin("kapt") kotlin("kapt")
@ -25,3 +29,40 @@ dependencies {
tasks.getByName("clean", type = Delete::class) { tasks.getByName("clean", type = Delete::class) {
delete(file("release")) delete(file("release"))
} }
val geoFilesDownloadDir = "src/main/assets"
task("downloadGeoFiles") {
val geoFilesUrls = mapOf(
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb" to "geoip.metadb",
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat" to "geosite.dat",
// "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb" to "country.mmdb",
)
doLast {
geoFilesUrls.forEach { (downloadUrl, outputFileName) ->
val url = URL(downloadUrl)
val outputPath = file("$geoFilesDownloadDir/$outputFileName")
outputPath.parentFile.mkdirs()
url.openStream().use { input ->
Files.copy(input, outputPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
println("$outputFileName downloaded to $outputPath")
}
}
}
}
afterEvaluate {
val downloadGeoFilesTask = tasks["downloadGeoFiles"]
tasks.forEach {
if (it.name.startsWith("assemble")) {
it.dependsOn(downloadGeoFilesTask)
}
}
}
tasks.getByName("clean", type = Delete::class) {
delete(file(geoFilesDownloadDir))
}

View File

@ -7,6 +7,12 @@ import com.github.kr328.clash.common.compat.currentProcessName
import com.github.kr328.clash.common.log.Log import com.github.kr328.clash.common.log.Log
import com.github.kr328.clash.remote.Remote import com.github.kr328.clash.remote.Remote
import com.github.kr328.clash.service.util.sendServiceRecreated import com.github.kr328.clash.service.util.sendServiceRecreated
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
@Suppress("unused") @Suppress("unused")
class MainApplication : Application() { class MainApplication : Application() {
@ -20,6 +26,7 @@ class MainApplication : Application() {
super.onCreate() super.onCreate()
val processName = currentProcessName val processName = currentProcessName
extractGeoFiles()
Log.d("Process $processName started") Log.d("Process $processName started")
@ -30,6 +37,22 @@ class MainApplication : Application() {
} }
} }
private fun extractGeoFiles() {
val geoipFile = File(filesDir, "clash/geoip.metadb")
if(!geoipFile.exists()) {
FileOutputStream(geoipFile).use {
assets.open("geoip.metadb").copyTo(it);
}
}
val geositeFile = File(filesDir, "clash/geosite.dat")
if(!geositeFile.exists()) {
FileOutputStream(geositeFile).use {
assets.open("geosite.dat").copyTo(it);
}
}
}
fun finalize() { fun finalize() {
Global.destroy() Global.destroy()
} }

View File

@ -1,10 +1,23 @@
package com.github.kr328.clash package com.github.kr328.clash
import android.R
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.database.Cursor
import android.provider.OpenableColumns
import android.widget.Toast
import com.github.kr328.clash.core.Clash import com.github.kr328.clash.core.Clash
import com.github.kr328.clash.design.MetaFeatureSettingsDesign import com.github.kr328.clash.design.MetaFeatureSettingsDesign
import com.github.kr328.clash.util.withClash import com.github.kr328.clash.util.withClash
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select import kotlinx.coroutines.selects.select
import java.io.File
import java.io.FileOutputStream
import kotlin.coroutines.resume
class MetaFeatureSettingsActivity : BaseActivity<MetaFeatureSettingsDesign>() { class MetaFeatureSettingsActivity : BaseActivity<MetaFeatureSettingsDesign>() {
override suspend fun main() { override suspend fun main() {
@ -41,9 +54,90 @@ class MetaFeatureSettingsActivity : BaseActivity<MetaFeatureSettingsDesign>() {
finish() finish()
} }
} }
MetaFeatureSettingsDesign.Request.ImportGeoIp -> {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
intent.addCategory(Intent.CATEGORY_OPENABLE)
startActivityForResult(
intent,
MetaFeatureSettingsDesign.Request.ImportGeoIp.ordinal
)
}
MetaFeatureSettingsDesign.Request.ImportGeoSite -> {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
intent.addCategory(Intent.CATEGORY_OPENABLE)
startActivityForResult(
intent,
MetaFeatureSettingsDesign.Request.ImportGeoSite.ordinal
)
}
MetaFeatureSettingsDesign.Request.ImportCountry -> {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
intent.addCategory(Intent.CATEGORY_OPENABLE)
startActivityForResult(
intent,
MetaFeatureSettingsDesign.Request.ImportCountry.ordinal
)
} }
} }
} }
} }
} }
} }
public val validDatabaseExtensions = listOf(
".metadb", ".db", ".dat", ".mmdb"
)
@SuppressLint("Range")
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if(resultCode == RESULT_OK) {
val uri = resultData?.data
val cursor: Cursor? = uri?.let {
contentResolver.query(it, null, null, null, null, null)
}
cursor?.use {
if (it.moveToFirst()) {
val displayName: String =
it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME))
val ext = "." + displayName.substringAfterLast(".")
if(!validDatabaseExtensions.contains(ext))
{
val dialog = MaterialAlertDialogBuilder(this)
.setTitle("Unknown Database Format")
.setMessage("Only ${validDatabaseExtensions.joinToString("/")} are supported")
.setPositiveButton("OK"){ _, _ -> }
.show()
return
}
val outputFileName = when (requestCode) {
MetaFeatureSettingsDesign.Request.ImportGeoIp.ordinal ->
"geoip$ext"
MetaFeatureSettingsDesign.Request.ImportGeoSite.ordinal ->
"geosite$ext"
MetaFeatureSettingsDesign.Request.ImportCountry.ordinal ->
"country$ext"
else -> ""
}
if(outputFileName.isEmpty())
{
Toast.makeText(this, "Bad request", Toast.LENGTH_LONG).show()
return
}
val outputFile = File(File(filesDir, "clash"), outputFileName);
contentResolver.openInputStream(uri).use { ins->
FileOutputStream(outputFile).use { outs->
ins?.copyTo(outs)
}
}
Toast.makeText(this, "$displayName imported", Toast.LENGTH_LONG).show()
return
}
}
}
Toast.makeText(this, "Import failed", Toast.LENGTH_LONG).show()
}
}

View File

@ -15,7 +15,7 @@ class MetaFeatureSettingsDesign(
configuration: ConfigurationOverride configuration: ConfigurationOverride
) : Design<MetaFeatureSettingsDesign.Request>(context) { ) : Design<MetaFeatureSettingsDesign.Request>(context) {
enum class Request { enum class Request {
ResetOverride ResetOverride, ImportGeoIp, ImportGeoSite, ImportCountry
} }
private val binding = DesignSettingsMetaFeatureBinding private val binding = DesignSettingsMetaFeatureBinding
@ -198,6 +198,36 @@ class MetaFeatureSettingsDesign(
) )
sniffer.listener?.onChanged() sniffer.listener?.onChanged()
category(R.string.geox_files)
clickable (
title = R.string.import_geoip_file,
summary = R.string.press_to_import,
){
clicked {
requests.trySend(Request.ImportGeoIp)
}
}
clickable (
title = R.string.import_geosite_file,
summary = R.string.press_to_import,
){
clicked {
requests.trySend(Request.ImportGeoSite)
}
}
clickable (
title = R.string.import_country_file,
summary = R.string.press_to_import,
){
clicked {
requests.trySend(Request.ImportCountry)
}
}
/* /*
category(R.string.geox_url_setting) category(R.string.geox_url_setting)

View File

@ -234,4 +234,9 @@
<string name="geox_geoip">GeoIP URL</string> <string name="geox_geoip">GeoIP URL</string>
<string name="geox_mmdb">MMDB URL</string> <string name="geox_mmdb">MMDB URL</string>
<string name="geox_geosite">Geosite URL</string> <string name="geox_geosite">Geosite URL</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">Import GeoIP Database</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">Import GeoSite Database</string>
<string name="import_country_file">Import Country Database</string>
</resources> </resources>

View File

@ -234,4 +234,9 @@
<string name="geox_geoip">GeoIP Url</string> <string name="geox_geoip">GeoIP Url</string>
<string name="geox_mmdb">MMDB Url</string> <string name="geox_mmdb">MMDB Url</string>
<string name="geox_geosite">Geosite Url</string> <string name="geox_geosite">Geosite Url</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">Import GeoIP Database</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">Import GeoSite Database</string>
<string name="import_country_file">Import Country Database</string>
</resources> </resources>

View File

@ -299,4 +299,9 @@
<string name="geoip_url" translatable="false">https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/geoip.dat</string> <string name="geoip_url" translatable="false">https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/geoip.dat</string>
<string name="mmdb_url" translatable="false">https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb</string> <string name="mmdb_url" translatable="false">https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb</string>
<string name="geosite_url" translatable="false">https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/geosite.dat</string> <string name="geosite_url" translatable="false">https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/geosite.dat</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">Import GeoIP Database</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">Import GeoSite Database</string>
<string name="import_country_file">Import Country Database</string>
</resources> </resources>

View File

@ -231,4 +231,9 @@
<string name="geox_geosite">Geosite Url</string> <string name="geox_geosite">Geosite Url</string>
<string name="prefer_h3">Prefer h3</string> <string name="prefer_h3">Prefer h3</string>
<string name="port_whitelist">Port Whitelist</string> <string name="port_whitelist">Port Whitelist</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">Import GeoIP Database</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">Import GeoSite Database</string>
<string name="import_country_file">Import Country Database</string>
</resources> </resources>

View File

@ -231,4 +231,9 @@
<string name="geox_geosite">Geosite Url</string> <string name="geox_geosite">Geosite Url</string>
<string name="prefer_h3">Prefer h3</string> <string name="prefer_h3">Prefer h3</string>
<string name="port_whitelist">Port Whitelist</string> <string name="port_whitelist">Port Whitelist</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">Import GeoIP Database</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">Import GeoSite Database</string>
<string name="import_country_file">Import Country Database</string>
</resources> </resources>

View File

@ -234,4 +234,9 @@
<string name="geox_geosite">Geosite Url</string> <string name="geox_geosite">Geosite Url</string>
<string name="prefer_h3">Prefer h3</string> <string name="prefer_h3">Prefer h3</string>
<string name="port_whitelist">Port Whitelist</string> <string name="port_whitelist">Port Whitelist</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">导入 GeoIP 数据库</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">导入 GeoSite 数据库</string>
<string name="import_country_file">导入 Country 数据库</string>
</resources> </resources>

View File

@ -299,4 +299,9 @@
<string name="geoip_url" translatable="false">https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geoip.dat</string> <string name="geoip_url" translatable="false">https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geoip.dat</string>
<string name="mmdb_url" translatable="false">https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/country.mmdb</string> <string name="mmdb_url" translatable="false">https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/country.mmdb</string>
<string name="geosite_url" translatable="false">https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat</string> <string name="geosite_url" translatable="false">https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat</string>
<string name="geox_files" >Geo Files</string>
<string name="import_geoip_file">Import GeoIP Database</string>
<string name="press_to_import">Press to import...</string>
<string name="import_geosite_file">Import GeoSite Database</string>
<string name="import_country_file">Import Country Database</string>
</resources> </resources>