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

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

Verzia zo dňa 24.05.2025. Pozri najnovšiu verziu.

Tento skript by nemal byť nainštalovaný priamo. Je to knižnica pre ďalšie skripty, ktorú by mali používať cez meta príkaz // @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('[调试加载器] 模块已加载');
})();