Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions app/src/main/java/me/iacn/biliroaming/SettingDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
packageName + "_preferences",
Context.MODE_MULTI_PROCESS
)
updatePurifyStoryVideoAdBlockedCount()
if (!prefs.getBoolean("hidden", false)) {
val hiddenGroup = findPreference("hidden_group") as PreferenceCategory
preferenceScreen.removePreference(hiddenGroup)
Expand Down Expand Up @@ -109,6 +110,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
findPreference("filter_search")?.onPreferenceClickListener = this
findPreference("filter_comment")?.onPreferenceClickListener = this
findPreference("copy_access_key")?.onPreferenceClickListener = this
findPreference("purify_story_video_ad")?.onPreferenceClickListener = this
checkCompatibleVersion()
searchItems = retrieve(preferenceScreen)
checkUpdate()
Expand Down Expand Up @@ -866,6 +868,61 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
return true
}

private fun onPurifyStoryVideoAdClick(): Boolean {
AlertDialog.Builder(activity).apply {
val tagMap = linkedMapOf(
"ad" to "广告(推荐勾选)",
"short" to "短剧(推荐勾选)",
"shopping" to "购物(推荐勾选)",
"tv" to "电视剧(强烈不推荐勾选,此处仅为视频同款电视剧,勾选后将无法见带有此标签视频!",
"doc" to "纪录片(强烈不推荐勾选,此处仅为视频同款纪录片,勾选后将无法见带有此标签视频!)",
"ent" to "娱乐(强烈不推荐勾选,此处仅为视频同款内容,勾选后将无法见带有此标签视频!)",
"movie" to "电影(强烈不推荐勾选,此处仅为视频同款电影,勾选后将无法见带有此标签视频!)",
"music" to "音乐(强烈不推荐勾选,此处仅为视频同款音乐,勾选后将无法看见带有此标签视频!",
"topic" to "话题(强烈不推荐勾选,此处仅为视频相关话题,勾选后将无法看见带有此标签视频!",
)

val prefKey = "purify_story_video_ad_tags"
val oldPurifyAdTags = sPrefs.getStringSet(prefKey, emptySet()) ?: emptySet()


val keys = tagMap.keys.toList()
val values = tagMap.values.toTypedArray()

val checkedTags = BooleanArray(keys.size) { index ->
keys[index] in oldPurifyAdTags
}


setTitle(context.getString(R.string.purify_story_video_ad_title))
setPositiveButton(context.getString(android.R.string.ok)) { _, _ ->
val selected = mutableSetOf<String>()
for (i in keys.indices) {
if (checkedTags[i]) selected.add(keys[i])
}
sPrefs.edit().putStringSet(prefKey, selected).apply()
Toast.makeText(activity, "已保存净化选项,重启客户端生效", Toast.LENGTH_SHORT).show()
}

setNegativeButton(android.R.string.cancel, null)

setNeutralButton("重置") { _, _ ->
sPrefs.edit().remove(prefKey).apply()
}

setMultiChoiceItems(values, checkedTags) { _, which, isChecked ->
checkedTags[which] = isChecked
}
}.show()
return true
}

private fun updatePurifyStoryVideoAdBlockedCount() {
val blockedCount = sPrefs.getInt("purify_story_video_ad_blocked_count", 0)
findPreference("purify_story_video_ad")?.summary = getString(R.string.purify_story_video_ad_summary) +
"(累计拦截 $blockedCount 条)"
}

@Deprecated("Deprecated in Java")
override fun onPreferenceClick(preference: Preference) = when (preference.key) {
"version" -> onVersionClick()
Expand All @@ -887,6 +944,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
"filter_search" -> onFilterSearchClick()
"filter_comment" -> onFilterCommentClick()
"copy_access_key" -> onCopyAccessKeyClick()
"purify_story_video_ad" -> onPurifyStoryVideoAdClick()
else -> false
}
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/me/iacn/biliroaming/XposedInit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class XposedInit : IXposedHookLoadPackage, IXposedHookZygoteInit {
startHook { SpeedHook(lpparam.classLoader) }
startHook { MultiWindowHook(lpparam.classLoader) }
startHook { LiveQualityHook(lpparam.classLoader) }
startHook { StoryPlayerAdHook(lpparam.classLoader) }
}

