@@ -14,6 +14,32 @@ export default {
1414 whiteList : [ "https://*.facebook.com/*" , "https://*.messenger.com/*" ] ,
1515
1616 onDocumentStart : ( ) => {
17+ window . ufs_rvdfm_all_msgs = JSON . parse (
18+ localStorage . ufs_rvdfm_all_msgs || "[]"
19+ ) ;
20+ window . addEventListener ( "beforeunload" , ( ) => {
21+ localStorage . ufs_rvdfm_all_msgs = JSON . stringify (
22+ window . ufs_rvdfm_all_msgs
23+ ) ;
24+ } ) ;
25+ window . UfsChatType = {
26+ text : "chữ" ,
27+ image : "ảnh" ,
28+ video : "video" ,
29+ GIF : "gif" ,
30+ audio : "âm thanh" ,
31+ attachment : "đính kèm" ,
32+ sticker : "sticker" ,
33+ sound : "sound" ,
34+ add_reaction : "react" ,
35+ remove_reaction : "gỡ react" ,
36+ share_location : "vị trí" ,
37+ realtime_location : "vị trí thực" ,
38+ pending : "pending" ,
39+ user_data : "user_data" ,
40+ delete_msg : "delete_msg" ,
41+ } ;
42+
1743 const WebSocketOrig = window . WebSocket ;
1844 window . WebSocket = function fakeConstructor ( dt , config ) {
1945 // hàm hỗ trợ
@@ -35,23 +61,7 @@ export default {
3561 return ret ;
3662 } ;
3763
38- const ChatType = {
39- text : "text" ,
40- image : "image" ,
41- video : "video" ,
42- GIF : "gif" ,
43- audio : "audio" ,
44- attachment : "attachment" ,
45- sticker : "sticker" ,
46- add_reaction : "add_reaction" ,
47- remove_reaction : "remove_reaction" ,
48- share_location : "share_location" ,
49- pending : "pending" ,
50- user_data : "user_data" ,
51- delete_msg : "delete_msg" ,
52- } ;
53-
54- function findAllChatData ( all_strings ) {
64+ const findAllChatData = ( all_strings ) => {
5565 let chats = [ ] ;
5666 for ( let i = 0 ; i < all_strings . length ; i ++ ) {
5767 const str_i = all_strings [ i ] ;
@@ -61,7 +71,7 @@ export default {
6171 const content = all_strings [ i + 1 ] ;
6272 if ( content ) {
6373 chats . push ( {
64- type : ChatType . text ,
74+ type : window . UfsChatType . text ,
6575 content : content ,
6676 id : all_strings [ i + 2 ] ,
6777 } ) ;
@@ -76,14 +86,14 @@ export default {
7686 const isVideo = a1 ?. startsWith ( "video-" ) ;
7787 const isAudio = a1 ?. startsWith ( "audioclip-" ) ;
7888 const type = isImg
79- ? ChatType . image
89+ ? window . UfsChatType . image
8090 : isGif
81- ? ChatType . GIF
91+ ? window . UfsChatType . GIF
8292 : isVideo
83- ? ChatType . video
93+ ? window . UfsChatType . video
8494 : isAudio
85- ? ChatType . audio
86- : ChatType . attachment ;
95+ ? window . UfsChatType . audio
96+ : window . UfsChatType . attachment ;
8797
8898 for ( let j = i ; j < all_strings . length - 1 ; j ++ ) {
8999 if ( isMsgIdStr ( all_strings [ j ] ) ) {
@@ -101,50 +111,78 @@ export default {
101111 if (
102112 str_i === "insertMessage" &&
103113 isMsgIdStr ( all_strings [ i + 1 ] ) &&
104- isLink ( all_strings [ i + 6 ] )
114+ ( all_strings [ i - 1 ] . includes ( "nhãn dán" ) ||
115+ all_strings [ i - 1 ] . includes ( "sticker" ) )
105116 ) {
106117 chats . push ( {
107- type : ChatType . sticker ,
108- content : all_strings [ i + 6 ] ,
118+ type : window . UfsChatType . sticker ,
119+ content : parse (
120+ all_strings [ i + 6 ] . match ( / " p l a y a b l e U r l " : " ( .* ?) " / ) ?. [ 1 ] ||
121+ all_strings [ i + 9 ] . match ( / " p r e v i e w U r l " : " ( .* ?) " / ) ?. [ 1 ] ||
122+ ""
123+ ) ,
109124 id : all_strings [ i + 1 ] ,
110125 } ) ;
111126 }
112127
113- // Thả react
114- if ( str_i === "upsertReaction" && isMsgIdStr ( all_strings [ i + 1 ] ) ) {
128+ // Tin nhắn sound
129+ if (
130+ str_i === "insertMessage" &&
131+ isMsgIdStr ( all_strings [ i + 5 ] ) &&
132+ all_strings [ i - 1 ] . includes ( "sound" )
133+ ) {
115134 chats . push ( {
116- type : ChatType . add_reaction ,
117- content : all_strings [ i + 2 ] ,
118- id : all_strings [ i + 1 ] ,
135+ type : window . UfsChatType . sound ,
136+ content : parse (
137+ all_strings [ i + 1 ] || ""
138+ // all_strings[i + 7].match(/"playableUrl":"(.*?)"/)?.[1] || ""
139+ ) ,
140+ id : all_strings [ i + 5 ] ,
119141 } ) ;
120142 }
121143
144+ // Thả react
145+ // if (str_i === "upsertReaction" && isMsgIdStr(all_strings[i + 1])) {
146+ // chats.push({
147+ // type: ChatType.add_reaction,
148+ // content: all_strings[i + 2],
149+ // id: all_strings[i + 1],
150+ // });
151+ // }
152+
122153 // Gỡ react
123- if ( str_i === "deleteReaction" && isMsgIdStr ( all_strings [ i + 1 ] ) ) {
124- const id = all_strings [ i + 1 ] ;
125- const content =
126- rvdfm_all_msgs . find ( ( c ) => c . id === id ) ?. content || "" ;
154+ // if (str_i === "deleteReaction" && isMsgIdStr(all_strings[i + 1])) {
155+ // const id = all_strings[i + 1];
156+ // const content =
157+ // rvdfm_all_msgs.find((c) => c.id === id)?.content || "";
127158
128- chats . push ( {
129- type : ChatType . remove_reaction ,
130- content : content ,
131- id : id ,
132- } ) ;
133- }
159+ // chats.push({
160+ // type: ChatType.remove_reaction,
161+ // content: content,
162+ // id: id,
163+ // });
164+ // }
134165
135166 // Tin nhắn chia sẻ vị trí / vị trí trực tiếp
136- if (
137- str_i === "xma_live_location_sharing" &&
138- isMsgIdStr ( all_strings [ i - 2 ] ) &&
139- isLink ( all_strings [ i + 1 ] )
140- ) {
141- const link = all_strings [ i + 1 ] ;
142-
143- chats . push ( {
144- type : ChatType . share_location ,
145- content : link ,
146- id : all_strings [ i - 2 ] ,
147- } ) ;
167+ if ( str_i . includes ( "xma_live_location_sharing" ) ) {
168+ if ( isMsgIdStr ( all_strings [ i + 8 ] ) ) {
169+ chats . push ( {
170+ type : window . UfsChatType . share_location ,
171+ content : parse (
172+ all_strings [ i + 1 ] . match ( / " a c t i o n U r l " : " ( .* ?) " / ) || ""
173+ ) ,
174+ id : all_strings [ i + 8 ] ,
175+ } ) ;
176+ }
177+ if ( isMsgIdStr ( all_strings [ i - 10 ] ) ) {
178+ chats . push ( {
179+ type : window . UfsChatType . realtime_location ,
180+ content : parse (
181+ all_strings [ i + 1 ] . match ( / " a c t i o n U r l " : " ( .* ?) " / ) || ""
182+ ) ,
183+ id : all_strings [ i - 10 ] ,
184+ } ) ;
185+ }
148186 }
149187
150188 // Thông tin user
@@ -169,47 +207,68 @@ export default {
169207 // }
170208
171209 // Thu hồi tin nhắn
172- if (
173- str_i === "deleteThenInsertMessage" &&
174- isMsgIdStr ( all_strings [ i + 2 ] )
175- ) {
176- const id = all_strings [ i + 2 ] ;
177- const msgs =
178- rvdfm_all_msgs . filter (
179- ( c ) => c . id === id && c . type !== "Thu hồi"
180- ) || [ ] ;
210+ // if (
211+ // str_i === "deleteThenInsertMessage" &&
212+ // isMsgIdStr(all_strings[i + 2])
213+ // ) {
214+ // const id = all_strings[i + 2];
215+ // const msgs =
216+ // rvdfm_all_msgs.filter(
217+ // (c) => c.id === id && c.type !== "Thu hồi"
218+ // ) || [];
181219
182- chats . push ( {
183- type : ChatType . delete_msg ,
184- msgs : msgs ,
185- id : id ,
186- } ) ;
187- }
220+ // chats.push({
221+ // type: ChatType.delete_msg,
222+ // msgs: msgs,
223+ // id: id,
224+ // });
225+ // }
188226 }
189227
190228 // Chèn thời gian hiện tại vào
191- chats = chats . map ( ( _ ) => ( { ..._ , time : Date . now ( ) } ) ) ;
229+ chats = chats . map ( ( _ ) => ( { ..._ , saved_time : Date . now ( ) } ) ) ;
230+ return chats ;
231+ } ;
192232
193- console . log ( "Thông tin lọc được:" , chats ) ;
194- }
233+ const saveChatData = ( chats ) => {
234+ let oldData = window . ufs_rvdfm_all_msgs || [ ] ;
235+ let newData = [ ] ;
236+ for ( let c of chats ) {
237+ let isDuplicated =
238+ oldData . find ( ( m ) => JSON . stringify ( c ) === JSON . stringify ( m ) ) !=
239+ null ;
240+
241+ if ( ! isDuplicated ) newData . push ( c ) ;
242+ }
243+ window . ufs_rvdfm_all_msgs = oldData . concat ( newData ) ;
244+ } ;
195245
196246 // ====== Start hacking ======
247+ let textDecoder = new TextDecoder ( "utf-8" ) ;
197248 const websocket_instant = new WebSocketOrig ( dt , config ) ;
198249 websocket_instant . addEventListener ( "message" , async function ( achunk ) {
199- const utf8_str = new TextDecoder ( "utf-8" ) . decode ( achunk . data ) ;
200-
201- if ( utf8_str [ 0 ] === "1" || utf8_str [ 0 ] === "2" || utf8_str [ 0 ] === "3" ) {
202- const have_msg_id = / (? = m i d \. \$ ) ( .* ?) (? = \\ " ) / . exec ( utf8_str ) ;
203- if ( have_msg_id ) {
204- // Lấy ra tất cả các thông tin dùng được trong dữ liệu (những chuỗi nằm giữa 2 dấu nháy kép "")
205- const all_strings_regex = / ( \\ \" ) ( .* ?) ( \\ \" ) (? = [ , ) ] ) / g;
206- let all_strings = utf8_str . match ( all_strings_regex ) || [ ] ;
207- all_strings = all_strings . map ( ( str ) => parse ( str ) ) ;
208-
209- if ( all_strings . length ) {
210- findAllChatData ( all_strings ) ;
250+ try {
251+ const utf8_str = textDecoder . decode ( achunk . data ) ;
252+
253+ if (
254+ utf8_str [ 0 ] === "1" ||
255+ utf8_str [ 0 ] === "2" ||
256+ utf8_str [ 0 ] === "3"
257+ ) {
258+ const have_msg_id = / (? = m i d \. \$ ) ( .* ?) (? = \\ " ) / . exec ( utf8_str ) ;
259+ if ( have_msg_id ) {
260+ let all_strings = (
261+ utf8_str . match ( / ( \\ \" ) ( .* ?) ( \\ \" ) (? = [ , ) ] ) / g) || [ ]
262+ ) . map ( ( str ) => parse ( str ) ) ;
263+
264+ if ( all_strings . length && all_strings . length < 200 ) {
265+ let chats = findAllChatData ( all_strings ) ;
266+ chats . length && saveChatData ( chats ) ;
267+ }
211268 }
212269 }
270+ } catch ( e ) {
271+ console . log ( "ERROR: " , e ) ;
213272 }
214273 } ) ;
215274
@@ -218,23 +277,17 @@ export default {
218277 window . WebSocket . prototype = WebSocketOrig . prototype ;
219278 window . WebSocket . prototype . constructor = window . WebSocket ;
220279 } ,
280+
221281 onDocumentIdle : ( ) => {
222282 // tất cả loại tin nhắn đều được bao bọc bởi:
223283 // MWPBaseMessage.bs
224284 // MWMessageListAttachment.bs
225285 // MWMessageListAttachmentContainer.bs
226286
227- let key = "ufs_reveal_deleted_fb_messages" ;
228- let savedMessages = JSON . parse ( localStorage . getItem ( key ) ?? "[]" ) ;
229-
230- console . log (
231- "Load " + savedMessages . length + " messages from localStorage."
232- ) ;
233-
287+ // TODO hiển thị đúng component react cho từng loại tin nhắn
234288 requireLazy (
235- [ "MWV2ChatUnsentMessage.bs" , "MWPBaseMessage.bs" ] ,
236- ( MWV2ChatUnsentMessage , MWPBaseMessage ) => {
237- // Override unsent message component
289+ [ "MWV2ChatUnsentMessage.bs" , "MWPBaseMessage.bs" , "MWV2ChatImage.bs" ] ,
290+ ( MWV2ChatUnsentMessage , MWPBaseMessage , MWV2ChatImage ) => {
238291 const MWV2ChatUnsentMessageOrig = MWV2ChatUnsentMessage . make ;
239292 MWV2ChatUnsentMessage . make = function ( a ) {
240293 if ( a ) {
@@ -254,18 +307,46 @@ export default {
254307 senderId =
255308 UsefulScriptGlobalPageContext . Facebook . decodeArrId ( senderId ) ;
256309
257- a . message . isUnsent = false ;
258- a . message . text = "[Hacked]: thu hồi nè" ;
259-
260- console . log (
261- "Tin nhắn thu hồi từ " + senderId + " trong " + threadKey ,
262- a
310+ let savedMsg = window . ufs_rvdfm_all_msgs . find (
311+ ( _ ) => _ . id === messageId
263312 ) ;
313+
314+ a . message . isUnsent = false ;
315+ if ( savedMsg ) {
316+ let time = new Date ( savedMsg . saved_time ) . toLocaleString ( ) ;
317+ let title = `[Tin thu hồi - ${ savedMsg . type } ]:\n` ;
318+ let text = `${ savedMsg ?. content } ` ;
319+ a . message . text = title + text ;
320+ } else {
321+ a . message . text = "[Tin thu hồi]: -Không có dữ liệu-" ;
322+ }
264323 }
265324 }
266325 return MWV2ChatUnsentMessageOrig . apply ( this , arguments ) ;
267326 } ;
268327 }
269328 ) ;
270329 } ,
330+
331+ onClick : ( ) => {
332+ let len = window . ufs_rvdfm_all_msgs . length ;
333+ if ( ! len )
334+ alert (
335+ "Chức năng chưa lưu được tin nhắn nào.\n" +
336+ "Hãy mở khung chat bất kỳ để chức năng tự động lưu tin nhắn giúp bạn.\n" +
337+ "Sau khi lưu, nếu có người thu hồi tin nhắn, chức năng sẽ lấy tin đã lưu hiển thị cho bạn xem."
338+ ) ;
339+ else if (
340+ confirm (
341+ `Bạn có chắc muốn xóa tất cả ${ len } tin nhắn` +
342+ ` đã được lưu bởi chức năng này?\n\n` +
343+ `+ Chỉ nên xóa khi thấy đã lưu quá nhiều tin nhắn.\n` +
344+ `+ Sau khi xóa, nếu có người thu hồi tin nhắn, mà tin đó chưa được lưu\n` +
345+ ` thì bạn sẽ ko biết được nội dung tin nhắn.`
346+ )
347+ ) {
348+ window . ufs_rvdfm_all_msgs = [ ] ;
349+ alert ( "Đã xóa " + len + " tin nhắn khỏi bộ nhớ." ) ;
350+ }
351+ } ,
271352} ;
0 commit comments