上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

尝试抹平Tampermonkey的VSCode开发体验(三)

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    655

    主题

    5316

    回帖

    6204

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6204

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2024-4-14 01:34:43 | 显示全部楼层 | 阅读模式

    在保证了浏览器和本地进行沟通的前提下,接下来我们要考虑传输脚本自动更新了
    我们已知每次创建脚本都会有一个uuid,这个uuid是唯一标识脚本的
    为了不破坏原有的流程,造成更大的污染,我们尽量模拟原系统
    但是我们又怎么对应呢?我们可以新建一个chrome的存储数据用于存储额外的这些信息
    用一个name和一个uuid来进行一一对应,
    如果出现新的name则是出现新的脚本,自动创建脚本并且进行设置,并存储下uuid
    如果是旧的name则是已经创建过的脚本,寻找到uuid并进行更新即可
    所以可以在backgroundInject中编写出初步的代码

    window.openPage = `http://<%= openPage %>`;
    
    const scriptSaveName = "scriptSaveName";
    
    function getScriptData() {
      return new Promise((resolve) => {
        chrome.storage.local.get([scriptSaveName], function (result) {
          if (result[scriptSaveName] === undefined) {
            resolve({});
          } else {
            resolve(JSON.parse(result[scriptSaveName]));
          }
        });
      });
    }
    
    async function init() {
      const scriptData = await getScriptData();
      var socket = io("http://<%= socketURL %>");
      socket.on("saveScript", (name, scriptContent) => {
        if (scriptData[name] !== undefined) {
          //更新脚本
        } else {
          //创建脚本
        }
      });
    }
    init();

    根据调试我们找到了tampermonkey的新建脚本保存的代码

                               Y(e.uuid, i, {
                                  clean: !1,
                                  new_script: e.nnew,
                                  auto_save: t && t.auto_save,
                                  reload: !0,
                                  lastModTime: A[e.uuid].saveEm_lastModTime,
                                }).done((n) => {
                                  n.installed
                                    ? e.nnew
                                      ? b(0, !0, !1)
                                      : (k(!1),
                                        n.lastModified &&
                                          (e.lastModTime = n.lastModified))
                                    : n.aborted ||
                                      (t && t.auto_save) ||
                                      (n.messages &&
                                      n.messages.errors &&
                                      n.messages.errors.length
                                        ? de(n.messages.errors.join("\n"))
                                        : de(ot("Unable_to_parse_this_")));
                                }),

    往里一路跟发现找到了

                      sendMessage(
                        {
                          ...e,
                          method: "saveScript",
                          code: t,
                          clean: n.clean,
                          force: n.force,
                          new_script: n.new_script,
                          auto_save: n.auto_save,
                          restore: n.restore,
                          lastModTime: n.lastModTime,
                          reload: n.reload,
                        },
                        (e) => {
                          n.auto_save || ((r || T)(), G()),
                            (e = e || {}).items ? Q(e.items, !0) : _t.hide(),
                            !t && n.reload && _t.hide(),
                            i.resolve(e);
                        }
                      );

    下断点得到了保存数据为

    {
        auto_save: undefined
        clean: false
        code: "脚本代码"
        force: undefined
        lastModTime: undefined
        method: "saveScript"
        new_script: true
        reload: true
        restore: undefined
        uuid: "new-user-script"
    }

    那我们可以直接编写sendMessage尝试一下

    chrome.runtime.sendMessage(
      {
        auto_save: undefined,
        clean: false,
        code: scriptContent,
        force: undefined,
        lastModTime: undefined,
        method: "saveScript",
        new_script: true,
        reload: true,
        restore: undefined,
        uuid: "new-user-script",
      },
      function (response) {
        console.log("获取到的设置信息为:", response);
      }
    );

    理想很丰满,显示很骨感,根据测试sendMessage无法在chrome插件的background中使用
    查阅了很多资料都没解决这个方法,本来想走hook了,但是意料之外找到了一个chrome.runtime.onMessage.dispatch函数,直接传入a,b,c即是三个参,原理不明兼容性也没查到,总是很神奇...

    next...

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表