Skip to content
Draft
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ jobs:
working_directory: ~/code
docker:
- image: cimg/android:2022.12.1-ndk
# ref: https://circleci.com/developer/images/image/cimg/android
environment:
GRADLE_OPTS: -Dorg.gradle.workers.max=1 -Dorg.gradle.daemon=false -Dkotlin.compiler.execution.strategy="in-process"
RUST_VERSION: 1.67.0
Expand Down
2 changes: 2 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
api("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion")
kapt("androidx.room:room-compiler:$roomVersion")
api("com.squareup.okhttp3:okhttp:5.0.0-alpha.10")
api("com.squareup.okhttp3:okhttp-brotli:5.0.0-alpha.10")
androidTestImplementation("androidx.room:room-testing:$roomVersion")
androidTestImplementation("androidx.test.ext:junit-ktx:1.1.5")
}
186 changes: 186 additions & 0 deletions core/schemas/com.github.shadowsocks.database.PrivateDatabase/30.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
{
"formatVersion": 1,
"database": {
"version": 30,
"identityHash": "e1c2ad386fb06fcb7c9090f43b712f1d",
"entities": [
{
"tableName": "Profile",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `host` TEXT NOT NULL, `remotePort` INTEGER NOT NULL, `password` TEXT NOT NULL, `method` TEXT NOT NULL, `route` TEXT NOT NULL, `remoteDns` TEXT NOT NULL, `localDohHostAddr` TEXT NOT NULL, `proxyApps` INTEGER NOT NULL, `bypass` INTEGER NOT NULL, `udpdns` INTEGER NOT NULL, `ipv6` INTEGER NOT NULL, `metered` INTEGER NOT NULL, `individual` TEXT NOT NULL, `plugin` TEXT, `udpFallback` INTEGER, `subscription` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "host",
"columnName": "host",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "remotePort",
"columnName": "remotePort",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "method",
"columnName": "method",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "route",
"columnName": "route",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "remoteDns",
"columnName": "remoteDns",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "localDohHostAddr",
"columnName": "localDohHostAddr",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "proxyApps",
"columnName": "proxyApps",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "bypass",
"columnName": "bypass",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "udpdns",
"columnName": "udpdns",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ipv6",
"columnName": "ipv6",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "metered",
"columnName": "metered",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "individual",
"columnName": "individual",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "plugin",
"columnName": "plugin",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "udpFallback",
"columnName": "udpFallback",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "subscription",
"columnName": "subscription",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tx",
"columnName": "tx",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "rx",
"columnName": "rx",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "userOrder",
"columnName": "userOrder",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "KeyValuePair",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `valueType` INTEGER NOT NULL, `value` BLOB NOT NULL, PRIMARY KEY(`key`))",
"fields": [
{
"fieldPath": "key",
"columnName": "key",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "valueType",
"columnName": "valueType",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "BLOB",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"key"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e1c2ad386fb06fcb7c9090f43b712f1d')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import com.github.shadowsocks.utils.Key
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

@Database(entities = [Profile::class, KeyValuePair::class], version = 29)
@Database(entities = [Profile::class, KeyValuePair::class], version = 30)
@TypeConverters(Profile.SubscriptionStatus::class)
abstract class PrivateDatabase : RoomDatabase() {
companion object {
Expand All @@ -42,7 +42,8 @@ abstract class PrivateDatabase : RoomDatabase() {
Migration26,
Migration27,
Migration28,
Migration29
Migration29,
Migration30,
)
allowMainThreadQueries()
enableMultiInstanceInvalidation()
Expand Down Expand Up @@ -78,4 +79,8 @@ abstract class PrivateDatabase : RoomDatabase() {
database.execSQL("ALTER TABLE `Profile` ADD COLUMN `subscription` INTEGER NOT NULL DEFAULT " +
Profile.SubscriptionStatus.UserConfigured.persistedValue)
}
object Migration30 : Migration(29, 30) {
override fun migrate(database: SupportSQLiteDatabase) =
database.execSQL("ALTER TABLE `Profile` ADD COLUMN `localDohHostAddr` TEXT NOT NULL DEFAULT ''")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import android.util.Base64
import android.util.LongSparseArray
import androidx.core.net.toUri
import androidx.room.*
import com.github.shadowsocks.acl.Acl
import com.github.shadowsocks.plugin.PluginConfiguration
import com.github.shadowsocks.plugin.PluginOptions
import com.github.shadowsocks.preference.DataStore
Expand Down Expand Up @@ -59,8 +60,9 @@ data class Profile(
var password: String = "u1rRWTssNv0p",
var method: String = "aes-256-cfb",

var route: String = "all",
var route: String = Acl.ALL,
var remoteDns: String = "dns.google",
var localDohHostAddr: String = "223.5.5.5,120.53.53.53,223.6.6.6,1.12.12.12",
var proxyApps: Boolean = false,
var bypass: Boolean = false,
var udpdns: Boolean = false,
Expand Down Expand Up @@ -197,6 +199,7 @@ data class Profile(
route = json["route"].optString ?: route
if (fallback) return@apply
remoteDns = json["remote_dns"].optString ?: remoteDns
localDohHostAddr = json["localDohHostAddr"].optString ?: localDohHostAddr
ipv6 = json["ipv6"].optBoolean ?: ipv6
metered = json["metered"].optBoolean ?: metered
(json["proxy_apps"] as? JsonObject)?.also {
Expand Down Expand Up @@ -323,6 +326,7 @@ data class Profile(
put("remarks", name)
put("route", route)
put("remote_dns", remoteDns)
put("localDohHostAddr", localDohHostAddr)
put("ipv6", ipv6)
put("metered", metered)
put("proxy_apps", JSONObject().apply {
Expand All @@ -346,6 +350,7 @@ data class Profile(
DataStore.privateStore.putString(Key.password, password)
DataStore.privateStore.putString(Key.route, route)
DataStore.privateStore.putString(Key.remoteDns, remoteDns)
DataStore.privateStore.putString(Key.localDohHostAddr, localDohHostAddr)
DataStore.privateStore.putString(Key.method, method)
DataStore.proxyApps = proxyApps
DataStore.bypass = bypass
Expand All @@ -370,6 +375,7 @@ data class Profile(
method = DataStore.privateStore.getString(Key.method) ?: ""
route = DataStore.privateStore.getString(Key.route) ?: ""
remoteDns = DataStore.privateStore.getString(Key.remoteDns) ?: ""
localDohHostAddr = DataStore.privateStore.getString(Key.localDohHostAddr) ?: ""
proxyApps = DataStore.proxyApps
bypass = DataStore.bypass
udpdns = DataStore.privateStore.getBoolean(Key.udpdns, false)
Expand Down
Loading