lpparam.processName.endsWith(":web") -> {
Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/me/iacn/biliroaming/hook/StoryPlayerAdHook.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package me.iacn.biliroaming.hook

import me.iacn.biliroaming.utils.Log
import me.iacn.biliroaming.utils.from
import me.iacn.biliroaming.utils.hookBeforeMethod
import me.iacn.biliroaming.utils.sPrefs

class StoryPlayerAdHook(classLoader: ClassLoader) : BaseHook(classLoader) {
override fun startHook() {


val purifyTags = sPrefs.getStringSet("purify_story_video_ad_tags", emptySet()) ?: emptySet()
if (purifyTags.isEmpty()) return

Log.d("startHook: StoryPlayerAd, purifyTags: ${purifyTags}")

"com.bilibili.video.story.player.StoryPagerPlayer".from(mClassLoader)
?.hookBeforeMethod("n1", List::class.java) { params ->
val storyDetailList = params.args[0] as? MutableList<*> ?: return@hookBeforeMethod
val toRemove = mutableListOf<Any>()

storyDetailList.forEach {
val storyDetail = it!!::class.java
val getCartIconInfoMethod = storyDetail.getDeclaredMethod("getCartIconInfo")
val isAdMethod = storyDetail.getDeclaredMethod("isAd")
getCartIconInfoMethod.isAccessible = true
isAdMethod.isAccessible = true

val isAd = isAdMethod.invoke(it) as? Boolean

var cartInfoText: String? = null
val cartIconInfo = getCartIconInfoMethod.invoke(it)
if (cartIconInfo != null) {
val cartClass = cartIconInfo.javaClass
val getEntryTextMethod = cartClass.getDeclaredMethod("getEntryText")
getEntryTextMethod.isAccessible = true
cartInfoText = getEntryTextMethod.invoke(cartIconInfo) as? String
}

val shouldRemove = when {
"ad" in purifyTags && isAd == true -> true
"short" in purifyTags && cartInfoText == "短剧" -> true
"shopping" in purifyTags && cartInfoText == "购物" -> true
"tv" in purifyTags && cartInfoText == "电视剧" -> true
"doc" in purifyTags && cartInfoText == "纪录片" -> true
"ent" in purifyTags && cartInfoText == "娱乐" -> true
"movie" in purifyTags && cartInfoText == "电影" -> true
"music" in purifyTags && cartInfoText == "音乐" -> true
"topic" in purifyTags && cartInfoText == "话题" -> true
else -> false
}
if (shouldRemove) {
toRemove.add(it)
}
}

storyDetailList.removeAll(toRemove.toSet())
val blockedCount = sPrefs.getInt("purify_story_video_ad_blocked_count", 0)
sPrefs.edit().putInt("purify_story_video_ad_blocked_count", blockedCount + toRemove.size).apply()
}

}


}
4 changes: 3 additions & 1 deletion app/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -282,5 +282,7 @@
<string name="pegasus_cover_ratio_summary">自訂首頁推薦小卡(雙列顯示的)封面比例</string>
<string name="filter_search_remove_relate_promote">搜尋結果移除推廣</string>
<string name="skip_reward_ad_title">跳過視頻激勵廣告</string>
<string name="skip_reward_ad_summary">受不了了!我要看個爽!(需重啟兩次嗶哩嗶哩)</string>
<string name="skip_reward_ad_summary">有了這個,終於能過第二關了😋(需重啟兩次嗶哩嗶哩)</string>
<string name="purify_story_video_ad_title">淨化豎屏模式廣告/推廣</string>
<string name="purify_story_video_ad_summary">有了這個,連第一關都看不到了😭</string>
</resources>
4 changes: 3 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -307,5 +307,7 @@
<string name="no_live_mask_title">隐藏直播模糊遮罩</string>
<string name="no_live_mask_summary">隐藏部分直播的模糊遮罩</string>
<string name="skip_reward_ad_title">跳过视频激励广告</string>
<string name="skip_reward_ad_summary">受不了了!我要看个爽!(需重启两次哔哩哔哩)</string>
<string name="skip_reward_ad_summary">有了这个,终于能过第二关了😋(需重启两次哔哩哔哩)</string>
<string name="purify_story_video_ad_title">净化竖屏模式广告/推广</string>
<string name="purify_story_video_ad_summary">有了这个,连第一关都看不到了😭</string>
</resources>
5 changes: 5 additions & 0 deletions app/src/main/res/xml/prefs_setting.xml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@
android:key="skip_reward_ad"
android:summary="@string/skip_reward_ad_summary"
android:title="@string/skip_reward_ad_title" />
<Preference
android:dependency="hidden"
android:key="purify_story_video_ad"
android:summary="@string/purify_story_video_ad_summary"
android:title="@string/purify_story_video_ad_title" />
<SwitchPreference
android:dependency="hidden"
android:key="purify_game"
Expand Down