Skip to content

Commit 660510c

Browse files
committed
Fix toast viewer for new WhatsApp versions
This commit adapts the toast viewer feature to support changes in recent WhatsApp versions where `onInsertReceipt` now receives a `Collection` instead of individual arguments.
1 parent 23fb668 commit 660510c

File tree

5 files changed

+81
-35
lines changed

5 files changed

+81
-35
lines changed

app/src/main/java/com/wmods/wppenhacer/xposed/core/WppCore.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public class WppCore {
6262
public static BaseClient client;
6363
private static Object mCachedMessageStore;
6464
private static Class<?> mSettingsNotificationsClass;
65+
private static Method convertLidToJid;
66+
67+
private static Object mWaJidMapRepository;
6568

6669

6770
public static void Initialize(ClassLoader loader, XSharedPreferences pref) throws Exception {
@@ -108,6 +111,15 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
108111
}
109112
});
110113

114+
// WaJidMap
115+
convertLidToJid = Unobfuscator.loadConvertLidToJid(loader);
116+
XposedBridge.hookAllConstructors(convertLidToJid.getDeclaringClass(), new XC_MethodHook() {
117+
@Override
118+
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
119+
mWaJidMapRepository = param.thisObject;
120+
}
121+
});
122+
111123
// Load wa database
112124
loadWADatabase();
113125

@@ -117,6 +129,17 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
117129

118130
}
119131

132+
public static Object convertLidToJid(Object lid) {
133+
if (lid == null) return null;
134+
if (!getRawString(lid).contains("@lid")) return lid;
135+
try {
136+
return ReflectionUtils.callMethod(convertLidToJid, mWaJidMapRepository, lid);
137+
} catch (Exception e) {
138+
XposedBridge.log(e);
139+
}
140+
return lid;
141+
}
142+
120143
public static void initBridge(Context context) throws Exception {
121144
var prefsCacheHooks = UnobfuscatorCache.getInstance().sPrefsCacheHooks;
122145
int preferredOrder = prefsCacheHooks.getInt("preferredOrder", 1); // 0 for ProviderClient first, 1 for BridgeClient first

app/src/main/java/com/wmods/wppenhacer/xposed/core/devkit/Unobfuscator.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.util.ArrayList;
4646
import java.util.Arrays;
4747
import java.util.Calendar;
48+
import java.util.Collection;
4849
import java.util.Collections;
4950
import java.util.Date;
5051
import java.util.HashMap;
@@ -56,6 +57,7 @@
5657
import java.util.TimerTask;
5758
import java.util.stream.Collectors;
5859

60+
import de.robv.android.xposed.XposedBridge;
5961
import de.robv.android.xposed.XposedHelpers;
6062

6163
public class Unobfuscator {
@@ -1462,14 +1464,10 @@ public synchronized static Method loadNextStatusRunMethod(ClassLoader classLoade
14621464

14631465
public synchronized static Method loadOnInsertReceipt(ClassLoader classLoader) throws Exception {
14641466
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
1465-
var methods = dexkit.findMethod(FindMethod.create().matcher(MethodMatcher.create().addUsingString("INSERT_RECEIPT_USER")));
1466-
for (var method : methods) {
1467-
var params = method.getParamTypeNames();
1468-
if (!params.isEmpty() && "com.whatsapp.jid.UserJid".equals(params.get(0))) {
1469-
return method.getMethodInstance(classLoader);
1470-
}
1471-
}
1472-
throw new RuntimeException("OnInsertReceipt method not found");
1467+
var method = dexkit.findMethod(FindMethod.create().matcher(MethodMatcher.create().addUsingString("INSERT_RECEIPT_USER").paramCount(1))).singleOrNull();
1468+
if (method == null)
1469+
throw new RuntimeException("OnInsertReceipt method not found");
1470+
return method.getMethodInstance(classLoader);
14731471
});
14741472

14751473
}
@@ -2014,4 +2012,8 @@ public static Method loadAddOptionSearchBarMethod(ClassLoader classLoader) throw
20142012
public static Method loadAddMenuAndroidX(ClassLoader classLoader) throws Exception {
20152013
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> findFirstMethodUsingStrings(classLoader, StringMatchType.Contains, "Maximum number of items supported by"));
20162014
}
2015+
2016+
public static Method loadConvertLidToJid(ClassLoader loader) throws Exception {
2017+
return findFirstMethodUsingStrings(loader, StringMatchType.Contains, "WaJidMapRepository/getJidByExistingAccountUserJidNoCreate");
2018+
}
20172019
}

app/src/main/java/com/wmods/wppenhacer/xposed/features/general/AntiRevoke.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ private int antiRevoke(FMessageWpp fMessage) {
229229
}
230230

