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

岐黄天使刷课助手的调试与模块状态监控器,用于 @require 架构下的模块状态跟踪和调试支持。

当前为 2025-05-24 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/537076/1594955/%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

  1. // ==UserScript==
  2. // @name 岐黄天使刷课助手 - 调试加载器模块
  3. // @namespace http://tampermonkey.net/qhtx-modules
  4. // @version 1.3.0
  5. // @description 岐黄天使刷课助手的调试与模块状态监控器,用于 @require 架构下的模块状态跟踪和调试支持。
  6. // @author AI助手
  7. // ==/UserScript==
  8.  
  9. /**
  10. * 调试加载器模块 - 重构版本
  11. *
  12. * 此模块已重构以适配基于 GreasyFork @require 指令的生产架构:
  13. * - 移除了所有本地开发服务器 (192.168.1.6:9999) 的 HTTP 请求
  14. * - 保留模块状态跟踪系统,用于监控 @require 加载的模块状态
  15. * - 提供备用函数注入功能,用于调试和开发场景
  16. * - 与 main.user.js 的增强错误处理机制完全兼容
  17. *
  18. * 架构说明:
  19. * - 所有模块现在通过 Tampermonkey 的 @require 机制从 GreasyFork 加载
  20. * - 版本控制通过 URL 查询参数 (?v=x.x.x&t=timestamp) 实现
  21. * - 此调试加载器仅负责状态监控和备用功能提供
  22. */
  23. (function() {
  24. 'use strict';
  25.  
  26. // 添加模块加载状态跟踪
  27. window.moduleStatus = {
  28. loaded: new Set(),
  29. pending: new Set([
  30. // 'styles', 'utils', 'ui', 'videoPlayer',
  31. // 'videoNavigation', 'courseNavigation', 'questionBank',
  32. // 'autoAnswer', 'remoteSync'
  33. ]),
  34. startTime: Date.now(),
  35. // 显示模块加载状态
  36. showStatus: function() {
  37. const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(2);
  38. console.log(`
  39. ========== 模块加载状态 (${elapsed}秒) ==========
  40. 已加载: ${Array.from(this.loaded).join(', ') || '无'}
  41. 待加载: ${Array.from(this.pending).join(', ') || '无'}
  42. ============================================
  43. `);
  44. }
  45. };
  46.  
  47. // 定期显示模块加载状态
  48. window.moduleStatusInterval = setInterval(() => {
  49. if (window.moduleStatus.pending.size === 0) {
  50. clearInterval(window.moduleStatusInterval);
  51. window.moduleStatus.showStatus();
  52. console.log('%c所有模块加载完成!', 'color: green; font-size: 14px; font-weight: bold');
  53. } else {
  54. window.moduleStatus.showStatus();
  55. }
  56. }, 2000);
  57.  
  58. // 检查模块加载状态
  59. function checkModuleLoaded(moduleName) {
  60. const now = new Date();
  61. const timeStr = now.toLocaleTimeString() + '.' + now.getMilliseconds();
  62. console.log(`[模块加载] 正在验证 ${moduleName} 状态,当前时间: ${timeStr}`);
  63.  
  64. // 详细检查window对象上的模块属性
  65. console.log(`[模块加载详情] ${moduleName} 检查:`, {
  66. '直接访问': window[moduleName],
  67. '类型': typeof window[moduleName],
  68. '是否存在': moduleName in window,
  69. 'window属性': Object.keys(window).filter(k => k.includes(moduleName)),
  70. '全局变量': Object.keys(window).filter(k => k.startsWith('qh') || k.includes('module') || k.includes('Module'))
  71. });
  72.  
  73. // 检查模块是否已加载
  74. if (typeof window[moduleName] === 'function') {
  75. window.moduleStatus.loaded.add(moduleName);
  76. window.moduleStatus.pending.delete(moduleName);
  77.  
  78. console.log(`[模块加载] %c${moduleName} 已就绪%c`,
  79. 'color: green; font-weight: bold', 'color: black');
  80.  
  81. // 输出已加载的模块列表
  82. console.log(`[模块加载] 已加载模块: ${Array.from(window.moduleStatus.loaded).join(', ')}`);
  83. console.log(`[模块加载] 待加载模块: ${Array.from(window.moduleStatus.pending).join(', ')}`);
  84.  
  85. return true;
  86. }
  87.  
  88. // 如果模块未加载,尝试检查是否有其他命名方式
  89. const possibleNames = [
  90. moduleName,
  91. moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // 首字母大写
  92. moduleName + 'Module',
  93. 'qh' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // qh前缀
  94. 'create' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // create前缀
  95. 'init' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // init前缀
  96. 'apply' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1) // apply前缀
  97. ];
  98.  
  99. console.log(`[模块加载] 尝试其他可能的命名:`, possibleNames.map(name => ({
  100. name,
  101. exists: name in window,
  102. type: typeof window[name]
  103. })));
  104.  
  105. console.warn(`[模块加载] %c${moduleName} 未就绪%cwindow[${moduleName}] = ${window[moduleName]}`,
  106. 'color: red; font-weight: bold', 'color: black');
  107.  
  108. return false;
  109. }
  110.  
  111. /**
  112. * 检查模块文件 (已重构)
  113. *
  114. * 此函数已重构为不执行实际的 HTTP 请求。
  115. * 在 @require 架构下,模块由 Tampermonkey 自动加载,
  116. * 此函数仅用于兼容性和调试目的。
  117. *
  118. * @param {string} moduleName - 模块名称
  119. * @returns {Promise} - 始终返回成功的 Promise
  120. */
  121. function checkModuleFile(moduleName) {
  122. console.log(`[模块检查] 模块 ${moduleName} 应通过 @require GreasyFork 加载,跳过本地检查`);
  123. return Promise.resolve({
  124. module: moduleName,
  125. content: '@require-loaded',
  126. status: 200,
  127. source: 'greasyfork-require'
  128. });
  129. }
  130.  
  131. /**
  132. * 加载模块 (已重构)
  133. *
  134. * 此函数已重构为不执行实际的模块加载。
  135. * 在 @require 架构下,模块由 Tampermonkey 在脚本启动时自动加载,
  136. * 此函数仅用于兼容性和状态跟踪目的。
  137. *
  138. * @param {string} moduleName - 模块名称
  139. * @returns {Promise} - 始终返回成功的 Promise
  140. */
  141. function loadModuleWithGM(moduleName) {
  142. console.log(`[模块加载] 模块 ${moduleName} 应通过 @require GreasyFork 自动加载,跳过手动加载`);
  143. return Promise.resolve({
  144. module: moduleName,
  145. loaded: true,
  146. source: 'greasyfork-require',
  147. timestamp: Date.now()
  148. });
  149. }
  150.  
  151. /**
  152. * 检查所有模块 (已重构)
  153. *
  154. * 此函数已重构为不执行实际的模块检查。
  155. * 在 @require 架构下,模块状态检查通过检测全局函数是否存在来实现。
  156. *
  157. * @returns {Promise} - 返回模块状态检查结果
  158. */
  159. function checkAllModules() {
  160. console.log('[模块检查] @require 架构下的模块状态检查');
  161.  
  162. // 检查关键模块函数是否已加载
  163. const moduleChecks = [
  164. { name: 'styles', func: 'applyStyles' },
  165. { name: 'ui', func: 'createPanel' },
  166. { name: 'utils', func: 'checkPageType' },
  167. { name: 'questionBank', func: 'getQuestionList' },
  168. { name: 'autoAnswer', func: 'startAutoAnswer' },
  169. { name: 'videoPlayer', func: 'toggleAutoLearn' }
  170. ];
  171.  
  172. const results = moduleChecks.map(check => {
  173. const isLoaded = typeof window[check.func] === 'function';
  174. const status = isLoaded ? 'loaded' : 'pending';
  175.  
  176. if (isLoaded) {
  177. window.moduleStatus.loaded.add(check.name);
  178. window.moduleStatus.pending.delete(check.name);
  179. } else {
  180. window.moduleStatus.pending.add(check.name);
  181. }
  182.  
  183. return {
  184. module: check.name,
  185. function: check.func,
  186. status: status,
  187. loaded: isLoaded
  188. };
  189. });
  190.  
  191. console.log('[模块检查] @require 模块状态检查完成:', results);
  192. return Promise.resolve(results);
  193. }
  194.  
  195. /**
  196. * 加载所有模块 (已重构)
  197. *
  198. * 此函数已重构为不执行实际的模块加载。
  199. * 在 @require 架构下,模块由 Tampermonkey 自动加载,
  200. * 此函数仅用于状态同步和兼容性目的。
  201. *
  202. * @returns {Promise} - 返回模块加载状态结果
  203. */
  204. function loadAllModules() {
  205. console.log('[模块加载] @require 架构下的模块状态同步');
  206.  
  207. // 重新检查模块状态,确保状态同步
  208. return checkAllModules().then(results => {
  209. const loadedModules = results.filter(r => r.loaded);
  210. const pendingModules = results.filter(r => !r.loaded);
  211.  
  212. console.log(`[模块加载] 模块状态同步完成:`, {
  213. total: results.length,
  214. loaded: loadedModules.length,
  215. pending: pendingModules.length,
  216. loadedModules: loadedModules.map(m => m.module),
  217. pendingModules: pendingModules.map(m => m.module)
  218. });
  219.  
  220. return results;
  221. });
  222. }
  223.  
  224. /**
  225. * 注入备用模块函数到全局作用域
  226. *
  227. * 此函数提供备用的模块函数实现,用于以下场景:
  228. * - @require 模块加载失败时的降级方案
  229. * - 开发和调试阶段的基本功能支持
  230. * - 确保核心功能在任何情况下都能正常工作
  231. *
  232. * 注意:这些是简化的备用实现,功能有限
  233. */
  234. function injectModuleFunctions() {
  235. console.log('[调试加载器] 开始注入备用模块函数到全局作用域');
  236.  
  237. // 注入styles模块
  238. if (!window.applyStyles) {
  239. window.applyStyles = function() {
  240. console.log('[模块注入] 执行注入的 applyStyles 函数');
  241. GM_addStyle(`
  242. .qh-assistant-panel {
  243. position: fixed;
  244. top: 100px;
  245. right: 10px;
  246. width: 280px;
  247. background: linear-gradient(135deg, #00a8cc, #0062bd);
  248. border-radius: 12px;
  249. padding: 15px;
  250. color: white;
  251. z-index: 9999;
  252. font-size: 14px;
  253. box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  254. }
  255. .qh-assistant-title {
  256. font-size: 18px;
  257. font-weight: bold;
  258. text-align: center;
  259. margin-bottom: 12px;
  260. border-bottom: 2px solid rgba(255, 255, 255, 0.3);
  261. padding-bottom: 8px;
  262. }
  263. .qh-assistant-content {
  264. margin-bottom: 12px;
  265. }
  266. .qh-assistant-btn {
  267. background: linear-gradient(90deg, #4CAF50, #45a049);
  268. border: none;
  269. color: white;
  270. padding: 8px 12px;
  271. text-align: center;
  272. display: block;
  273. width: 100%;
  274. margin: 5px 0;
  275. cursor: pointer;
  276. border-radius: 4px;
  277. }
  278. `);
  279. console.log('[模块注入] applyStyles 函数执行完成');
  280. };
  281. console.log('[模块注入] 已注入 applyStyles 函数');
  282. }
  283.  
  284. // 注入ui模块
  285. if (!window.createPanel) {
  286. window.createPanel = function() {
  287. console.log('[模块注入] 执行注入的 createPanel 函数');
  288.  
  289. // 检查是否已经创建过面板
  290. if (document.querySelector('.qh-assistant-panel')) {
  291. console.log('[模块注入] 面板已存在,不重复创建');
  292. return;
  293. }
  294.  
  295. const panel = document.createElement('div');
  296. panel.className = 'qh-assistant-panel';
  297. panel.innerHTML = `
  298. <div class="qh-assistant-title">岐黄天使刷课助手 v1.3.0</div>
  299. <div class="qh-assistant-content">
  300. <div>状态: 调试模式</div>
  301. <div>当前页面: ${window.location.href}</div>
  302. </div>
  303. <button class="qh-assistant-btn" id="qh-debug-btn">调试信息</button>
  304. `;
  305. document.body.appendChild(panel);
  306.  
  307. // 添加调试按钮事件
  308. document.getElementById('qh-debug-btn').addEventListener('click', function() {
  309. console.log('[调试] 当前页面信息:', {
  310. 'URL': window.location.href,
  311. '已加载模块': Array.from(window.moduleStatus.loaded),
  312. '待加载模块': Array.from(window.moduleStatus.pending),
  313. 'window.qh': window.qh
  314. });
  315. alert('调试信息已输出到控制台');
  316. });
  317.  
  318. console.log('[模块注入] createPanel 函数执行完成');
  319. };
  320. console.log('[模块注入] 已注入 createPanel 函数');
  321. }
  322.  
  323. // 注入utils模块
  324. if (!window.checkPageType) {
  325. window.checkPageType = function() {
  326. console.log('[模块注入] 执行注入的 checkPageType 函数');
  327. console.log('[页面检查] 当前页面URL:', window.location.href);
  328. };
  329. console.log('[模块注入] 已注入 checkPageType 函数');
  330. }
  331.  
  332. console.log('[调试加载器] 模块函数注入完成');
  333. }
  334.  
  335. // 导出模块函数
  336. window.debugLoader = {
  337. checkModuleLoaded,
  338. checkModuleFile,
  339. loadModuleWithGM,
  340. checkAllModules,
  341. loadAllModules,
  342. injectModuleFunctions
  343. };
  344.  
  345. /**
  346. * 自动执行模块状态检查和备用函数准备
  347. *
  348. * 在 @require 架构下,此函数主要用于:
  349. * - 检查 @require 加载的模块状态
  350. * - 在需要时提供备用函数
  351. * - 与 main.user.js 的初始化流程协调
  352. */
  353. setTimeout(() => {
  354. console.log('[调试加载器] @require 架构下的模块状态检查开始');
  355.  
  356. // 首先检查 @require 模块的加载状态
  357. checkAllModules()
  358. .then(results => {
  359. const loadedCount = results.filter(r => r.loaded).length;
  360. const totalCount = results.length;
  361.  
  362. console.log(`[调试加载器] @require 模块状态检查完成: ${loadedCount}/${totalCount} 已加载`);
  363.  
  364. // 如果有模块未加载,提供备用函数
  365. if (loadedCount < totalCount) {
  366. console.log('[调试加载器] 检测到未加载的模块,准备备用函数');
  367. injectModuleFunctions();
  368.  
  369. // 更新状态,标记备用函数已提供
  370. results.forEach(result => {
  371. if (!result.loaded) {
  372. window.moduleStatus.loaded.add(result.module + '-fallback');
  373. console.log(`[调试加载器] ${result.module} 提供了备用函数`);
  374. }
  375. });
  376. } else {
  377. console.log('[调试加载器] 所有 @require 模块已正常加载,无需备用函数');
  378. }
  379.  
  380. return loadAllModules();
  381. })
  382. .then(() => {
  383. console.log('[调试加载器] 模块状态同步完成');
  384. })
  385. .catch(error => {
  386. console.error('[调试加载器] 模块状态检查出错:', error);
  387. console.log('[调试加载器] 启用备用函数作为安全措施');
  388. injectModuleFunctions();
  389. });
  390. }, 500); // 减少延迟,因为 @require 模块应该已经加载
  391.  
  392. console.log('[调试加载器] 模块已加载 - @require 架构兼容版本');
  393. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址