Skip to content

Commit

Permalink
add Remove the relationship identifier from the stranger’s profile card
Browse files Browse the repository at this point in the history
  • Loading branch information
suzhelan committed Nov 22, 2023
1 parent 1d40e82 commit e2cae28
Show file tree
Hide file tree
Showing 7 changed files with 530 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ app/src/main/gen/
app/src/main/bin/
cmake-build-*
release/

debug/
# Files for the ART/Dalvik VM
*.dex

Expand Down
2 changes: 1 addition & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
-keep class cc.microblock.** { *; }
-keep class com.tencent.mmkv.** { *; }
-keep class com.alphi.qhmk.** { *; }

-keep class top.linl.** { *; }
-keepclasseswithmembernames class * {
native <methods>;
}
Expand Down
66 changes: 66 additions & 0 deletions app/src/main/java/top/linl/hook/OffRelationshipIdentification.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package top.linl.hook;

import android.view.View;
import android.view.ViewParent;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import cc.ioctl.util.HookUtils;
import io.github.qauxv.base.annotation.FunctionHookEntry;
import io.github.qauxv.base.annotation.UiItemAgentEntry;
import io.github.qauxv.dsl.FunctionEntryRouter;
import io.github.qauxv.hook.CommonSwitchFunctionHook;
import io.github.qauxv.util.Initiator;
import java.lang.reflect.Method;
import top.linl.util.FieIdUtils;
import top.linl.util.MethodTool;


@FunctionHookEntry
@UiItemAgentEntry
public class OffRelationshipIdentification extends CommonSwitchFunctionHook {

public static final OffRelationshipIdentification INSTANCE = new OffRelationshipIdentification();

@Override
protected boolean initOnce() throws Exception {
Class<?> profileInStepComponentClass = Initiator.loadClass("com.tencent.mobileqq.profilecard.component.ProfileInStepComponent");

Method method = profileInStepComponentClass.getDeclaredMethod(
"onDataUpdate",
Initiator.loadClass("com.tencent.mobileqq.profilecard.data.ProfileCardInfo"));
HookUtils.hookAfterIfEnabled(this, method, param -> {
Object recyclerView = FieIdUtils.getFirstField(param.thisObject,
Initiator.loadClass("com.tencent.biz.richframework.widget.listview.card.RFWCardListView"));
if (recyclerView == null) {
return;
}
LinearLayout parent = MethodTool.find(recyclerView.getClass()).name("getParent").returnType(ViewParent.class).call(recyclerView);
if (parent == null) {
throw new RuntimeException("ParentLayout == null");
}
for (int i = 0; i < parent.getChildCount(); i++) {
if (parent.getChildAt(i).getVisibility() != View.GONE) {
parent.getChildAt(i).setVisibility(View.GONE);
}
}
if (parent.getVisibility() != View.GONE) {
parent.setVisibility(View.GONE);
}
}
);
return true;
}


@NonNull
@Override
public String[] getUiItemLocation() {
return FunctionEntryRouter.Locations.Simplify.UI_PROFILE;
}

@NonNull
@Override
public String getName() {
return "精简陌生人资料卡你们的关系标识";
}
}
50 changes: 50 additions & 0 deletions app/src/main/java/top/linl/util/CheckClassType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package top.linl.util;