231231
private void showToast(FMessageWpp fMessage) {
232-
var jidAuthor = WppCore.getRawString(fMessage.getKey().remoteJid);
232+
var jidAuthor = WppCore.getRawString(WppCore.convertLidToJid(fMessage.getKey().remoteJid));
233233
var messageSuffix = Utils.getApplication().getString(ResId.string.deleted_message);
234234
var isStatus = Objects.equals(WppCore.stripJID(jidAuthor), "status");
235235
if (isStatus) {
236236
messageSuffix = Utils.getApplication().getString(ResId.string.deleted_status);
237-
jidAuthor = WppCore.getRawString(fMessage.getUserJid());
237+
jidAuthor = WppCore.getRawString(WppCore.convertLidToJid(fMessage.getUserJid()));
238238
}
239239
if (TextUtils.isEmpty(jidAuthor)) return;
240240
String name = WppCore.getContactName(WppCore.createUserJid(jidAuthor));

app/src/main/java/com/wmods/wppenhacer/xposed/features/general/Others.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,13 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
301301
Object callinfo = XposedHelpers.callMethod(param.thisObject, "getCallInfo");
302302
if (callinfo == null) return;
303303
var userJid = XposedHelpers.callMethod(callinfo, "getPeerJid");
304+
if (WppCore.getRawString(userJid).contains("@lid"))
305+
userJid = WppCore.convertLidToJid(userJid);
304306

307+
Object finalUserJid = userJid;
305308
CompletableFuture.runAsync(() -> {
306309
try {
307-
showCallInformation(param.args[0], userJid);
310+
showCallInformation(param.args[0], finalUserJid);
308311
} catch (Exception e) {
309312
logDebug(e);
310313
}

app/src/main/java/com/wmods/wppenhacer/xposed/features/others/ToastViewer.java

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import com.wmods.wppenhacer.xposed.utils.ResId;
1717
import com.wmods.wppenhacer.xposed.utils.Utils;
1818

19+
import java.util.Collection;
20+
import java.util.Collections;
1921
import java.util.HashMap;
2022
import java.util.Map;
2123
import java.util.Objects;
@@ -47,39 +49,55 @@ public void doHook() throws Throwable {
4749
var toastViewedMessage = prefs.getBoolean("toast_viewed_message", false);
4850

4951
var onInsertReceipt = Unobfuscator.loadOnInsertReceipt(classLoader);
52+
5053
XposedBridge.hookMethod(onInsertReceipt, new XC_MethodHook() {
5154
@Override
5255
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
53-
int type = ReflectionUtils.getArg(param.args, Integer.class, 0);
54-
long id = ReflectionUtils.getArg(param.args, Long.class, 0);
55-
if (type != 13) return;
56-
var jidClass = classLoader.loadClass("com.whatsapp.jid.Jid");
57-
var PhoneUserJid = ReflectionUtils.getArg(param.args, jidClass, 0);
58-
AtomicReference<Object> fmessage = new AtomicReference<>();
59-
try {
60-
fmessage.set(ReflectionUtils.getArg(param.args, FMessageWpp.TYPE, 0));
61-
} catch (Exception ignored) {
62-
}
63-
CompletableFuture.runAsync(() -> {
64-
var raw = WppCore.getRawString(PhoneUserJid);
65-
var UserJid = WppCore.createUserJid(raw);
66-
var contactName = WppCore.getContactName(UserJid);
67-
var rowId = id;
56+
processNewWA(param, toastViewedMessage, toastViewedStatus);
57+
}
58+
});
59+
}
60+
61+
private void processNewWA(XC_MethodHook.MethodHookParam param, boolean toastViewedMessage, boolean toastViewedStatus) throws ClassNotFoundException, IllegalAccessException {
62+
Collection collection = Collections.emptyList();
63+
if (!(param.args[0] instanceof Collection)){
64+
collection = Collections.singleton(param.args[0]);
65+
}
66+
var jidClass = classLoader.loadClass("com.whatsapp.jid.Jid");
67+
for (var messageStatusUpdateReceipt : collection) {
68+
var fieldByType = ReflectionUtils.getFieldByType(messageStatusUpdateReceipt.getClass(), int.class);
69+
var fieldId = ReflectionUtils.getFieldByType(messageStatusUpdateReceipt.getClass(), long.class);
70+
var fieldByUserJid = ReflectionUtils.getFieldByExtendType(messageStatusUpdateReceipt.getClass(), jidClass);
71+
var fieldMessage = ReflectionUtils.getFieldByExtendType(messageStatusUpdateReceipt.getClass(), FMessageWpp.TYPE);
72+
int type = fieldByType.getInt(messageStatusUpdateReceipt);
73+
long id = fieldId.getLong(messageStatusUpdateReceipt);
74+
if (type != 13) return;
75+
var PhoneUserJid = fieldByUserJid.get(messageStatusUpdateReceipt);
76+
AtomicReference<Object> fmessage = new AtomicReference<>();
77+
try {
78+
fmessage.set(fieldMessage.get(messageStatusUpdateReceipt));
79+
} catch (Exception ignored) {
80+
}
81+
CompletableFuture.runAsync(() -> {
82+
var raw = WppCore.getRawString(PhoneUserJid).replace(".0:0", "");
83+
var UserJid = WppCore.createUserJid(raw);
84+
var contactName = WppCore.getContactName(UserJid);
85+
var rowId = id;
6886

69-
if (TextUtils.isEmpty(contactName)) contactName = WppCore.stripJID(raw);
87+
if (TextUtils.isEmpty(contactName)) contactName = WppCore.stripJID(raw);
7088

71-
var sql = MessageStore.getInstance().getDatabase();
89+
var sql = MessageStore.getInstance().getDatabase();
7290

73-
if (fmessage.get() != null) {
74-
rowId = new FMessageWpp(fmessage.get()).getRowId();
75-
}
91+
if (fmessage.get() != null) {
92+
rowId = new FMessageWpp(fmessage.get()).getRowId();
93+
}
7694

77-
checkDataBase(sql, rowId, contactName, raw, toastViewedMessage, toastViewedStatus);
78-
});
79-
}
80-
});
95+
checkDataBase(sql, rowId, contactName, raw, toastViewedMessage, toastViewedStatus);
96+
});
97+
}
8198
}
8299

100+
83101
@NonNull
84102
@Override
85103
public String getPluginName() {

0 commit comments

Comments
 (0)