Skip to content

Commit

Permalink
feat: support filter comment base on author level
Browse files Browse the repository at this point in the history
  • Loading branch information
cxw620 committed Oct 2, 2023
1 parent 5b559e2 commit 7190e70
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 16 deletions.
35 changes: 35 additions & 0 deletions app/src/main/java/me/iacn/biliroaming/CommentFilterDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.view.inputmethod.EditorInfo
import android.widget.*
import me.iacn.biliroaming.utils.Log
import me.iacn.biliroaming.utils.dp
import me.iacn.biliroaming.utils.inflateLayout

class CommentFilterDialog(activity: Activity, prefs: SharedPreferences) :
BaseWidgetDialog(activity) {
Expand Down Expand Up @@ -47,6 +48,39 @@ class CommentFilterDialog(activity: Activity, prefs: SharedPreferences) :
).let { root.addView(it.first); it.second }
blockAtCommentSwitch.isChecked = prefs.getBoolean("comment_filter_block_at_comment", false)

val targetCommentAuthorLevelTitle =
categoryTitle(string(R.string.target_comment_author_level_title))
root.addView(targetCommentAuthorLevelTitle)

val seekBarView = context.inflateLayout(R.layout.seekbar_dialog)
val currentTargetCommentAuthorLevel =
prefs.getLong("target_comment_author_level", 0L).toInt()
val tvHint = seekBarView.findViewById<TextView>(R.id.tvHint).apply {
text = if (currentTargetCommentAuthorLevel == 0) "关闭" else context.getString(
R.string.danmaku_filter_weight_hint,
currentTargetCommentAuthorLevel
)
}
val seekBar = seekBarView.findViewById<SeekBar>(R.id.seekBar).apply {
max = 6
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar?, progress: Int, fromUser: Boolean
) {
tvHint.text =
if (progress == 0) "关闭" else context.getString(
R.string.danmaku_filter_weight_hint,
progress
)
}

override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
progress = currentTargetCommentAuthorLevel
}
root.addView(seekBarView)

setTitle(string(R.string.filter_comment_title))

setPositiveButton(android.R.string.ok) { _, _ ->
Expand All @@ -64,6 +98,7 @@ class CommentFilterDialog(activity: Activity, prefs: SharedPreferences) :
putStringSet("comment_filter_keyword_at_uid", uidGroup.getKeywords())
putBoolean("comment_filter_content_regex_mode", contentRegexMode)
putBoolean("comment_filter_block_at_comment", blockAtCommentSwitch.isChecked)
putLong("target_comment_author_level", seekBar.progress.toLong())
}.apply()
Log.toast(string(R.string.prefs_save_success_and_reboot))
}
Expand Down
47 changes: 31 additions & 16 deletions app/src/main/java/me/iacn/biliroaming/hook/ProtoBufHook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ProtoBufHook(classLoader: ClassLoader) : BaseHook(classLoader) {
sPrefs.getStringSet("comment_filter_keyword_at_upname", null).orEmpty()
}
val commentFilterBlockAtComment = sPrefs.getBoolean("comment_filter_block_at_comment", false)
val targetCommentAuthorLevel = sPrefs.getLong("target_comment_author_level", 0L)
val purifyCampus = sPrefs.getBoolean("purify_campus", false)
val blockWordSearch = sPrefs.getBoolean("block_word_search", false)
val blockModules = sPrefs.getBoolean("block_modules", false)
Expand Down Expand Up @@ -315,34 +316,48 @@ class ProtoBufHook(classLoader: ClassLoader) : BaseHook(classLoader) {
}
}

val needCommentFilter = hidden and (commentFilterBlockAtComment or commentFilterContents.isNotEmpty() or commentFilterAtUid.isNotEmpty() or commentFilterAtUpNames.isNotEmpty())
val needCommentFilter =
hidden && (commentFilterBlockAtComment || commentFilterContents.isNotEmpty() || commentFilterAtUid.isNotEmpty() || commentFilterAtUpNames.isNotEmpty() || targetCommentAuthorLevel != 0L)
if (needCommentFilter) {
val blockAtCommentSplitRegex = Regex("\\s+")
fun filterComment(replyInfo: Any?): Boolean {
if (replyInfo == null) return true
val content = replyInfo.getObjectField("content_")!!
val message = content.getObjectFieldAs<String>("message_")
if (commentFilterContents.isNotEmpty()) {
if (commentFilterContentRegexMode) {
if (commentFilterContentRegexes.any { it.matches(message) }) return false
} else {
if (commentFilterContents.any { message.contains(it) }) return false
}

fun Any.validCommentAuthorLevel(): Boolean {
if (targetCommentAuthorLevel == 0L) return true
val authorLevel = getObjectField("member_")?.getObjectFieldAs<Long>("level_") ?: 6L
return authorLevel >= targetCommentAuthorLevel
}

fun Any.validCommentContent(): Boolean {
val content = getObjectField("content_") ?: return true
val commentMessage = content.getObjectFieldAs<String>("message_")

val contentIsToBlock = commentFilterContents.isNotEmpty() && if (commentFilterContentRegexMode) {
commentFilterContentRegexes.any { commentMessage.contains(it) }
} else {
commentFilterContents.any { commentMessage.contains(it) }
}
if (commentFilterBlockAtComment && message.trim().split(blockAtCommentSplitRegex).all { it.startsWith("@") }) return false
if (contentIsToBlock) return false

if (commentFilterBlockAtComment && commentMessage.trim()
.split(blockAtCommentSplitRegex).all { it.startsWith("@") }
) return false

if (commentFilterAtUpNames.isEmpty() && commentFilterAtUid.isEmpty()) return true
val atNameToMid = content.getObjectFieldAs<Map<String, Long>>("atNameToMid_")
if (commentFilterAtUpNames.isNotEmpty() && atNameToMid.keys.any { it in commentFilterAtUpNames }) return false
return !(commentFilterAtUid.isNotEmpty() && atNameToMid.values.any { it in commentFilterAtUid })
return !(atNameToMid.keys.any { it in commentFilterAtUpNames } || atNameToMid.values.any { it in commentFilterAtUid })
}

fun Any.filterComment() = validCommentAuthorLevel() && validCommentContent()

"com.bapis.bilibili.main.community.reply.v1.MainListReply".from(mClassLoader)
?.hookAfterMethod("getRepliesList") { p ->
val l = p.result as? List<*> ?: return@hookAfterMethod
p.result = l.filter { filterComment(it) }
p.result = l.filter { it?.filterComment() ?: true }
}
"com.bapis.bilibili.main.community.reply.v1.ReplyInfo".from(mClassLoader)
?.hookAfterMethod("getRepliesList") { p ->
val l = p.result as? List<*> ?: return@hookAfterMethod
p.result = l.filter { filterComment(it) }
p.result = l.filter { it?.filterComment() ?: true }
}
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@
<string name="keyword_group_name_at_up">\@的用户名</string>
<string name="keyword_group_name_at_uid">\@的uid</string>
<string name="comment_filter_block_at_comment_title">屏蔽只含\@的评论</string>
<string name="target_comment_author_level_title">屏蔽指定等级以下用户评论</string>
<string name="pegasus_cover_ratio_title">推荐封面比例</string>
<string name="pegasus_cover_ratio_summary">自定义首页推荐小卡(双列显示的)封面比例</string>
</resources>

0 comments on commit 7190e70

Please sign in to comment.