Greasy Fork

NJU Helper

A helper for you to automate your life in NJU.

当前为 2024-04-28 提交的版本,查看 最新版本

// ==UserScript==
// @name         NJU Helper
// @namespace    Flying-Tom/NJU-Helper
// @version      0.0.3
// @author       Flying-Tom
// @description  A helper for you to automate your life in NJU.
// @license      MIT
// @icon         https://z1.ax1x.com/2023/11/21/pia2Gtg.png
// @match        https://authserver.nju.edu.cn/authserver/login*
// @match        http://ndyy.nju.edu.cn/*
// @match        https://zhtj.youth.cn/zhtj/
// @match        https://ehall.nju.edu.cn/ywtb-portal/official/index.html*
// @match        https://mail.smail.nju.edu.cn/cgi-bin/loginpage*
// @match        https://ehallapp.nju.edu.cn/gsapp/sys/wspjapp/*
// @match        https://epay.nju.edu.cn/epay/h5/*
// @match        https://zzbdjgz.nju.edu.cn/consumer/*
// @grant        GM_info
// ==/UserScript==

(function () {
  'use strict';

  var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
  function wechat_page_handler() {
    if (window.location.href.includes("electric"))
      ;
    else if (window.location.href.includes("recharge")) {
      let styleElement = document.createElement("style");
      styleElement.textContent = `
          body {
              width: 40%;
              margin: 0 auto;
          }
        `;
      document.head.appendChild(styleElement);
    }
  }
  function waitForElm(selector) {
    return new Promise((resolve) => {
      if (document.querySelector(selector)) {
        return resolve(document.querySelector(selector));
      }
      const observer = new MutationObserver(() => {
        if (document.querySelector(selector)) {
          resolve(document.querySelector(selector));
          observer.disconnect();
        }
      });
      observer.observe(document.body, {
        childList: true,
        subtree: true
      });
    });
  }
  function waitForElms(selector) {
    return new Promise((resolve) => {
      if (document.querySelectorAll(selector).length > 0) {
        return resolve(document.querySelectorAll(selector));
      }
      const observer = new MutationObserver(() => {
        if (document.querySelectorAll(selector).length > 0) {
          resolve(document.querySelectorAll(selector));
          observer.disconnect();
        }
      });
      observer.observe(document.body, {
        childList: true,
        subtree: true
      });
    });
  }
  function getImageDataString(image_target) {
    let data_string = "";
    let canvas = document.createElement("canvas");
    canvas.width = image_target.naturalWidth;
    canvas.height = image_target.naturalHeight;
    let ctx = canvas.getContext("2d");
    if (ctx) {
      ctx.drawImage(image_target, 0, 0);
      let image_data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
      for (let i = 0; i < image_data.length; i += 4) {
        const r = image_data[i];
        const g = image_data[i + 1];
        const b = image_data[i + 2];
        const grayscale = 0.299 * r + 0.587 * g + 0.114 * b;
        data_string += Math.floor(grayscale).toString(16).padStart(2, "0");
      }
    }
    return data_string;
  }
  function handleCaptcha(captcha_img_selectors, captcha_input_selectors, auto_login) {
    waitForElm(captcha_img_selectors).then((data) => {
      let image_target = data;
      function solveCAPTCHA() {
        const captcha_provider_host = "https://api.cystom.top";
        const ifrm = document.createElement("iframe");
        let params = new URLSearchParams({
          mode: "uia",
          width: image_target.naturalWidth.toString(),
          height: image_target.naturalHeight.toString(),
          data: getImageDataString(image_target)
        });
        ifrm.setAttribute("src", captcha_provider_host + "/captcha/?" + params.toString());
        ifrm.style.width = "640px";
        ifrm.style.height = "480px";
        ifrm.style.display = "none";
        window.addEventListener("message", (e) => {
          if (e.origin !== captcha_provider_host) {
            console.warn("Invalid origin");
            return;
          }
          if (e == null ? void 0 : e.data) {
            let data2 = { type: "", content: "" };
            try {
              data2 = JSON.parse(e.data);
            } catch (e2) {
              console.warn(e2);
            } finally {
              if (data2.type == "captcha") {
                /* @__PURE__ */ console.debug(data2.content);
                let captcha_input = document.querySelector(captcha_input_selectors);
                if (captcha_input) {
                  captcha_input.value = data2.content;
                }
                if (auto_login.enabled == true) {
                  let intervalId = setInterval(function() {
                    let username_input = document.querySelector(auto_login.username_selectors);
                    let password_input = document.querySelector(auto_login.password_selectors);
                    let submit_button = document.querySelector(auto_login.submit_selectors);
                    if (username_input.value && password_input.value) {
                      submit_button.click();
                      clearInterval(intervalId);
                    }
                  }, 200);
                }
              }
            }
          }
        });
        document.body.appendChild(ifrm);
      }
      if (image_target.complete == true) {
        solveCAPTCHA();
      } else {
        image_target.addEventListener("load", solveCAPTCHA);
      }
    });
  }
  function njuauth_handler() {
    var _a;
    const inputElement = document.querySelector("input[name=dllt][value=userNamePasswordLogin]");
    if (inputElement) {
      inputElement.value = "mobileLogin";
    }
    const showPassElement = (_a = document.getElementsByClassName("showPass")) == null ? void 0 : _a[0];
    if (showPassElement) {
      showPassElement.click();
    }
    handleCaptcha("#captchaImg", "#captchaResponse", {
      enabled: true,
      // enabled: false,
      username_selectors: "input[name=username]",
      password_selectors: "input[type=password]",
      submit_selectors: "button[type=submit]"
    });
  }
  function njuhospital_handler() {
    const inputElement = document.querySelector('input[name="NewWebYzm"]');
    if (inputElement) {
      inputElement.value = "";
    }
    handleCaptcha("#refreshCaptcha", 'input[name="NewWebYzm"]', {
      enabled: false
    });
  }
  function ehall_handler() {
    let intervalId = setInterval(function() {
      if (document.querySelector(".header-user")) {
        let spanElement = document.evaluate("//span[contains(., '首页')]", document, null, XPathResult.ANY_TYPE).iterateNext();
        if (spanElement) {
          spanElement.click();
        }
        clearInterval(intervalId);
      }
      const btnLogin = document.querySelector(".btn-login");
      if (btnLogin) {
        btnLogin.click();
      }
    }, 200);
    setTimeout(function() {
      clearInterval(intervalId);
    }, 5e3);
  }
  function email_trust_handler() {
    let intervalId = setInterval(function() {
      const checkbox = document.getElementById("force_wx_scan_login_tc");
      if (checkbox) {
        checkbox.checked = true;
        clearInterval(intervalId);
      }
    }, 500);
  }
  function zhtj_handler() {
    handleCaptcha("#codeImage", "#yzm", {
      enabled: false
    });
  }
  function wspj_handler() {
    setInterval(checkForElement, 1e3);
    function checkForElement() {
      const element = document.querySelector("#pjfooter");
      if (element) {
        waitForElms(".bh-radio-label.paper_dx").then(
          (elems) => {
            let choices = elems;
            choices.forEach((elem) => {
              let choice = elem;
              const spanElement = choice.querySelector("span");
              const input = choice.querySelector("input");
              if (spanElement && input && spanElement.textContent === "符合") {
                input.checked = true;
              }
            });
          }
        );
      } else {
        return;
      }
    }
  }
  function samrt_party_handler() {
    function search_and_pay() {
      if (window.location.href.includes("partyCostPay")) {
        waitForElms(".ivu-input-number-input").then((data) => {
          const feeInputElems = data;
          feeInputElems.forEach((inputElem) => {
            const fee = "0.2";
            inputElem.value = fee;
            inputElem.dispatchEvent(new Event("input", { bubbles: true }));
          });
        });
      }
    }
    waitForElm("#app").then((data) => {
      const observer = new MutationObserver(search_and_pay);
      observer.observe(data, {
        childList: true,
        subtree: true
      });
    });
  }
  (function() {
    (function() {
      let match_idx = _GM_info.script.matches.map((rule) => rule.replace(/\.|\*|\/|\?/g, (match) => ({ ".": "\\.", "*": ".*", "/": "\\/", "?": "\\?" })[match] || "")).map((rule) => new RegExp(rule)).map((regExp, index) => regExp.test(window.location.href) ? index : null).filter((index) => index != null).join().toString();
      const strategy_load = {
        "0": njuauth_handler,
        // 南大统一身份认证自动登录
        "1": njuhospital_handler,
        // 南大校医院验证码
        "2": zhtj_handler,
        // 智慧团建验证码
        "3": ehall_handler,
        // 南大 ehall 自动登录
        "4": email_trust_handler,
        // 南大学生邮箱信任本机
        "5": wspj_handler
        // 南大ehall 课程评教
      };
      const strategy_instant = {
        "6": wechat_page_handler,
        // 南大信息门户 pc 端
        "7": samrt_party_handler
        // 智慧党建
      };
      if (match_idx in strategy_instant) {
        let strategy_instant_func = strategy_instant[match_idx];
        strategy_instant_func();
      } else if (match_idx in strategy_load) {
        let strategy_load_func = strategy_load[match_idx];
        if (document.readyState == "complete") {
          strategy_load_func();
        } else {
          window.addEventListener("load", strategy_load_func);
        }
      }
    })();
  })();

})();