Lib_MyAPI

又拍云自动活动签到程序

Per 06-03-2024. Zie de nieuwste versie.

Dit script moet niet direct worden geïnstalleerd - het is een bibliotheek voor andere scripts om op te nemen met de meta-richtlijn // @require https://update.greasyfork.org/scripts/489184/1338823/Lib_MyAPI.js

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name Lib_MyAPI
// @namespace AC-API
// @include *
// @run-at document-start
// @version 2024.03.07
// @grant   GM_xmlhttpRequest
// @grant   unsafeWindow
// @description 又拍云自动活动签到程序
// ==/UserScript==

// 避免函数污染
const ACMO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

unsafeWindow.MyApi = (() => {
  /**
   * @param css CSS的正文内容
   * @param className 被添加的css节点的class,用于onlyOne检测
   * @param isReload 是否自动更新:移除后重新添加
   */
  function addStyle(css, className = '', isReload = false){ // 添加CSS代码,不考虑文本载入时间,带有className
    const tout = setInterval(function() {
      if (document.body != null) {
        clearInterval(tout);
        if (className) {
          // 节点不存在,或者是准备覆盖的时候
          if (isReload === false && document.querySelector("." + className) != null) {
            return;
          }

          // 节点已经存在,并且不准备覆盖
          try {
            document.querySelector("." + className).remove();
          } catch (e) {
          }
        }
        const cssNode = document.createElement("style");
        if (className) {
          cssNode.className = className;
        }
        cssNode.innerHTML = css;
        try {
          document.body.appendChild(cssNode);
        } catch (e) {
          console.log(e.message);
        }
      }
    }, 200);
  }

  function addScript(scriptInner) {
    const scriptNode = document.createElement('script')
    scriptNode.innerText = scriptInner
    document.head.appendChild(scriptNode)
  }

  const safeWaitFunc = function waitForElm(selector, callbackFunc = node => {}, findTick = 200, clearAfterFind = true, timeout = 20000 * 1000) {
    const handle = () => {
      if ((typeof (selector) === "string")) {
        let res = document.querySelectorAll(selector);
        if(res && res.length) {
          callbackFunc(res);
        }
      } else if (typeof (selector) === "function") {
        const res =  selector()
        if(res && res.length) {
          callbackFunc(res);
        }
      }
    }
    let lastRunAt = 0 // 最近一次运行的时间
    let onlyTimer;
    const firstRunAt = Date.now()
    
    // 处理第一次
    handle()
    // 其他时间增加监听即可
    const watcher = new ACMO(() => {
      // 超过节流时间间隔,立即执行事件处理函数
      if(Date.now() - lastRunAt > findTick) {
        handle()
        if(clearAfterFind) {
          watcher.disconnect();
        }
        lastRunAt = Date.now()
      } else {
        // 未超过节流时间间隔,设置定时器延迟执行事件处理函数
        clearTimeout(timer);
        onlyTimer = setTimeout(() => {
          handle();
          lastRunAt = Date.now()
        }, findTick);
      }
      
      // 超过最大时限,那么停止监听
      if(Date.now() - firstRunAt > timeout) {
        watcher.disconnect();
      }
    });

    watcher.observe(document.body, {
      childList: true,
      subtree: true
    });
  }

  function getUrlAttribute(attribute, needDecode = true){
    var searchValue = (window.location.search.substr(1) + "").split("&");
    for (var i = 0; i < searchValue.length; i++) {
      var key_value = searchValue[i].split("=");
      var reg = new RegExp("^"+attribute+"$");
      if (reg.test(key_value[0])) {
        var searchWords = key_value[1];
        return needDecode?decodeURIComponent(searchWords):searchWords;
      }
    }
  }

  const http = {
    async get(url) {
      return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          url,
          method: 'GET',
          timeout: 10000,
          onload: resp => resolve([null, resp.responseText]),
          onerror: resp => reject([resp, {}])
        })
      })
    },
    async post(url, data) {
      return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          url,
          data,
          method: 'POST',
          timeout: 10000,
          onload: resp => resolve([null, resp.responseText]),
          onerror: resp => reject([resp, {}])
        })
      })
    }
  }

  return {
    addStyle,
    addScript,
    safeWaitFunc,
    getUrlAttribute,
    http
  }
})()