huiyadanli / RevokeMsgPatcher

:trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了)
GNU General Public License v3.0
27.8k stars 3.28k forks source link

[Feature Request]QQ频道的防撤回功能 #242

Open SekiBetu opened 2 years ago

SekiBetu commented 2 years ago

image QQ频道有撤回功能,所以希望推出防撤回功能

callng commented 2 years ago

这东西还在测试中。

SekiBetu commented 2 years ago

这东西还在测试中。

提前部署,五年计划

callng commented 2 years ago

这东西还在测试中。

提前部署,五年计划

如果可以实现,那作者目前需要一个有内测资格的账号

SekiBetu commented 2 years ago

这东西还在测试中。

提前部署,五年计划

如果可以实现,那作者目前需要一个有内测资格的账号

关闭安卓QQ后台,进入安卓根目录(如果手机没有root可以用电脑上的安卓模拟器) /data/user/0/com.tencent.mobileqq/shared_prefs/TabDataHelper_Shared_Prefs.xml 添加以下两项配置

<int name="KeyTabSwitchQQ号_GUILD" value="2" />
<int name="KeyTabLocalSwitchQQ号_GUILD" value="2" />

<map></map>

注:其中 QQ号 字段替换为你的QQ号 例如QQ号为 123456789 ,则为以下例子:

<map>
    <int name="KeyTabSwitch123456789_GUILD" value="2" />
    <int name="KeyTabLocalSwitch123456789_GUILD" value="2" />
</map>

打开安卓QQ,就有频道了,有了安卓QQ的频道之后随便加一个频道,几分钟后再打开PC版QQ,就有PC版QQ的频道了

callng commented 2 years ago

打开安卓QQ,就有频道了,有了安卓QQ的频道之后随便加一个频道,几分钟后再打开PC版QQ,就有PC版QQ的频道了

感谢提供方法。

yyuueexxiinngg commented 2 years ago

更新:拿到创建频道的资格了,进行了详细测试,以下方法证实用处不大。

此方法仅能实现目前浏览的子频道中的消息防撤回,因为其余子频道的消息没有进行下载,仅仅更新了消息预览。 且消息并没有保存下来,切换子频道后会重新加载子频道消息,获取消息的逻辑还是在QQ中(ipcRenderer.invoke('[gpro-invoke][0]','getChannelMsg')),导致防撤回的消息丢失。

如果还是有兴趣可以参考修改后的代码:

bindMsgInfoListUpdate({ rootState: e, commit: t }) {
  o["a"].on("onMsgInfoListUpdate", (n) => {
    r["a"].info("onMsgInfoListUpdate: ", JSON.stringify(n));
    const { msgList: i } = e.chat,
      A = [...i],
      { msgList: s } = n;
    s.forEach((e) => {
      const { msgId: t } = e,
        n = i.findIndex((e) => e.msgId === t);
        if (-1 !== n) {
          if (e.elements.some(el => el.grayTipElement.subElementType == 1)) {
            e = A[n];
            e.elements.push(
              {
                "elementType": 1,
                "elementId": "114514",
                "textElement": {
                    "content": "\r↑拦截到此消息撤回↑",
                    "atType": 0,
                    "atUid": "0",
                    "atTinyId": "0"
                },
                "faceElement": {
                    "faceIndex": 0,
                    "faceText": ""
                },
                "replyElement": {
                    "replayMsgId": "0",
                    "replayMsgSeq": "0",
                    "sourceMsgText": "",
                    "senderUid": "0"
                },
                "picElement": {
                    "fileName": "",
                    "fileSize": "0",
                    "picWidth": 0,
                    "picHeight": 0,
                    "original": false,
                    "md5": "",
                    "sourcePath": "",
                    "thumbPath": {}
                },
                "videoElement": {
                    "fileName": "",
                    "videoMd5": "",
                    "thumbMd5": "",
                    "fileTime": 0,
                    "thumbSize": 0,
                    "fileFormat": 0,
                    "fileSize": 0,
                    "thumbWidth": 0,
                    "thumbHeight": 0,
                    "busiType": 0
                },
                "grayTipElement": {
                    "subElementType": 0,
                    "revokeElement": {
                        "operatorTinyId": "0",
                        "operatorRole": "0"
                    },
                    "proclamationElement": {
                        "isSetProclamation": 0
                    }
                },
                "arkElement": {
                    "bytesData": ""
                },
                "fileElement": {
                    "fileMd5": "",
                    "fileName": "",
                    "filePath": "",
                    "fileSize": "0",
                    "picHeight": 0,
                    "picWidth": 0,
                    "picThumbPath": {},
                    "expireTime": "0"
                }
            }
            );
          }
          A[n] = e;
        }
    }),
      t("UPDATE_MSG_LIST", A);
  });
},

原文:

可通过修改QQ频道的app.xxx.js实现,位于C:\Users\xxx\AppData\Local\Tencent\QQGuild\1.0.1\resources\app\js\app.xxx.js

我用了相当粗暴的方法:

bindMsgInfoListUpdate({ rootState: e, commit: t }) {
    o["a"].on("onMsgInfoListUpdate", (n) => {
        r["a"].info("onMsgInfoListUpdate: ", n);
        const { msgList: i } = e.chat,
              A = [...i],
              { msgList: s } = n;
        s.forEach((e) => {
            const { msgId: t } = e,
                  n = i.findIndex((e) => e.msgId === t);
            -1 !== n && (A[n] = e);
        }),
            t("UPDATE_MSG_LIST", A);
    });
},

直接注释成了:

bindMsgInfoListUpdate({ rootState: e, commit: t }) {
  o["a"].on("onMsgInfoListUpdate", (n) => {
    r["a"].info("onMsgInfoListUpdate: 不许撤回!", n);
    // const { msgList: i } = e.chat,
    //   A = [...i],
    //   { msgList: s } = n;
    // s.forEach((e) => {
    //   const { msgId: t } = e,
    //     n = i.findIndex((e) => e.msgId === t);
    //   -1 !== n && (A[n] = e);
    // }),
    //   t("UPDATE_MSG_LIST", A);
  });
},

找到这个方法的过程:https://blog.hoshi.tech/archives/89/

yorshkas commented 2 years ago

任何频道都不让加入怎么办

SekiBetu commented 2 years ago

任何频道都不让加入怎么办

内测就是让有资格的拉没资格的人进去,你进不去就等公测,很简单的道理,内测一个人有一千多个邀请券,估计有几百万几千万个邀请券在市面上流传,你这都碰不到,我觉得你没资格使用这个功能

mysq1isworst commented 2 years ago

pc版频道已经公测了?可以支持了吗?

EmiyaNiu commented 6 months ago

现在qq频道支持防撤回了吗?