diff --git a/app/build.gradle b/app/build.gradle index 20e300e..0ba259c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ android { minSdk 27 targetSdk 34 versionCode = date.format("yyyyMMdd").toInteger() - versionName "1.6.2" + versionName "1.6.5" ksp { arg("room.schemaLocation", "$projectDir/schemas") @@ -75,15 +75,15 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.core:core-ktx:1.12.0' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'androidx.core:core-ktx:1.13.1' implementation 'androidx.room:room-runtime:2.6.1' - implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02' + implementation 'androidx.viewpager2:viewpager2:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.preference:preference-ktx:1.2.1' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.2' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' - implementation 'androidx.window:window:1.3.0-beta01' + implementation 'androidx.window:window:1.3.0' ksp 'androidx.room:room-compiler:2.6.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3' @@ -95,7 +95,7 @@ dependencies { coolapkImplementation 'com.microsoft.appcenter:appcenter-analytics:5.0.1' coolapkImplementation 'com.microsoft.appcenter:appcenter-crashes:5.0.1' - implementation 'com.google.android.material:material:1.11.0' + implementation 'com.google.android.material:material:1.12.0' implementation "dev.rikka.rikkax.material:material-preference:2.0.0" implementation 'com.guolindev.permissionx:permissionx:1.7.1' @@ -109,6 +109,6 @@ dependencies { implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' } diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/logic/AppDatabase.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/logic/AppDatabase.kt index b8f13c2..706dff0 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/logic/AppDatabase.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/logic/AppDatabase.kt @@ -14,10 +14,11 @@ import cn.ac.lz233.tarnhelm.logic.module.meta.RegexRule @Database( entities = [RegexRule::class, ParameterRule::class, RedirectRule::class, Extension::class], - version = 4, + version = 5, exportSchema = true, autoMigrations = [ - AutoMigration(from = 3, to = 4) + AutoMigration(from = 3, to = 4), + AutoMigration(from = 4, to = 5) ] ) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/logic/module/meta/RedirectRule.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/logic/module/meta/RedirectRule.kt index b38f5da..92fe051 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/logic/module/meta/RedirectRule.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/logic/module/meta/RedirectRule.kt @@ -8,6 +8,7 @@ data class RedirectRule( @PrimaryKey val id: Int, val description: String, val domain: String, + val userAgent: String?, val author: String, val sourceType: Int, // 0:manual 1:paste 2:?? val enabled: Boolean, diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/RulesActivity.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/RulesActivity.kt index fb353f3..baaf79b 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/RulesActivity.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/RulesActivity.kt @@ -17,10 +17,17 @@ import cn.ac.lz233.tarnhelm.logic.module.meta.RedirectRule import cn.ac.lz233.tarnhelm.logic.module.meta.RegexRule import cn.ac.lz233.tarnhelm.ui.SecondaryBaseActivity import cn.ac.lz233.tarnhelm.ui.rules.parameter.ParameterRulesFragment -import cn.ac.lz233.tarnhelm.ui.rules.regex.RegexRulesFragment import cn.ac.lz233.tarnhelm.ui.rules.redirect.RedirectRulesFragment +import cn.ac.lz233.tarnhelm.ui.rules.regex.RegexRulesFragment import cn.ac.lz233.tarnhelm.util.LogUtil -import cn.ac.lz233.tarnhelm.util.ktx.* +import cn.ac.lz233.tarnhelm.util.ktx.decodeBase64 +import cn.ac.lz233.tarnhelm.util.ktx.decodeURL +import cn.ac.lz233.tarnhelm.util.ktx.getModeId +import cn.ac.lz233.tarnhelm.util.ktx.getString +import cn.ac.lz233.tarnhelm.util.ktx.insertToParameterRules +import cn.ac.lz233.tarnhelm.util.ktx.insertToRedirectRules +import cn.ac.lz233.tarnhelm.util.ktx.insertToRegexRules +import cn.ac.lz233.tarnhelm.util.ktx.toJSONArray import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayoutMediator @@ -92,6 +99,7 @@ class RulesActivity : SecondaryBaseActivity() { } } } + 1 -> { val dialogBinding = DialogRegexRuleAddBinding.inflate(layoutInflater) val dialog = MaterialAlertDialogBuilder(this) @@ -125,6 +133,7 @@ class RulesActivity : SecondaryBaseActivity() { } } } + 2 -> { val dialogBinding = DialogRedirectRuleAddBinding.inflate(layoutInflater) val dialog = MaterialAlertDialogBuilder(this) @@ -134,6 +143,7 @@ class RulesActivity : SecondaryBaseActivity() { App.redirectRuleDao.getMaxId() + 1, dialogBinding.descriptionEditText.text.toString(), dialogBinding.domainEditText.text.toString(), + dialogBinding.userAgentEditText.text.toString(), dialogBinding.authorEditText.text.toString(), 0, true diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/redirect/RedirectRulesAdapter.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/redirect/RedirectRulesAdapter.kt index aab281b..340a763 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/redirect/RedirectRulesAdapter.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/ui/rules/redirect/RedirectRulesAdapter.kt @@ -29,6 +29,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R val ruleEnableSwitch: MaterialSwitch = view.findViewById(R.id.ruleEnableSwitch) val descriptionContentTextView: AppCompatTextView = view.findViewById(R.id.descriptionContentTextView) val domainContentTextView: AppCompatTextView = view.findViewById(R.id.domainContentTextView) + val userAgentContentTextView: AppCompatTextView = view.findViewById(R.id.userAgentContentTextView) val authorContentTextView: AppCompatTextView = view.findViewById(R.id.authorContentTextView) } @@ -44,6 +45,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R val base64Text = (if (SettingsDao.exportRulesAsLink) "tarnhelm://rule?redirect=" else "") + rule.toJSONObject().toString().encodeBase64().encodeURL() dialogBinding.descriptionEditText.setText(rule.description) dialogBinding.domainEditText.setText(rule.domain) + dialogBinding.userAgentEditText.setText(rule.userAgent) dialogBinding.authorEditText.setText(rule.author) dialogBinding.authorEditText.isEnabled = (rule.sourceType == 0) or BuildConfig.DEBUG val dialog = MaterialAlertDialogBuilder(holder.itemView.context) @@ -53,6 +55,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R rule.id, dialogBinding.descriptionEditText.text.toString(), dialogBinding.domainEditText.text.toString(), + dialogBinding.userAgentEditText.text.toString(), dialogBinding.authorEditText.text.toString(), rule.sourceType, rule.enabled @@ -89,6 +92,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R rule.id, rule.description, rule.domain, + rule.userAgent, rule.author, rule.sourceType, b @@ -99,6 +103,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R } holder.descriptionContentTextView.text = rule.description holder.domainContentTextView.text = rule.domain + holder.userAgentContentTextView.text = rule.userAgent holder.authorContentTextView.text = rule.author } @@ -112,6 +117,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R toRule.id, fromRule.description, fromRule.domain, + fromRule.userAgent, fromRule.author, fromRule.sourceType, fromRule.enabled @@ -120,6 +126,7 @@ class RedirectRulesAdapter(private val rulesList: MutableList) : R fromRule.id, toRule.description, toRule.domain, + toRule.userAgent, toRule.author, toRule.sourceType, toRule.enabled diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/JSONObject.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/JSONObject.kt index 4903f86..a069c49 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/JSONObject.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/JSONObject.kt @@ -40,6 +40,7 @@ fun JSONObject.insertToRedirectRules(type: Int = 1, enabled: Boolean = true): Re App.redirectRuleDao.getMaxId() + 1, this.getString("a"), this.getString("e"), + this.getString("h"), this.getString("d"), type, enabled diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/OkHttp.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/OkHttp.kt index 3bddd5b..58bff76 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/OkHttp.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/OkHttp.kt @@ -1,15 +1,23 @@ package cn.ac.lz233.tarnhelm.util.ktx +import android.webkit.WebSettings +import cn.ac.lz233.tarnhelm.App import cn.ac.lz233.tarnhelm.logic.Network import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.Request +import okhttp3.internal.commonToString import org.json.JSONObject import java.io.IOException -fun HttpUrl.followRedirect(): HttpUrl { +fun HttpUrl.followRedirect(userAgent: String?): HttpUrl { val response = Network.okHttpClientNoRedirect - .newCall(Request.Builder().url(this).build()) + .newCall( + Request.Builder() + .url(this) + .addHeader("User-Agent", if (userAgent.isNullOrEmpty()) WebSettings.getDefaultUserAgent(App.context) else userAgent) + .build() + ) .execute() return if (response.isSuccessful) { // bilibili returns 404 but still using 200 header @@ -22,8 +30,8 @@ fun HttpUrl.followRedirect(): HttpUrl { this } else if (response.isRedirect) { (response.header("Location")?.toHttpUrlOrNull() ?: response.header("location")?.toHttpUrlOrNull()) - ?.followRedirect() ?: this + ?.followRedirect(userAgent) ?: this } else { - throw IOException(response.body.string()) + throw IOException(response.commonToString()) } } \ No newline at end of file diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/Rule.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/Rule.kt index 319db05..b43fd8d 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/Rule.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/Rule.kt @@ -24,5 +24,6 @@ fun RegexRule.toJSONObject() = JSONObject().apply { fun RedirectRule.toJSONObject() = JSONObject().apply { put("a", this@toJSONObject.description) put("e", this@toJSONObject.domain) + put("h", this@toJSONObject.userAgent) put("d", this@toJSONObject.author) } \ No newline at end of file diff --git a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/String.kt b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/String.kt index 3915bca..bbf4c36 100644 --- a/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/String.kt +++ b/app/src/main/java/cn/ac/lz233/tarnhelm/util/ktx/String.kt @@ -61,7 +61,7 @@ fun String.doTarnhelm(): Triple> { .setProgress(100, 0, true) .build() App.notificationManager.notify(234, notification) - httpUrl = httpUrl.followRedirect() + httpUrl = httpUrl.followRedirect(rule.userAgent) } } result = httpUrl.toString() @@ -117,6 +117,7 @@ fun String.doTarnhelm(): Triple> { } } } + if (targetRules.isEmpty()) result = this LogUtil._d("Result: $result") LogUtil._d("TargetRules: $targetRules") return Triple(result, hasTimeConsumingOperation, targetRules) @@ -128,7 +129,7 @@ fun CharSequence.doTarnhelms(): Triple> var hasTimeConsumingOperation = false val targetRules = mutableListOf>() methodResult = - //Regex("""((https|http)://)(\p{L}|\p{Nd})+\.\p{L}+(:\p{Nd})?(\p{Ll}|\p{Lu}|\p{Nd}|/|\?|\+|&|=|\.|-|_|#|%)*""") + //Regex("""((https|http)://)(\p{L}|\p{Nd})+\.\p{L}+(:\p{Nd})?(\p{Ll}|\p{Lu}|\p{Nd}|/|\?|\+|&|=|\.|-|_|#|%)*""") Regex("""(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s\uFF01-\uFF5E\u4e00-\u9fff\u3400-\u4DBF\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF\u3000-\u303F]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s\uFF01-\uFF5E\u4e00-\u9fff\u3400-\u4DBF\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF\u3000-\u303F]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s\uFF01-\uFF5E\u4e00-\u9fff\u3400-\u4DBF\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF\u3000-\u303F]{2,}|www\.[a-zA-Z0-9]+\.[^\s\uFF01-\uFF5E\u4e00-\u9fff\u3400-\u4DBF\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF\u3000-\u303F]{2,})""") // PatternsCompat.AUTOLINK_WEB_URL.toRegex() cannot recognize some irregular sharing texts // 73 xx发布了一篇小红书笔记,快来看吧! 😆 xxxxxxxxxxxxx 😆 http://xhslink.com/xxxxxx,复制本条信息,打开【小红书】App查看精彩内容! diff --git a/app/src/main/res/layout/dialog_redirect_rule_add.xml b/app/src/main/res/layout/dialog_redirect_rule_add.xml index 0268334..d87e9bd 100644 --- a/app/src/main/res/layout/dialog_redirect_rule_add.xml +++ b/app/src/main/res/layout/dialog_redirect_rule_add.xml @@ -26,6 +26,7 @@ android:layout_marginEnd="5dp" android:layout_weight="1" android:singleLine="true" + android:text="@string/redirectRulesAddDialogTitle" android:textAppearance="@style/TextAppearance.Material3.TitleLarge" android:textColor="?attr/colorOnSecondaryContainer" /> @@ -70,6 +71,22 @@ + + + + + + + + + + + + + + + + 编辑一个重定向规则 描述 域名 + 用户代理 作者 确认 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 0fcc112..5a8feaa 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -70,6 +70,7 @@ 編輯一個重定向規則 描述 域名 + 用戶代理 作者 確認 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f6e9a17..eda3ffd 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -70,6 +70,7 @@ 編輯一個重定向規則 描述 域名 + 用戶代理 作者 確認 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 9bda18c..418e400 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -68,6 +68,7 @@ 编辑一个重定向规则 描述 域名 + 用户代理 作者 确认 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5fe1d97..fb3fc85 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -70,6 +70,7 @@ Edit a Redirect Rule Description Domain + User Agent Author OK diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png new file mode 100644 index 0000000..ff15abe Binary files /dev/null and b/fastlane/metadata/android/en-US/images/icon.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png new file mode 100644 index 0000000..04ba3ab Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png new file mode 100644 index 0000000..754a7e9 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