Skip to content

Commit

Permalink
I need more checks!
Browse files Browse the repository at this point in the history
  • Loading branch information
shatyuka committed Mar 9, 2024
1 parent 7b83473 commit 63f72bf
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 66 deletions.
12 changes: 12 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/Helper.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

Expand Down Expand Up @@ -245,4 +246,15 @@ public static Method getMethodByParameterTypes(Class<?> clazz, int skip, Class<?
}
return null;
}

public static Field findFieldByType(Class<?> clazz, Class<?> type) {
Optional<Field> fieldOptional = Arrays.stream(clazz.getDeclaredFields())
.filter(f -> f.getType() == type).findFirst();
if (!fieldOptional.isPresent())
return null;

Field field = fieldOptional.get();
field.setAccessible(true);
return field;
}
}
21 changes: 13 additions & 8 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/FeedTopHotBanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@ public String getName() {

@Override
public void init(ClassLoader classLoader) throws Throwable {
feedTopHotAutoJacksonDeserializer = classLoader.loadClass("com.zhihu.android.api.model.FeedTopHotAutoJacksonDeserializer");
try {
feedTopHotAutoJacksonDeserializer = classLoader.loadClass("com.zhihu.android.api.model.FeedTopHotAutoJacksonDeserializer");
} catch (ClassNotFoundException ignore) {
}
}

@Override
public void hook() throws Throwable {
XposedBridge.hookAllMethods(feedTopHotAutoJacksonDeserializer, "deserialize", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_feedtophot", false)) {
param.setResult(null);
if (feedTopHotAutoJacksonDeserializer != null) {
XposedBridge.hookAllMethods(feedTopHotAutoJacksonDeserializer, "deserialize", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_feedtophot", false)) {
param.setResult(null);
}
}
}
});
});
}
}
}
68 changes: 36 additions & 32 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/FollowButton.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
Expand All @@ -32,46 +33,49 @@ public String getName() {

@Override
public void init(ClassLoader classLoader) throws Throwable {
followWithAvatarView = classLoader.loadClass("com.zhihu.android.unify_interactive.view.follow.FollowWithAvatarView");
bottomReactionView = classLoader.loadClass("com.zhihu.android.mixshortcontainer.function.mixup.view.BottomReactionView");
try {
followWithAvatarView = classLoader.loadClass("com.zhihu.android.unify_interactive.view.follow.FollowWithAvatarView");
bottomReactionView = classLoader.loadClass("com.zhihu.android.mixshortcontainer.function.mixup.view.BottomReactionView");

followPeopleButton = classLoader.loadClass("com.zhihu.android.unify_interactive.view.follow.FollowPeopleButton");
zHAuthorInfoView = classLoader.loadClass("com.zhihu.android.mixshortcontainer.function.mixup.author.ZHAuthorInfoView");
followPeopleButton = classLoader.loadClass("com.zhihu.android.unify_interactive.view.follow.FollowPeopleButton");
zHAuthorInfoView = classLoader.loadClass("com.zhihu.android.mixshortcontainer.function.mixup.author.ZHAuthorInfoView");

followWithAvatarViewField = findFieldByType(bottomReactionView, followWithAvatarView);
followPeopleButtonField = findFieldByType(zHAuthorInfoView, followPeopleButton);
followWithAvatarViewField = Helper.findFieldByType(bottomReactionView, followWithAvatarView);
followPeopleButtonField = Helper.findFieldByType(zHAuthorInfoView, followPeopleButton);
} catch (ClassNotFoundException ignore) {
}
}

@Override
public void hook() throws Throwable {
XposedBridge.hookAllMethods(bottomReactionView, "setData", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_subscribe", false)) {
// 去除底部关注(带头像)
FrameLayout followWithAvatarViewInstance = (FrameLayout) followWithAvatarViewField.get(param.thisObject);
followWithAvatarViewInstance.setVisibility(View.GONE);
if (followWithAvatarViewField != null) {
XposedBridge.hookAllMethods(bottomReactionView, "setData", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_subscribe", false)) {
// 去除底部关注(带头像)
FrameLayout followWithAvatarViewInstance = (FrameLayout) followWithAvatarViewField.get(param.thisObject);
if (followWithAvatarViewInstance != null) {
followWithAvatarViewInstance.setVisibility(View.GONE);
}
}
}
}
});
});
}

XposedBridge.hookAllMethods(zHAuthorInfoView, "setData", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_subscribe", false)) {
// 去除顶部关注
ViewGroup followPeopleButtonFieldInstance = (ViewGroup) followPeopleButtonField.get(param.thisObject);
followPeopleButtonFieldInstance.setVisibility(View.GONE);
if (followPeopleButtonField != null) {
XposedBridge.hookAllMethods(zHAuthorInfoView, "setData", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_subscribe", false)) {
// 去除顶部关注
ViewGroup followPeopleButtonFieldInstance = (ViewGroup) followPeopleButtonField.get(param.thisObject);
if (followPeopleButtonFieldInstance != null) {
followPeopleButtonFieldInstance.setVisibility(View.GONE);
}
}
}
}
});
}

private Field findFieldByType(Class<?> clazz, Class<?> type) {
Field field = Arrays.stream(clazz.getDeclaredFields())
.filter(f -> f.getType() == type).findFirst().get();

field.setAccessible(true);
return field;
});
}
}
}
28 changes: 16 additions & 12 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/HeadZoneBanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import de.robv.android.xposed.XposedBridge;

