mirror of
https://github.com/MetaCubeX/ClashMetaForAndroid.git
synced 2024-11-25 06:46:09 +03:00
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:
parent
4051033d7d
commit
ecf03507e6
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||||
|
@ -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))
|
||||||
|
}
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
@ -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)
|
||||||
|
|
||||||
|
@ -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>
|
@ -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>
|
@ -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>
|
||||||
|
@ -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>
|
@ -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>
|
||||||
|
@ -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>
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user