岐黄天使刷课助手 - 调试加载器模块

岐黄天使刷课助手的调试与模块加载器,用于开发和测试阶段管理模块依赖。

Tính đến 24-05-2025. Xem phiên bản mới nhất.

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greasyfork.org/scripts/537076/1594857/%E5%B2%90%E9%BB%84%E5%A4%A9%E4%BD%BF%E5%88%B7%E8%AF%BE%E5%8A%A9%E6%89%8B%20-%20%E8%B0%83%E8%AF%95%E5%8A%A0%E8%BD%BD%E5%99%A8%E6%A8%A1%E5%9D%97.js

// ==UserScript==
// @name         岐黄天使刷课助手 - 调试加载器模块
// @namespace    http://tampermonkey.net/qhtx-modules
// @version      1.3.0
// @description  岐黄天使刷课助手的调试与模块加载器,用于开发和测试阶段管理模块依赖。
// @author       AI助手
// ==/UserScript==

// 调试加载器模块
(function() {
    'use strict';

    // 添加模块加载状态跟踪
    window.moduleStatus = {
      loaded: new Set(),
      pending: new Set([
        // 'styles', 'utils', 'ui', 'videoPlayer',
        // 'videoNavigation', 'courseNavigation', 'questionBank',
        // 'autoAnswer', 'remoteSync'
      ]),
      startTime: Date.now(),
      // 显示模块加载状态
      showStatus: function() {
        const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(2);
        console.log(`
        ========== 模块加载状态 (${elapsed}秒) ==========
        已加载: ${Array.from(this.loaded).join(', ') || '无'}
        待加载: ${Array.from(this.pending).join(', ') || '无'}
        ============================================
        `);
      }
    };

    // 定期显示模块加载状态
    window.moduleStatusInterval = setInterval(() => {
      if (window.moduleStatus.pending.size === 0) {
        clearInterval(window.moduleStatusInterval);
        window.moduleStatus.showStatus();
        console.log('%c所有模块加载完成!', 'color: green; font-size: 14px; font-weight: bold');
      } else {
        window.moduleStatus.showStatus();
      }
    }, 2000);

    // 检查模块加载状态
    function checkModuleLoaded(moduleName) {
      const now = new Date();
      const timeStr = now.toLocaleTimeString() + '.' + now.getMilliseconds();
      console.log(`[模块加载] 正在验证 ${moduleName} 状态,当前时间: ${timeStr}`);

      // 详细检查window对象上的模块属性
      console.log(`[模块加载详情] ${moduleName} 检查:`, {
        '直接访问': window[moduleName],
        '类型': typeof window[moduleName],
        '是否存在': moduleName in window,
        'window属性': Object.keys(window).filter(k => k.includes(moduleName)),
        '全局变量': Object.keys(window).filter(k => k.startsWith('qh') || k.includes('module') || k.includes('Module'))
      });

      // 检查模块是否已加载
      if (typeof window[moduleName] === 'function') {
        window.moduleStatus.loaded.add(moduleName);
        window.moduleStatus.pending.delete(moduleName);

        console.log(`[模块加载] %c${moduleName} 已就绪%c`,
                    'color: green; font-weight: bold', 'color: black');

        // 输出已加载的模块列表
        console.log(`[模块加载] 已加载模块: ${Array.from(window.moduleStatus.loaded).join(', ')}`);
        console.log(`[模块加载] 待加载模块: ${Array.from(window.moduleStatus.pending).join(', ')}`);

        return true;
      }

      // 如果模块未加载,尝试检查是否有其他命名方式
      const possibleNames = [
        moduleName,
        moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // 首字母大写
        moduleName + 'Module',
        'qh' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // qh前缀
        'create' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // create前缀
        'init' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // init前缀
        'apply' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1) // apply前缀
      ];

      console.log(`[模块加载] 尝试其他可能的命名:`, possibleNames.map(name => ({
        name,
        exists: name in window,
        type: typeof window[name]
      })));

      console.warn(`[模块加载] %c${moduleName} 未就绪%c,window[${moduleName}] = ${window[moduleName]}`,
                  'color: red; font-weight: bold', 'color: black');

      return false;
    }

    // 使用GM_xmlhttpRequest检查模块文件
    function checkModuleFile(moduleName) {
      return new Promise((resolve, reject) => {
        // const url = `//192.168.1.6:9999/qhtx/${moduleName}.js?check=${Date.now()}`;
        // console.log(`[模块检查] 使用GM_xmlhttpRequest检查模块文件: ${url}`);
        console.log(`[模块检查] 本地模块文件检查功能已禁用。模块 ${moduleName} 应通过 @require 加载。`);
        resolve({ module: moduleName, content: 'noop', status: 200 }); // 模拟成功,但不做实际操作

        // if (typeof GM_xmlhttpRequest !== 'function') {
        //   console.error('[模块检查] GM_xmlhttpRequest不可用');
        //   reject('GM_xmlhttpRequest不可用');
        //   return;
        // }

        // GM_xmlhttpRequest({
        //   method: 'GET',
        //   url: url,
        //   onload: function(response) {
        //     console.log(`[模块检查] ${moduleName}.js 检查结果:`, {
        //       status: response.status,
        //       statusText: response.statusText,
        //       responseSize: response.responseText ? response.responseText.length : 0,
        //       responsePreview: response.responseText ? response.responseText.substring(0, 100) + '...' : '无内容'
        //     });

        //     if (response.status >= 200 && response.status < 300) {
        //       resolve({
        //         module: moduleName,
        //         content: response.responseText,
        //         status: response.status
        //       });
        //     } else {
        //       reject(`HTTP错误: ${response.status} ${response.statusText}`);
        //     }
        //   },
        //   onerror: function(error) {
        //     console.error(`[模块检查] ${moduleName}.js 请求失败:`, error);
        //     reject(`请求失败: ${error.error || '未知错误'}`);
        //   },
        //   ontimeout: function() {
        //     console.error(`[模块检查] ${moduleName}.js 请求超时`);
        //     reject('请求超时');
        //   }
        // });
      });
    }

    // 使用GM_xmlhttpRequest直接加载模块
    function loadModuleWithGM(moduleName) {
      return new Promise((resolve, reject) => {
        // const url = `//192.168.1.6:9999/qhtx/${moduleName}.js?direct=true&t=${Date.now()}`;
        // console.log(`[模块加载] 使用GM_xmlhttpRequest直接加载模块: ${url}`);
        console.log(`[模块加载] 本地模块加载功能已禁用。模块 ${moduleName} 应通过 @require 加载。`);
        resolve(true); // 模拟成功

        // if (typeof GM_xmlhttpRequest !== 'function') {
        //   console.error('[模块加载] GM_xmlhttpRequest不可用,无法直接加载模块');
        //   reject('GM_xmlhttpRequest不可用');
        //   return;
        // }

        // GM_xmlhttpRequest({
        //   method: 'GET',
        //   url: url,
        //   onload: function(response) {
        //     if (response.status >= 200 && response.status < 300) {
        //       console.log(`[模块加载] 成功获取模块 ${moduleName}.js 内容,长度: ${response.responseText.length}字节`);

        //       try {
        //         // 创建一个新的script元素
        //         const script = document.createElement('script');
        //         script.textContent = response.responseText;
        //         document.head.appendChild(script);

        //         console.log(`[模块加载] 模块 ${moduleName}.js 已注入到页面`);
        //         resolve(true);
        //       } catch (error) {
        //         console.error(`[模块加载] 注入模块 ${moduleName}.js 时出错:`, error);
        //         reject(error);
        //       }
        //     } else {
        //       console.error(`[模块加载] 获取模块 ${moduleName}.js 失败: HTTP ${response.status}`);
        //       reject(`HTTP错误: ${response.status}`);
        //     }
        //   },
        //   onerror: function(error) {
        //     console.error(`[模块加载] 请求模块 ${moduleName}.js 时出错:`, error);
        //     reject(error);
        //   }
        // });
      });
    }

    // 检查所有模块
    function checkAllModules() {
      console.log('[模块检查] 开始检查所有模块文件 - (此功能已调整为不执行实际检查)');
      return Promise.resolve([]); // 直接返回一个空的 resolved Promise

      // 创建一个模块检查队列
      // const moduleCheckPromises = Array.from(window.moduleStatus.pending)
      //   .map(module => {
      //     return checkModuleFile(module)
      //       .then(result => {
      //         console.log(`[模块检查] 模块文件 ${module}.js 检查成功:`, {
      //           size: result.content.length,
      //           preview: result.content.substring(0, 50) + '...'
      //         });
      //         return { module, status: 'success' };
      //       })
      //       .catch(error => {
      //         console.error(`[模块检查] 模块文件 ${module}.js 检查失败:`, error);
      //         return { module, status: 'error', error };
      //       });
      //   });

      // 等待所有模块检查完成
      // return Promise.all(moduleCheckPromises)
      //   .then(results => {
      //     const successModules = results.filter(r => r.status === 'success').map(r => r.module);
      //     const failedModules = results.filter(r => r.status === 'error').map(r => r.module);

      //     console.log(`[模块检查] 模块检查完成:`, {
      //       total: results.length,
      //       success: successModules.length,
      //       failed: failedModules.length,
      //       successModules,
      //       failedModules
      //     });

      //     return results;
      //   });
    }

    // 加载所有模块
    function loadAllModules() {
      console.log('[模块加载] 开始加载所有模块 - (此功能已调整为不执行实际加载)');
      return Promise.resolve([]); // 直接返回一个空的 resolved Promise

      // 创建一个模块加载队列
      // const moduleLoadPromises = Array.from(window.moduleStatus.pending)
      //   .map(module => {
      //     return loadModuleWithGM(module)
      //       .then(() => {
      //         console.log(`[模块加载] 模块 ${module} 加载成功`);
      //         setTimeout(() => checkModuleLoaded(module), 500);
      //         return { module, status: 'success' };
      //       })
      //       .catch(error => {
      //         console.error(`[模块加载] 模块 ${module} 加载失败:`, error);
      //         return { module, status: 'error', error };
      //       });
      //   });

      // 等待所有模块加载完成
      // return Promise.all(moduleLoadPromises)
      //   .then(results => {
      //     const successModules = results.filter(r => r.status === 'success').map(r => r.module);
      //     const failedModules = results.filter(r => r.status === 'error').map(r => r.module);

      //     console.log(`[模块加载] 模块加载完成:`, {
      //       total: results.length,
      //       success: successModules.length,
      //       failed: failedModules.length,
      //       successModules,
      //       failedModules
      //     });

      //     return results;
      //   });
    }

    // 直接注入模块函数到全局作用域
    function injectModuleFunctions() {
      console.log('[调试加载器] 开始注入模块函数到全局作用域');

      // 注入styles模块
      if (!window.applyStyles) {
        window.applyStyles = function() {
          console.log('[模块注入] 执行注入的 applyStyles 函数');
          GM_addStyle(`
            .qh-assistant-panel {
                position: fixed;
                top: 100px;
                right: 10px;
                width: 280px;
                background: linear-gradient(135deg, #00a8cc, #0062bd);
                border-radius: 12px;
                padding: 15px;
                color: white;
                z-index: 9999;
                font-size: 14px;
                box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
            }
            .qh-assistant-title {
                font-size: 18px;
                font-weight: bold;
                text-align: center;
                margin-bottom: 12px;
                border-bottom: 2px solid rgba(255, 255, 255, 0.3);
                padding-bottom: 8px;
            }
            .qh-assistant-content {
                margin-bottom: 12px;
            }
            .qh-assistant-btn {
                background: linear-gradient(90deg, #4CAF50, #45a049);
                border: none;
                color: white;
                padding: 8px 12px;
                text-align: center;
                display: block;
                width: 100%;
                margin: 5px 0;
                cursor: pointer;
                border-radius: 4px;
            }
          `);
          console.log('[模块注入] applyStyles 函数执行完成');
        };
        console.log('[模块注入] 已注入 applyStyles 函数');
      }

      // 注入ui模块
      if (!window.createPanel) {
        window.createPanel = function() {
          console.log('[模块注入] 执行注入的 createPanel 函数');

          // 检查是否已经创建过面板
          if (document.querySelector('.qh-assistant-panel')) {
            console.log('[模块注入] 面板已存在,不重复创建');
            return;
          }

          const panel = document.createElement('div');
          panel.className = 'qh-assistant-panel';
          panel.innerHTML = `
            <div class="qh-assistant-title">岐黄天使刷课助手 v1.3.0</div>
            <div class="qh-assistant-content">
                <div>状态: 调试模式</div>
                <div>当前页面: ${window.location.href}</div>
            </div>
            <button class="qh-assistant-btn" id="qh-debug-btn">调试信息</button>
          `;
          document.body.appendChild(panel);

          // 添加调试按钮事件
          document.getElementById('qh-debug-btn').addEventListener('click', function() {
            console.log('[调试] 当前页面信息:', {
              'URL': window.location.href,
              '已加载模块': Array.from(window.moduleStatus.loaded),
              '待加载模块': Array.from(window.moduleStatus.pending),
              'window.qh': window.qh
            });
            alert('调试信息已输出到控制台');
          });

          console.log('[模块注入] createPanel 函数执行完成');
        };
        console.log('[模块注入] 已注入 createPanel 函数');
      }

      // 注入utils模块
      if (!window.checkPageType) {
        window.checkPageType = function() {
          console.log('[模块注入] 执行注入的 checkPageType 函数');
          console.log('[页面检查] 当前页面URL:', window.location.href);
        };
        console.log('[模块注入] 已注入 checkPageType 函数');
      }

      console.log('[调试加载器] 模块函数注入完成');
    }

    // 导出模块函数
    window.debugLoader = {
      checkModuleLoaded,
      checkModuleFile,
      loadModuleWithGM,
      checkAllModules,
      loadAllModules,
      injectModuleFunctions
    };

    // 自动执行检查和加载
    setTimeout(() => {
      console.log('[调试加载器] 开始自动检查和加载模块');

      // 先注入基本函数
      injectModuleFunctions();

      // 然后检查和加载模块
      checkAllModules()
        .then(() => loadAllModules())
        .then(() => {
          console.log('[调试加载器] 模块检查和加载完成');

          // 如果仍有未加载的模块,使用注入的函数
          if (window.moduleStatus.pending.size > 0) {
            console.log('[调试加载器] 仍有未加载的模块,使用注入的函数');
            window.moduleStatus.loaded.add('styles');
            window.moduleStatus.loaded.add('ui');
            window.moduleStatus.loaded.add('utils');
            window.moduleStatus.pending.delete('styles');
            window.moduleStatus.pending.delete('ui');
            window.moduleStatus.pending.delete('utils');
          }
        })
        .catch(error => {
          console.error('[调试加载器] 模块检查和加载出错:', error);
          console.log('[调试加载器] 使用注入的函数作为备用');
          injectModuleFunctions();
        });
    }, 1000);

    console.log('[调试加载器] 模块已加载');
})();