-
Notifications
You must be signed in to change notification settings - Fork 327
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add Remove the relationship identifier from the stranger’s profile card
- Loading branch information
suzhelan
committed
Nov 22, 2023
1 parent
1d40e82
commit e2cae28
Showing
7 changed files
with
530 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ app/src/main/gen/ | |
app/src/main/bin/ | ||
cmake-build-* | ||
release/ | ||
|
||
debug/ | ||
# Files for the ART/Dalvik VM | ||
*.dex | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
app/src/main/java/top/linl/hook/OffRelationshipIdentification.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "精简陌生人资料卡你们的关系标识"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.