Aggressive ajaxOrder injector

去你的lry 帮助计算机学子快速看完砺儒云的视频 点一下播放几秒就能看完了

// ==UserScript==
// @name         Aggressive ajaxOrder injector
// @namespace    https://github.com/laoyup1
// @version      0.3
// @match        https://moodle.scnu.edu.cn/mod/fsresource/*
// @grant        none
// @run-at       document-start
// @author       t1ara
// @description   去你的lry 帮助计算机学子快速看完砺儒云的视频 点一下播放几秒就能看完了
// @language     JavaScript
// @license MIT
// ==/UserScript==

(function(){
  'use strict';

  const INJECT_LINE = 'window.viewTotalTime = 99999;'; // 使用 window. 更稳妥

  function wrapGlobalIfExists(){
    try{
      if(typeof window.ajaxOrder === 'function'){
        const orig = window.ajaxOrder;
        window.ajaxOrder = function(...args){
          try{ window.viewTotalTime = 99999; }catch(e){}
          return orig.apply(this, args);
        };
        console.log('[inject] Wrapped existing global ajaxOrder');
        return true;
      }
    }catch(e){}
    return false;
  }

  // 尝试立即包装(若已定义为全局)
  wrapGlobalIfExists();

  // --- helper: try to modify inline script source by regex injection ---
  function tryPatchScriptText(text){
    // 多种常见定义形式: function ajaxOrder() { ... }
    // 或者 var/let/const ajaxOrder = function(...) { ... }
    // 或者 ajaxOrder = function(...) { ... }
    // 正则尽量稳健但不完美(注意多行)
    let patched = text;
    let changed = false;

    // 1) 匹配 function ajaxOrder (...) {  --> 在第一个 { 后注入
    patched = patched.replace(/function\s+ajaxOrder\s*\([^)]*\)\s*\{/, function(m){
      changed = true;
      return m + '\n' + INJECT_LINE + '\n';
    });

    // 2) 匹配 ajaxOrder\s*=\s*function(...) {
    patched = patched.replace(/(ajaxOrder\s*=\s*function\s*\([^)]*\)\s*\{)/, function(m){
      changed = true;
      return m + '\n' + INJECT_LINE + '\n';
    });

    // 3) 匹配 var|let|const ajaxOrder = function(...) {
    patched = patched.replace(/((?:var|let|const)\s+ajaxOrder\s*=\s*function\s*\([^)]*\)\s*\{)/, function(m){
      changed = true;
      return m + '\n' + INJECT_LINE + '\n';
    });

    // 4) 匹配箭头函数: ajaxOrder = (...) => { ... }
    patched = patched.replace(/(ajaxOrder\s*=\s*\([^)]*\)\s*=>\s*\{)/, function(m){
      changed = true;
      return m + '\n' + INJECT_LINE + '\n';
    });

    return changed ? patched : null;
  }

  // 替换并重新插入内联脚本节点(保持位置)
  function replaceInlineScriptNode(node, newText){
    try{
      const parent = node.parentNode;
      if(!parent) return false;
      const s2 = document.createElement('script');
      // preserve type and attrs
      if(node.type) s2.type = node.type;
      if(node.noModule) s2.noModule = node.noModule;
      s2.textContent = newText;
      parent.insertBefore(s2, node);
      parent.removeChild(node);
      console.log('[inject] Replaced inline script with patched version');
      return true;
    }catch(e){
      console.error('[inject] replaceInlineScriptNode failed', e);
      return false;
    }
  }

  // 遍历现有的内联 script 标签尝试修补
  function scanAndPatchExistingScripts(){
    const scripts = Array.from(document.querySelectorAll('script:not([src])'));
    for(const s of scripts){
      if(!s.textContent) continue;
      const patched = tryPatchScriptText(s.textContent);
      if(patched){
        replaceInlineScriptNode(s, patched);
      }
    }
  }

  // 观察未来插入的内联 script 并尝试修补
  function observeFutureInlineScripts(){
    const mo = new MutationObserver(muts => {
      for(const m of muts){
        for(const node of m.addedNodes){
          if(node.tagName === 'SCRIPT' && !node.src && node.textContent){
            const patched = tryPatchScriptText(node.textContent);
            if(patched){
              // 替换新插入的节点
              replaceInlineScriptNode(node, patched);
            } else {
              // 如果是普通内联脚本但包含定义 ajaxOrder later, attempt to wrap after short delay
              setTimeout(wrapGlobalIfExists, 50);
            }
          }
        }
      }
    });
    mo.observe(document.documentElement || document, { childList: true, subtree: true });
    // 自动停止观察 30s 后(避免永久开销)
    setTimeout(()=>mo.disconnect(), 30000);
  }

  // 若脚本在更晚的时候被定义为全局(异步加载、动态执行),反复尝试包装一段时间
  function periodicWrapTries(){
    let tries = 0;
    const id = setInterval(()=>{
      tries++;
      if(wrapGlobalIfExists() || tries > 50) clearInterval(id);
    }, 200); // 每200ms尝试一次,最多约10s
  }

  // 启动流程(在 document-start 即刻执行)
  try{
    // 扫描已有内联脚本(此处会在 DOM 早期运行,可能找不到所有脚本)
    setTimeout(scanAndPatchExistingScripts, 0);
    // 监听未来内联脚本
    observeFutureInlineScripts();
    // 循环尝试包装全局(覆盖异步赋值场景)
    periodicWrapTries();
    console.log('[inject] aggressive injector installed');
  }catch(e){
    console.error('[inject] installer failed', e);
  }

    const CLASS_LIST = ['prism-play-btn', 'prism-play-btn playing']; // 替换成你的两个按钮 class
    const CLICK_TIMES = 888; // 每个按钮点击次数
    const CLICK_INTERVAL = 50; // 每次点击间隔,毫秒
    const POLL_INTERVAL = 100; // 检测新按钮间隔,毫秒

    // 存储已经点击次数的按钮
    const clickedMap = new WeakMap();

    const getAllButtons = () => {
        return Array.from(document.querySelectorAll(CLASS_LIST.map(c => `.${c}`).join(',')));
    };

    const clickButtons = () => {
        const buttons = getAllButtons();
        buttons.forEach(btn => {
            let count = clickedMap.get(btn) || 0;
            if (count < CLICK_TIMES) {
                btn.click();
                clickedMap.set(btn, count + 1);
                console.log(`按钮点击次数: ${count + 1}`);
            }
        });
    };

    // 定时点击已存在和新出现的按钮
    const intervalId = setInterval(() => {
        clickButtons();

        // 检查是否所有按钮都已点击完成
        const buttons = getAllButtons();
        const allDone = buttons.every(btn => (clickedMap.get(btn) || 0) >= CLICK_TIMES);
        if (allDone && buttons.length > 0) {
            console.log('所有按钮已点击完成,停止脚本');
            clearInterval(intervalId);
        }
    }, POLL_INTERVAL);
})();