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

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

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

    [LV.7]常住居民III

    637

    主题

    5224

    回帖

    6096

    积分

    管理员

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

    积分
    6096

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

    发表于 2024-4-13 20:49:48 | 显示全部楼层 | 阅读模式

    在能加载插件并且自动唤起浏览器后

    我们的下一个目标就是可以实现插件与本地进行通信并且传输数据

    并且在加载后会提示一个插件已被篡改

    https://www.tampermonkey.net/index.php?version=5.1.0&updated=true#installed

    我们可以在本地起一个express的服务器,并且篡改掉显示的主页来表明我们注入成功

    const express = require("express");
    const path = require("path");
    const http = require("http");
    const { Server } = require("socket.io");
    
    function initLocalServer() {
      return new Promise((resolve) => {
        const app = express();
        app.use(express.static(path.join(__dirname, "/public")));
    
        let server = http.createServer(app);
        const io = new Server(server);
        io.on("connection", (socket) => {
          console.log("a user connected");
          socket.on("disconnect", () => {
            console.log("user disconnected");
          });
        });
        server.listen(0, () => {
          resolve(server.address().port);
        });
      });
    }
    
    exports.initLocalServer = initLocalServer;

    这里我们写了一个express服务器,并且监听了socket用于双向传输数据,同时为了解决篡改错误页面的显示,我们可以在public目录写一个自己的页面,然后通过调试找到了在插件的

              let e,
                t = "version=" + ti.newV + "&ext=" + qe.short_id + "&updated=true";
              if (
                (ti.first_run
                  ? ((e = "https://www.tampermonkey.net/installed.php?" + t),
                    (ti.active = !0))
                  : ((t += "&old=" + ti.oldV),
                    (e = "https://www.tampermonkey.net/changelog.php?" + t)),
                "off" == un.values.notification_showUpdate)
              );

    我们可以直接替换一下

              let e,
                t = "version=" + ti.newV + "&ext=" + qe.short_id + "&updated=true";
              if (
                (ti.first_run
                  ? ((e = window.openPage),
                    (ti.active = !0))
                  : ((t += "&old=" + ti.oldV),
                    (e = window.openPage)),
                "off" == un.values.notification_showUpdate)
              );

    然后提前在该js前引入另外一个js隔离引入变量即可
    但是由于express的port是动态的,所以我们需要动态修改,这里我引入了ejs模板

    const path = require("path");
    const ejs = require("ejs");
    const puppeteer = require("puppeteer");
    const fs = require("fs");
    
    const templateBase = path.join(__dirname, "./template");
    const crxBase = path.join(__dirname, "./tampermonkey_crx");
    
    async function injectCode({ port }) {
      const result = await ejs.renderFile(templateBase + "/backgroundInject.js", {
        openPage: "127.0.0.1:" + port,
        socketURL:"127.0.0.1:" + port
      });
      fs.writeFileSync(path.join(crxBase, "/backgroundInject.js"), result);
    }
    async function openBroswer() {
      const pathToExtension = crxBase;
      const browser = await puppeteer.launch({
        headless: false,
        args: [
          `--disable-extensions-except=${pathToExtension}`,
          `--load-extension=${pathToExtension}`,
        ],
      });
    }
    
    async function init(options) {
      await injectCode(options);
      await openBroswer();
    }

    然后编写一个ejs模板

    window.openPage=`http://<%= openPage %>`
    var socket = io('http://<%= socketURL %>');
    socket.send({"Title": "12315645566"})

    这样本地的express建立成功并且得到了端口,传给客户端,客户端通过ejs合成一个backgroundInject.js的文件,然后写入到插件目录中,那我们需要提前在background.html声明一下socket文件以及backgroundInject文件

    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <script src="socket.io.min.js"></script>
        <script src="backgroundInject.js"></script>
        <script src="test.js"></script>
        <script src="background.js"></script>
    </head>
    <body>
    </body>
    </html>
    

    再通过puppteer来唤起浏览器,那我们编制一下client和server的粘合代码

    const server = require("./server/index.js");
    const client = require("./client/index.js");
    
    async function init() {
       const port=await server.initLocalServer()
       client.init({port})
       console.log('port',port)
    }
    init()
    exports.init = init;

    图片.png

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

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

    发表回复

    本版积分规则

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