public class CheckClassType {

//缩小范围匹配字节引用类型
public static boolean CheckClass(Class<?> clz, Class<?> convert) {
if (clz.equals(convert)) {
return true;
}
if (clz.equals(hasType(convert))) {
return true;
}
if (clz.isAssignableFrom(convert)) {
return true;
}
return false;
}

private static Class<?> hasType(Class<?> clz) {
try {
if (clz.equals(Boolean.class)) {
return boolean.class;
}
if (clz.equals(Integer.class)) {
return int.class;
}
if (clz.equals(Long.class)) {
return long.class;
}
if (clz.equals(Byte.class)) {
return byte.class;
}
if (clz.equals(Short.class)) {
return short.class;
}
if (clz.equals(Float.class)) {
return float.class;
}
if (clz.equals(Double.class)) {
return double.class;
}
if (clz.equals(Character.class)) {
return char.class;
}
return null;
} catch (Exception e) {
return null;
}
}
}
253 changes: 253 additions & 0 deletions app/src/main/java/top/linl/util/FieIdUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package top.linl.util;


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
* 反射字段工具
*/
public class FieIdUtils {

private static final HashMap<String, Field> FIELD_CACHE = new HashMap<>();

/**
* 设置字段内容
*
* @param target 运行时对象
* @param fieldName 字段名称
* @param value 设置后的字段内容
*/
public static void setField(Object target, String fieldName, Object value) throws Exception {
setField(target, target.getClass(), fieldName, value.getClass(), value);
}

/**
* 设置字段内容
*
* @param target 运行时对象
* @param fieldName 字段名称
* @param fieldType 字段类型
* @param value 设置后的字段内容
*/
public static void setField(Object target, String fieldName, Class<?> fieldType, Object value) throws Exception {
setField(target, target.getClass(), fieldName, fieldType, value);
}

/**
* 设置字段内容
*
* @param targetObj 运行时对象
* @param findClass 字段所处的类
* @param fieldName 字段名称
* @param fieldType 字段类型
* @param value 设置后的字段内容
*/
public static void setField(Object targetObj,
Class<?> findClass,
String fieldName,
Class<?> fieldType,
Object value) throws Exception {
Field field = findField(findClass, fieldName, fieldType);
field.set(targetObj, value);
}

/**
* 设置首个此类型的字段内容
*
* @param targetObj 运行时对象
* @param findClass 字段所处的类
* @param fieldType 字段类型
* @param value 设置后的字段内容
*/
public static void setFirstField(Object targetObj, Class<?> findClass, Class<?> fieldType, Object value) throws Exception {
Field field = findFirstField(findClass, fieldType);
field.set(targetObj, value);
}

/**
* 获取首个类型为fieldType的字段
*
* @param targetObj 运行时对象
* @param fieldName 字段名称
* @param fieldType 字段类型
*/
public static <T> T getField(Object targetObj, String fieldName, Class<?> fieldType) throws Exception {
return getField(targetObj, targetObj.getClass(), fieldName, fieldType);
}

/**
* 获取首个类型为fieldType的字段
*
* @param targetObj 运行时对象
* @param fieldType 字段类型
*/
public static <T> T getFirstField(Object targetObj, Class<?> fieldType) throws Exception {
return getFirstField(targetObj, targetObj.getClass(), fieldType);
}

/**
* 获取首个类型为fieldType的字段
*
* @param targetObj 运行时对象
* @param findClass 字段所处的类
* @param fieldType 字段类型
*/
public static <T> T getFirstField(Object targetObj, Class<?> findClass, Class<?> fieldType) throws Exception {
Field field = findFirstField(findClass, fieldType);
return (T) field.get(targetObj);
}

/**
* 获取字段内容
*
* @param targetObj 运行时对象
* @param findClass 字段所处的类
* @param fieldName 字段名称
* @param fieldType 字段类型
*/
public static <T> T getField(Object targetObj, Class<?> findClass, String fieldName,
Class<?> fieldType) throws Exception {
Field field = findField(findClass, fieldName, fieldType);
return (T) field.get(targetObj);
}

/**
* 查找并获取未知类型的静态字段
*
* @param findClass 要查找的字段
* @param findName 字段名称
*/
public static <T> T getStaticFieId(Class<?> findClass, String findName) throws Exception {
Field field = findUnknownTypeField(findClass, findName);
return (T) field.get(null);
}

/**
* 查找并获取静态字段
*
* @param findClass 要查找的字段
* @param findName 字段名称
* @param fieldType 字段类型
*/
public static <T> T getStaticFieId(Class<?> findClass, String findName, Class<?> fieldType) throws Exception {
Field field = findField(findClass, findName, fieldType);
return (T) field.get(null);
}

/**
* 获取未知类型的字段属性
*
* @param target 运行时对象
* @param fieldName 字段名
*/
public static <T> T getUnknownTypeField(Object target, String fieldName) throws Exception {
Field field = findUnknownTypeField(target.getClass(), fieldName);
return (T) field.get(target);
}

/**
* 获取未知类型但有字段名的字段
*
* @param findClass 查找的类
* @param fieldName 字段名
*/
public static Field findUnknownTypeField(Class<?> findClass, String fieldName) throws Exception {
String key = findClass.getName() + " " + fieldName;
if (FIELD_CACHE.containsKey(key)) {
return FIELD_CACHE.get(key);
}
Class<?> Check = findClass;
while (Check != null) {
for (Field f : Check.getDeclaredFields()) {
if (f.getName().equals(fieldName)) {
f.setAccessible(true);
FIELD_CACHE.put(key, f);
return f;
}
}
Check = Check.getSuperclass();
}
throw new ReflectException("查找不到未知类型但有字段名的字段 " + key);
}

/**
* 查找首个此类型的字段
*
* @param findClass 查找的类
* @param fieldType 查找类型
*/
public static Field findFirstField(Class<?> findClass, Class<?> fieldType) {
String fieldSignText = findClass.getName() + " type= " + fieldType.getName();
if (FIELD_CACHE.containsKey(fieldSignText)) {
return FIELD_CACHE.get(fieldSignText);
}
Class<?> FindClass = findClass;
while (FindClass != null) {
for (Field f : FindClass.getDeclaredFields()) {
if (f.getType() == fieldType) {
f.setAccessible(true);
FIELD_CACHE.put(fieldSignText, f);
return f;
}
}
FindClass = FindClass.getSuperclass();
}
throw new ReflectException("查找不到唯一此类型的字段 : " + fieldSignText);
}

/**
* 查找字段
*
* @param findClass 查找的类
* @param fieldName 字段名
* @param fieldType 字段类型
*/
public static Field findField(Class<?> findClass, String fieldName, Class<?> fieldType) {
String fieldSignText = findClass.getName() + " " + fieldType.getName() + " " + fieldName;
if (FIELD_CACHE.containsKey(fieldSignText)) {
return FIELD_CACHE.get(fieldSignText);
}
Class<?> FindClass = findClass;
while (FindClass != null) {
for (Field f : FindClass.getDeclaredFields()) {
if (f.getName().equals(fieldName) && CheckClassType.CheckClass(f.getType(), (fieldType))) {
f.setAccessible(true);
FIELD_CACHE.put(fieldSignText, f);
return f;
}
}
FindClass = FindClass.getSuperclass();
}
throw new ReflectException("查找不到字段 : " + fieldSignText);
}

/**
* 模糊查找字段
*
* @param findClass 要查找的类
* @param lookupConditions 判断字段是否符合条件
*/
public static Field[] fuzzyLookupFiled(Class<?> findClass, FuzzyLookupConditions lookupConditions) {
List<Field> fieldList = new ArrayList<>();
for (Class<?> currentFindClass = findClass; currentFindClass != Object.class; currentFindClass = currentFindClass.getSuperclass()) {
for (Field field : currentFindClass.getDeclaredFields()) {
if (lookupConditions.isItCorrect(field)) {
field.setAccessible(true);
fieldList.add(field);
}
}
}
if (fieldList.isEmpty()) {
throw new ReflectException("模糊查找字段异常 : " + findClass.getName());
}
return fieldList.toArray(new Field[0]);
}

public interface FuzzyLookupConditions {

boolean isItCorrect(Field currentField);
}
}
Loading

0 comments on commit e2cae28

Please sign in to comment.