diff --git a/app/build.gradle b/app/build.gradle index 5008f981..402f0429 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { minSdk 28 targetSdk sdk versionCode gitCommitCount - versionName '2.9.7.1' + versionName '2.9.8' buildConfigField "String", "TARGET_VERSION", "\"12.58.1.0\"" buildConfigField "String", "MIN_VERSION", "\"12.53.1.0\"" diff --git a/app/src/main/java/gm/tieba/tabswitch/XposedInit.java b/app/src/main/java/gm/tieba/tabswitch/XposedInit.java index 967f7e8c..2903ea67 100644 --- a/app/src/main/java/gm/tieba/tabswitch/XposedInit.java +++ b/app/src/main/java/gm/tieba/tabswitch/XposedInit.java @@ -55,6 +55,7 @@ import gm.tieba.tabswitch.hooker.eliminate.PurgeVideo; import gm.tieba.tabswitch.hooker.eliminate.RedTip; import gm.tieba.tabswitch.hooker.eliminate.RemoveUpdate; +import gm.tieba.tabswitch.hooker.eliminate.UserFilter; import gm.tieba.tabswitch.hooker.extra.ForbidGesture; import gm.tieba.tabswitch.hooker.extra.Hide; import gm.tieba.tabswitch.hooker.extra.StackTrace; @@ -155,7 +156,8 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable { new MsgCenterTab(), new NotificationDetect(), new PurgeVideo(), - new SelectClipboard() + new SelectClipboard(), + new UserFilter() ); final var matchers = new ArrayList(hookers.size() + 2); matchers.add(new TbToast()); diff --git a/app/src/main/java/gm/tieba/tabswitch/hooker/TSPreference.java b/app/src/main/java/gm/tieba/tabswitch/hooker/TSPreference.java index dd0d4923..5ac716cd 100644 --- a/app/src/main/java/gm/tieba/tabswitch/hooker/TSPreference.java +++ b/app/src/main/java/gm/tieba/tabswitch/hooker/TSPreference.java @@ -193,8 +193,9 @@ private LinearLayout createRootPreference(final Activity activity) { preferenceLayout.addView(new SwitchButtonHolder(activity, "只推荐已关注的吧", "follow_filter", SwitchButtonHolder.TYPE_SWITCH)); preferenceLayout.addView(new SwitchButtonHolder(activity, "屏蔽首页视频贴", "purge_video", SwitchButtonHolder.TYPE_SWITCH)); preferenceLayout.addView(new SwitchButtonHolder(activity, "过滤首页推荐", "personalized_filter", SwitchButtonHolder.TYPE_DIALOG)); - preferenceLayout.addView(new SwitchButtonHolder(activity, "过滤帖子回复", "content_filter", SwitchButtonHolder.TYPE_DIALOG)); preferenceLayout.addView(new SwitchButtonHolder(activity, "过滤吧页面", "frs_page_filter", SwitchButtonHolder.TYPE_DIALOG)); + preferenceLayout.addView(new SwitchButtonHolder(activity, "过滤帖子回复", "content_filter", SwitchButtonHolder.TYPE_DIALOG)); + preferenceLayout.addView(new SwitchButtonHolder(activity, "过滤用户", "user_filter", SwitchButtonHolder.TYPE_DIALOG)); preferenceLayout.addView(TSPreferenceHelper.createTextView(isPurgeEnabled ? "别出新意" : "增加功能")); preferenceLayout.addView(new SwitchButtonHolder(activity, "浏览历史增加搜索", "history_cache", SwitchButtonHolder.TYPE_SWITCH)); diff --git a/app/src/main/java/gm/tieba/tabswitch/hooker/add/HistoryCache.java b/app/src/main/java/gm/tieba/tabswitch/hooker/add/HistoryCache.java index 9cb525cd..e8e2d946 100644 --- a/app/src/main/java/gm/tieba/tabswitch/hooker/add/HistoryCache.java +++ b/app/src/main/java/gm/tieba/tabswitch/hooker/add/HistoryCache.java @@ -2,6 +2,7 @@ import android.app.Activity; import android.app.AlertDialog; +import android.content.DialogInterface; import android.graphics.Color; import android.os.Bundle; import android.text.Editable; @@ -122,10 +123,13 @@ public void afterTextChanged(final Editable s) { linearLayout.addView(editText); + String currRegex = mRegex; + AlertDialog alert = new AlertDialog.Builder(currentActivity, isLightMode ? android.R.style.Theme_DeviceDefault_Light_Dialog_Alert : android.R.style.Theme_DeviceDefault_Dialog_Alert) .setTitle("搜索").setView(linearLayout) - .setNegativeButton(activity.getString(android.R.string.cancel), null) + .setOnCancelListener(dialog -> mRegex = currRegex) + .setNegativeButton(activity.getString(android.R.string.cancel), (dialogInterface, i) -> mRegex = currRegex) .setPositiveButton(activity.getString(android.R.string.ok), null).create(); alert.setOnShowListener(dialogInterface -> { diff --git a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/ContentFilter.java b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/ContentFilter.java index 09bd5879..cb270b7e 100644 --- a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/ContentFilter.java +++ b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/ContentFilter.java @@ -2,11 +2,7 @@ import androidx.annotation.NonNull; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; @@ -15,7 +11,6 @@ import gm.tieba.tabswitch.util.Parser; public class ContentFilter extends XposedContext implements IHooker, RegexFilter { - private final Set mIds = new HashSet<>(); @NonNull @Override @@ -32,11 +27,9 @@ protected void beforeHookedMethod(final MethodHookParam param) throws Throwable final var postList = (List) XposedHelpers.getObjectField(param.thisObject, "post_list"); if (postList == null) return; final var pattern = getPattern(); - initIdList(param.thisObject, pattern); postList.removeIf(o -> ((Integer) XposedHelpers.getObjectField(o, "floor") != 1) - && (pattern.matcher(Parser.parsePbContent(o, "content")).find() - || mIds.contains(XposedHelpers.getObjectField(o, "author_id")))); + && (pattern.matcher(Parser.parsePbContent(o, "content")).find())); } }); // 楼中楼:[\u202e|\ud83c\udd10-\ud83c\udd89] @@ -46,8 +39,7 @@ protected void beforeHookedMethod(final MethodHookParam param) throws Throwable final var subPostList = (List) XposedHelpers.getObjectField(param.thisObject, "sub_post_list"); if (subPostList == null) return; final var pattern = getPattern(); - subPostList.removeIf(o -> pattern.matcher(Parser.parsePbContent(o, "content")).find() - || mIds.contains(XposedHelpers.getObjectField(o, "author_id"))); + subPostList.removeIf(o -> pattern.matcher(Parser.parsePbContent(o, "content")).find()); } }); // 楼层回复 @@ -57,28 +49,8 @@ protected void beforeHookedMethod(final MethodHookParam param) throws Throwable final var subpostList = (List) XposedHelpers.getObjectField(param.thisObject, "subpost_list"); if (subpostList == null) return; final var pattern = getPattern(); - subpostList.removeIf(o -> { - if (pattern.matcher(Parser.parsePbContent(o, "content")).find()) { - return true; - } - - final var author = XposedHelpers.getObjectField(o, "author"); - final var authors = new String[]{(String) XposedHelpers.getObjectField(author, "name"), - (String) XposedHelpers.getObjectField(author, "name_show")}; - return Arrays.stream(authors).anyMatch(s -> pattern.matcher(s).find()); - }); + subpostList.removeIf(o -> pattern.matcher(Parser.parsePbContent(o, "content")).find()); } }); } - - private void initIdList(final Object thisObject, final Pattern pattern) { - final var userList = (List) XposedHelpers.getObjectField(thisObject, "user_list"); - for (final var user : userList) { - final var authors = new String[]{(String) XposedHelpers.getObjectField(user, "name"), - (String) XposedHelpers.getObjectField(user, "name_show")}; - if (Arrays.stream(authors).anyMatch(s -> pattern.matcher(s).find())) { - mIds.add(XposedHelpers.getObjectField(user, "id")); - } - } - } } diff --git a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/FrsPageFilter.java b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/FrsPageFilter.java index 9e364abc..a816e363 100644 --- a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/FrsPageFilter.java +++ b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/FrsPageFilter.java @@ -52,31 +52,6 @@ private void filterPageData(Object pageData) { } } } - - List components = (List) XposedHelpers.getObjectField(currFeed, "components"); - if (components != null ){ - for (var component: components) { - if (XposedHelpers.getObjectField(component, "component").toString().equals("feed_head")) { - Object feedHead = XposedHelpers.getObjectField(component, "feed_head"); - List mainData = (List) XposedHelpers.getObjectField(feedHead, "main_data"); - if (mainData != null) { - for (var feedHeadSymbol: mainData) { - Object feedHeadText = XposedHelpers.getObjectField(feedHeadSymbol, "text"); - if (feedHeadText != null) { - String username = (String) XposedHelpers.getObjectField(feedHeadText, "text"); - if (username != null) { - if (pattern.matcher(username).find()) { - return true; - } - break; - } - } - } - } - break; - } - } - } } return false; } diff --git a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/PersonalizedFilter.java b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/PersonalizedFilter.java index d42aad47..3f6d4f50 100644 --- a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/PersonalizedFilter.java +++ b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/PersonalizedFilter.java @@ -2,7 +2,6 @@ import androidx.annotation.NonNull; -import java.util.Arrays; import java.util.List; import de.robv.android.xposed.XC_MethodHook; @@ -32,16 +31,7 @@ protected void beforeHookedMethod(final MethodHookParam param) throws Throwable return true; } - final var strings = new String[]{(String) XposedHelpers.getObjectField(o, "title"), - (String) XposedHelpers.getObjectField(o, "fname")}; - if (Arrays.stream(strings).anyMatch(s -> pattern.matcher(s).find())) { - return true; - } - - final var author = XposedHelpers.getObjectField(o, "author"); - final var authors = new String[]{(String) XposedHelpers.getObjectField(author, "name"), - (String) XposedHelpers.getObjectField(author, "name_show")}; - return Arrays.stream(authors).anyMatch(s -> pattern.matcher(s).find()); + return pattern.matcher((String) XposedHelpers.getObjectField(o, "title")).find(); }); } }); diff --git a/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/UserFilter.java b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/UserFilter.java new file mode 100644 index 00000000..b77ee616 --- /dev/null +++ b/app/src/main/java/gm/tieba/tabswitch/hooker/eliminate/UserFilter.java @@ -0,0 +1,144 @@ +package gm.tieba.tabswitch.hooker.eliminate; + +import androidx.annotation.NonNull; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XposedHelpers; +import gm.tieba.tabswitch.XposedContext; +import gm.tieba.tabswitch.hooker.IHooker; + +public class UserFilter extends XposedContext implements IHooker, RegexFilter { + private final Set mIds = new HashSet<>(); + + @NonNull + @Override + public String key() { + return "user_filter"; + } + + @Override + public void hook() throws Throwable { + XposedHelpers.findAndHookMethod("tbclient.Personalized.DataRes$Builder", sClassLoader, "build", boolean.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { + final var threadList = (List) XposedHelpers.getObjectField(param.thisObject, "thread_list"); + if (threadList == null) return; + final var pattern = getPattern(); + threadList.removeIf(o -> { + final var author = XposedHelpers.getObjectField(o, "author"); + final var authors = new String[]{(String) XposedHelpers.getObjectField(author, "name"), + (String) XposedHelpers.getObjectField(author, "name_show")}; + return Arrays.stream(authors).anyMatch(s -> pattern.matcher(s).find()); + }); + } + }); + + XposedHelpers.findAndHookMethod("tbclient.FrsPage.PageData$Builder", sClassLoader, "build", boolean.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { + filterPageData(param.thisObject); + } + }); + + XposedHelpers.findAndHookMethod("tbclient.ThreadList.PageData$Builder", sClassLoader, "build", boolean.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { + filterPageData(param.thisObject); + } + }); + + // 楼层 + XposedHelpers.findAndHookMethod("tbclient.PbPage.DataRes$Builder", sClassLoader, "build", boolean.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { + final var postList = (List) XposedHelpers.getObjectField(param.thisObject, "post_list"); + if (postList == null) return; + final var pattern = getPattern(); + initIdList(param.thisObject, pattern); + + postList.removeIf(o -> ((Integer) XposedHelpers.getObjectField(o, "floor") != 1) + && mIds.contains(XposedHelpers.getObjectField(o, "author_id"))); + } + }); + // 楼中楼:[\u202e|\ud83c\udd10-\ud83c\udd89] + XposedHelpers.findAndHookMethod("tbclient.SubPost$Builder", sClassLoader, "build", boolean.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { + final var subPostList = (List) XposedHelpers.getObjectField(param.thisObject, "sub_post_list"); + if (subPostList == null) return; + subPostList.removeIf(o -> mIds.contains(XposedHelpers.getObjectField(o, "author_id"))); + } + }); + // 楼层回复 + XposedHelpers.findAndHookMethod("tbclient.PbFloor.DataRes$Builder", sClassLoader, "build", boolean.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { + final var subpostList = (List) XposedHelpers.getObjectField(param.thisObject, "subpost_list"); + if (subpostList == null) return; + final var pattern = getPattern(); + subpostList.removeIf(o -> { + final var author = XposedHelpers.getObjectField(o, "author"); + final var authors = new String[]{(String) XposedHelpers.getObjectField(author, "name"), + (String) XposedHelpers.getObjectField(author, "name_show")}; + return Arrays.stream(authors).anyMatch(s -> pattern.matcher(s).find()); + }); + } + }); + } + + private void filterPageData(Object pageData) { + List feedList = (List) XposedHelpers.getObjectField(pageData, "feed_list"); + if (feedList == null) return; + final var pattern = getPattern(); + feedList.removeIf( + o -> { + Object currFeed = XposedHelpers.getObjectField(o, "feed"); + if (currFeed != null) { + List components = (List) XposedHelpers.getObjectField(currFeed, "components"); + if (components != null ){ + for (var component: components) { + if (XposedHelpers.getObjectField(component, "component").toString().equals("feed_head")) { + Object feedHead = XposedHelpers.getObjectField(component, "feed_head"); + List mainData = (List) XposedHelpers.getObjectField(feedHead, "main_data"); + if (mainData != null) { + for (var feedHeadSymbol: mainData) { + Object feedHeadText = XposedHelpers.getObjectField(feedHeadSymbol, "text"); + if (feedHeadText != null) { + String username = (String) XposedHelpers.getObjectField(feedHeadText, "text"); + if (username != null) { + if (pattern.matcher(username).find()) { + return true; + } + break; + } + } + } + } + break; + } + } + } + } + return false; + } + ); + } + + private void initIdList(final Object thisObject, final Pattern pattern) { + final var userList = (List) XposedHelpers.getObjectField(thisObject, "user_list"); + for (final var user : userList) { + final var authors = new String[]{(String) XposedHelpers.getObjectField(user, "name"), + (String) XposedHelpers.getObjectField(user, "name_show")}; + if (Arrays.stream(authors).anyMatch(s -> pattern.matcher(s).find())) { + mIds.add(XposedHelpers.getObjectField(user, "id")); + } + } + } + +} diff --git a/app/src/main/java/gm/tieba/tabswitch/util/Parser.java b/app/src/main/java/gm/tieba/tabswitch/util/Parser.java index 13f23034..0abad942 100644 --- a/app/src/main/java/gm/tieba/tabswitch/util/Parser.java +++ b/app/src/main/java/gm/tieba/tabswitch/util/Parser.java @@ -1,7 +1,6 @@ package gm.tieba.tabswitch.util; import java.util.List; -import java.util.Locale; import de.robv.android.xposed.XposedHelpers; import gm.tieba.tabswitch.XposedContext; @@ -13,6 +12,6 @@ public static String parsePbContent(final Object instance, final String fieldNam for (int i = 0; i < contents.size(); i++) { pbContent.append(XposedHelpers.getObjectField(contents.get(i), "text")); } - return pbContent.toString().toLowerCase(Locale.CHINA); + return pbContent.toString(); } } diff --git a/app/src/main/java/gm/tieba/tabswitch/widget/TbEditText.java b/app/src/main/java/gm/tieba/tabswitch/widget/TbEditText.java deleted file mode 100644 index 88723749..00000000 --- a/app/src/main/java/gm/tieba/tabswitch/widget/TbEditText.java +++ /dev/null @@ -1,26 +0,0 @@ -package gm.tieba.tabswitch.widget; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.view.ViewGroup; -import android.widget.EditText; -import android.widget.LinearLayout; - -import gm.tieba.tabswitch.util.ReflectUtils; - -@SuppressLint("AppCompatCustomView") -public class TbEditText extends EditText { - public TbEditText(final Context context) { - super(context); - setFocusable(true); - setFocusableInTouchMode(true); - final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - setLayoutParams(layoutParams); - setTextColor(ReflectUtils.getColor("CAM_X0105")); - setHintTextColor(ReflectUtils.getColor("CAM_X0108")); - setTextSize(ReflectUtils.getDimenDip("fontsize36")); - setBackgroundResource(ReflectUtils.getDrawableId("blue_rectangle_input_bg")); - setMinWidth((int) ReflectUtils.getDimen("ds140")); - } -}