public class HeadZoneBanner implements IHook {
static Class<?> rankFeedList;
static Class<?> feedsHotListFragment2;

static Field head_zone;
Expand All @@ -20,21 +19,26 @@ public String getName() {

@Override
public void init(ClassLoader classLoader) throws Throwable {
rankFeedList = classLoader.loadClass("com.zhihu.android.api.model.RankFeedList");
head_zone = rankFeedList.getDeclaredField("head_zone");
head_zone.setAccessible(true);
feedsHotListFragment2 = classLoader.loadClass("com.zhihu.android.app.feed.ui.fragment.FeedsHotListFragment2");
try {
Class<?> rankFeedList = classLoader.loadClass("com.zhihu.android.api.model.RankFeedList");
head_zone = rankFeedList.getDeclaredField("head_zone");
head_zone.setAccessible(true);
feedsHotListFragment2 = classLoader.loadClass("com.zhihu.android.app.feed.ui.fragment.FeedsHotListFragment2");
} catch (ClassNotFoundException | NoSuchFieldException ignore) {
}
}

@Override
public void hook() throws Throwable {
XposedBridge.hookAllMethods(feedsHotListFragment2, "postRefreshSucceed", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws IllegalAccessException {
if (Helper.prefs.getBoolean("switch_mainswitch", false)) {
head_zone.set(param.args[0], null);
if (feedsHotListFragment2 != null && head_zone != null) {
XposedBridge.hookAllMethods(feedsHotListFragment2, "postRefreshSucceed", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws IllegalAccessException {
if (Helper.prefs.getBoolean("switch_mainswitch", false)) {
head_zone.set(param.args[0], null);
}
}
}
});
});
}
}
}
31 changes: 17 additions & 14 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/MineHybridView.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.shatyuka.zhiliao.Helper;

import java.lang.reflect.Field;
import java.util.Arrays;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
Expand All @@ -23,25 +22,29 @@ public String getName() {

@Override
public void init(ClassLoader classLoader) throws Throwable {
mineTabFragment = classLoader.loadClass("com.zhihu.android.app.ui.fragment.more.mine.MineTabFragment");
mineHybridView = classLoader.loadClass("com.zhihu.android.app.ui.fragment.more.mine.widget.MineHybridView");
try {
mineTabFragment = classLoader.loadClass("com.zhihu.android.app.ui.fragment.more.mine.MineTabFragment");
mineHybridView = classLoader.loadClass("com.zhihu.android.app.ui.fragment.more.mine.widget.MineHybridView");

mineHybridViewField = Arrays.stream(mineTabFragment.getDeclaredFields()).filter(field -> field.getType() == mineHybridView).findFirst().get();
mineHybridViewField.setAccessible(true);
mineHybridViewField = Helper.findFieldByType(mineTabFragment, mineHybridView);
} catch (ClassNotFoundException ignore) {
}
}

@Override
public void hook() throws Throwable {
XposedBridge.hookAllMethods(mineTabFragment, "onCreateView", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_minehybrid", false)) {
View mineHybridView = (View) mineHybridViewField.get(param.thisObject);
if (mineHybridView != null) {
mineHybridView.setVisibility(View.GONE);
if (mineHybridViewField != null) {
XposedBridge.hookAllMethods(mineTabFragment, "onCreateView", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_minehybrid", false)) {
View mineHybridView = (View) mineHybridViewField.get(param.thisObject);
if (mineHybridView != null) {
mineHybridView.setVisibility(View.GONE);
}
}
}
}
});
});
}
}
}
24 changes: 24 additions & 0 deletions app/src/test/java/com/shatyuka/zhiliao/HookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
import com.shatyuka.zhiliao.hooks.CustomFilter;
import com.shatyuka.zhiliao.hooks.ExternLink;
import com.shatyuka.zhiliao.hooks.FeedAd;
import com.shatyuka.zhiliao.hooks.FeedTopHotBanner;
import com.shatyuka.zhiliao.hooks.FollowButton;
import com.shatyuka.zhiliao.hooks.HeadZoneBanner;
import com.shatyuka.zhiliao.hooks.Horizontal;
import com.shatyuka.zhiliao.hooks.HotBanner;
import com.shatyuka.zhiliao.hooks.IHook;
import com.shatyuka.zhiliao.hooks.LaunchAd;
import com.shatyuka.zhiliao.hooks.LiveButton;
import com.shatyuka.zhiliao.hooks.MineHybridView;
import com.shatyuka.zhiliao.hooks.NavButton;
import com.shatyuka.zhiliao.hooks.NavRes;
import com.shatyuka.zhiliao.hooks.NextAnswer;
Expand Down Expand Up @@ -182,4 +186,24 @@ public void thirdPartyLoginTest() {
public void navResTest() {
checkHook(new NavRes());
}

@Test
public void feedTopHotBannerTest() {
checkHook(new FeedTopHotBanner());
}

@Test
public void headZoneBannerTest() {
checkHook(new HeadZoneBanner());
}

@Test
public void mineHybridViewTest() {
checkHook(new MineHybridView());
}

@Test
public void followButtonTest() {
checkHook(new FollowButton());
}
}

0 comments on commit 63f72bf

Please sign in to comment.