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

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

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

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/537076/1594813/%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 岐黄天使刷课助手的调试与模块加载器,用于开发和测试阶段管理模块依赖。
  6. // @author AI助手
  7. // ==/UserScript==
  8.  
  9. // 调试加载器模块
  10. (function() {
  11. 'use strict';
  12.  
  13. // 添加模块加载状态跟踪
  14. window.moduleStatus = {
  15. loaded: new Set(),
  16. pending: new Set([
  17. 'styles', 'utils', 'ui', 'videoPlayer',
  18. 'videoNavigation', 'courseNavigation', 'questionBank',
  19. 'autoAnswer', 'remoteSync'
  20. ]),
  21. startTime: Date.now(),
  22. // 显示模块加载状态
  23. showStatus: function() {
  24. const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(2);
  25. console.log(`
  26. ========== 模块加载状态 (${elapsed}秒) ==========
  27. 已加载: ${Array.from(this.loaded).join(', ') || '无'}
  28. 待加载: ${Array.from(this.pending).join(', ') || '无'}
  29. ============================================
  30. `);
  31. }
  32. };
  33.  
  34. // 定期显示模块加载状态
  35. window.moduleStatusInterval = setInterval(() => {
  36. if (window.moduleStatus.pending.size === 0) {
  37. clearInterval(window.moduleStatusInterval);
  38. window.moduleStatus.showStatus();
  39. console.log('%c所有模块加载完成!', 'color: green; font-size: 14px; font-weight: bold');
  40. } else {
  41. window.moduleStatus.showStatus();
  42. }
  43. }, 2000);
  44.  
  45. // 检查模块加载状态
  46. function checkModuleLoaded(moduleName) {
  47. const now = new Date();
  48. const timeStr = now.toLocaleTimeString() + '.' + now.getMilliseconds();
  49. console.log(`[模块加载] 正在验证 ${moduleName} 状态,当前时间: ${timeStr}`);
  50.  
  51. // 详细检查window对象上的模块属性
  52. console.log(`[模块加载详情] ${moduleName} 检查:`, {
  53. '直接访问': window[moduleName],
  54. '类型': typeof window[moduleName],
  55. '是否存在': moduleName in window,
  56. 'window属性': Object.keys(window).filter(k => k.includes(moduleName)),
  57. '全局变量': Object.keys(window).filter(k => k.startsWith('qh') || k.includes('module') || k.includes('Module'))
  58. });
  59.  
  60. // 检查模块是否已加载
  61. if (typeof window[moduleName] === 'function') {
  62. window.moduleStatus.loaded.add(moduleName);
  63. window.moduleStatus.pending.delete(moduleName);
  64.  
  65. console.log(`[模块加载] %c${moduleName} 已就绪%c`,
  66. 'color: green; font-weight: bold', 'color: black');
  67.  
  68. // 输出已加载的模块列表
  69. console.log(`[模块加载] 已加载模块: ${Array.from(window.moduleStatus.loaded).join(', ')}`);
  70. console.log(`[模块加载] 待加载模块: ${Array.from(window.moduleStatus.pending).join(', ')}`);
  71.  
  72. return true;
  73. }
  74.  
  75. // 如果模块未加载,尝试检查是否有其他命名方式
  76. const possibleNames = [
  77. moduleName,
  78. moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // 首字母大写
  79. moduleName + 'Module',
  80. 'qh' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // qh前缀
  81. 'create' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // create前缀
  82. 'init' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1), // init前缀
  83. 'apply' + moduleName.charAt(0).toUpperCase() + moduleName.slice(1) // apply前缀
  84. ];
  85.  
  86. console.log(`[模块加载] 尝试其他可能的命名:`, possibleNames.map(name => ({
  87. name,
  88. exists: name in window,
  89. type: typeof window[name]
  90. })));
  91.  
  92. console.warn(`[模块加载] %c${moduleName} 未就绪%cwindow[${moduleName}] = ${window[moduleName]}`,
  93. 'color: red; font-weight: bold', 'color: black');
  94.  
  95. return false;
  96. }
  97.  
  98. // 使用GM_xmlhttpRequest检查模块文件
  99. function checkModuleFile(moduleName) {
  100. return new Promise((resolve, reject) => {
  101. const url = `//192.168.1.6:9999/qhtx/${moduleName}.js?check=${Date.now()}`;
  102. console.log(`[模块检查] 使用GM_xmlhttpRequest检查模块文件: ${url}`);
  103.  
  104. if (typeof GM_xmlhttpRequest !== 'function') {
  105. console.error('[模块检查] GM_xmlhttpRequest不可用');
  106. reject('GM_xmlhttpRequest不可用');
  107. return;
  108. }
  109.  
  110. GM_xmlhttpRequest({
  111. method: 'GET',
  112. url: url,
  113. onload: function(response) {
  114. console.log(`[模块检查] ${moduleName}.js 检查结果:`, {
  115. status: response.status,
  116. statusText: response.statusText,
  117. responseSize: response.responseText ? response.responseText.length : 0,
  118. responsePreview: response.responseText ? response.responseText.substring(0, 100) + '...' : '无内容'
  119. });
  120.  
  121. if (response.status >= 200 && response.status < 300) {
  122. resolve({
  123. module: moduleName,
  124. content: response.responseText,
  125. status: response.status
  126. });
  127. } else {
  128. reject(`HTTP错误: ${response.status} ${response.statusText}`);
  129. }
  130. },
  131. onerror: function(error) {
  132. console.error(`[模块检查] ${moduleName}.js 请求失败:`, error);
  133. reject(`请求失败: ${error.error || '未知错误'}`);
  134. },
  135. ontimeout: function() {
  136. console.error(`[模块检查] ${moduleName}.js 请求超时`);
  137. reject('请求超时');
  138. }
  139. });
  140. });
  141. }
  142.  
  143. // 使用GM_xmlhttpRequest直接加载模块
  144. function loadModuleWithGM(moduleName) {
  145. return new Promise((resolve, reject) => {
  146. const url = `//192.168.1.6:9999/qhtx/${moduleName}.js?direct=true&t=${Date.now()}`;
  147. console.log(`[模块加载] 使用GM_xmlhttpRequest直接加载模块: ${url}`);
  148.  
  149. if (typeof GM_xmlhttpRequest !== 'function') {
  150. console.error('[模块加载] GM_xmlhttpRequest不可用,无法直接加载模块');
  151. reject('GM_xmlhttpRequest不可用');
  152. return;
  153. }
  154.  
  155. GM_xmlhttpRequest({
  156. method: 'GET',
  157. url: url,
  158. onload: function(response) {
  159. if (response.status >= 200 && response.status < 300) {
  160. console.log(`[模块加载] 成功获取模块 ${moduleName}.js 内容,长度: ${response.responseText.length}字节`);
  161.  
  162. try {
  163. // 创建一个新的script元素
  164. const script = document.createElement('script');
  165. script.textContent = response.responseText;
  166. document.head.appendChild(script);
  167.  
  168. console.log(`[模块加载] 模块 ${moduleName}.js 已注入到页面`);
  169. resolve(true);
  170. } catch (error) {
  171. console.error(`[模块加载] 注入模块 ${moduleName}.js 时出错:`, error);
  172. reject(error);
  173. }
  174. } else {
  175. console.error(`[模块加载] 获取模块 ${moduleName}.js 失败: HTTP ${response.status}`);
  176. reject(`HTTP错误: ${response.status}`);
  177. }
  178. },
  179. onerror: function(error) {
  180. console.error(`[模块加载] 请求模块 ${moduleName}.js 时出错:`, error);
  181. reject(error);
  182. }
  183. });
  184. });
  185. }
  186.  
  187. // 检查所有模块
  188. function checkAllModules() {
  189. console.log('[模块检查] 开始检查所有模块文件');
  190.  
  191. // 创建一个模块检查队列
  192. const moduleCheckPromises = Array.from(window.moduleStatus.pending)
  193. .map(module => {
  194. return checkModuleFile(module)
  195. .then(result => {
  196. console.log(`[模块检查] 模块文件 ${module}.js 检查成功:`, {
  197. size: result.content.length,
  198. preview: result.content.substring(0, 50) + '...'
  199. });
  200. return { module, status: 'success' };
  201. })
  202. .catch(error => {
  203. console.error(`[模块检查] 模块文件 ${module}.js 检查失败:`, error);
  204. return { module, status: 'error', error };
  205. });
  206. });
  207.  
  208. // 等待所有模块检查完成
  209. return Promise.all(moduleCheckPromises)
  210. .then(results => {
  211. const successModules = results.filter(r => r.status === 'success').map(r => r.module);
  212. const failedModules = results.filter(r => r.status === 'error').map(r => r.module);
  213.  
  214. console.log(`[模块检查] 模块检查完成:`, {
  215. total: results.length,
  216. success: successModules.length,
  217. failed: failedModules.length,
  218. successModules,
  219. failedModules
  220. });
  221.  
  222. return results;
  223. });
  224. }
  225.  
  226. // 加载所有模块
  227. function loadAllModules() {
  228. console.log('[模块加载] 开始加载所有模块');
  229.  
  230. // 创建一个模块加载队列
  231. const moduleLoadPromises = Array.from(window.moduleStatus.pending)
  232. .map(module => {
  233. return loadModuleWithGM(module)
  234. .then(() => {
  235. console.log(`[模块加载] 模块 ${module} 加载成功`);
  236. setTimeout(() => checkModuleLoaded(module), 500);
  237. return { module, status: 'success' };
  238. })
  239. .catch(error => {
  240. console.error(`[模块加载] 模块 ${module} 加载失败:`, error);
  241. return { module, status: 'error', error };
  242. });
  243. });
  244.  
  245. // 等待所有模块加载完成
  246. return Promise.all(moduleLoadPromises)
  247. .then(results => {
  248. const successModules = results.filter(r => r.status === 'success').map(r => r.module);
  249. const failedModules = results.filter(r => r.status === 'error').map(r => r.module);
  250.  
  251. console.log(`[模块加载] 模块加载完成:`, {
  252. total: results.length,
  253. success: successModules.length,
  254. failed: failedModules.length,
  255. successModules,
  256. failedModules
  257. });
  258.  
  259. return results;
  260. });
  261. }
  262.  
  263. // 直接注入模块函数到全局作用域
  264. function injectModuleFunctions() {
  265. console.log('[调试加载器] 开始注入模块函数到全局作用域');
  266.  
  267. // 注入styles模块
  268. if (!window.applyStyles) {
  269. window.applyStyles = function() {
  270. console.log('[模块注入] 执行注入的 applyStyles 函数');
  271. GM_addStyle(`
  272. .qh-assistant-panel {
  273. position: fixed;
  274. top: 100px;
  275. right: 10px;
  276. width: 280px;
  277. background: linear-gradient(135deg, #00a8cc, #0062bd);
  278. border-radius: 12px;
  279. padding: 15px;
  280. color: white;
  281. z-index: 9999;
  282. font-size: 14px;
  283. box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  284. }
  285. .qh-assistant-title {
  286. font-size: 18px;
  287. font-weight: bold;
  288. text-align: center;
  289. margin-bottom: 12px;
  290. border-bottom: 2px solid rgba(255, 255, 255, 0.3);
  291. padding-bottom: 8px;
  292. }
  293. .qh-assistant-content {
  294. margin-bottom: 12px;
  295. }
  296. .qh-assistant-btn {
  297. background: linear-gradient(90deg, #4CAF50, #45a049);
  298. border: none;
  299. color: white;
  300. padding: 8px 12px;
  301. text-align: center;
  302. display: block;
  303. width: 100%;
  304. margin: 5px 0;
  305. cursor: pointer;
  306. border-radius: 4px;
  307. }
  308. `);
  309. console.log('[模块注入] applyStyles 函数执行完成');
  310. };
  311. console.log('[模块注入] 已注入 applyStyles 函数');
  312. }
  313.  
  314. // 注入ui模块
  315. if (!window.createPanel) {
  316. window.createPanel = function() {
  317. console.log('[模块注入] 执行注入的 createPanel 函数');
  318.  
  319. // 检查是否已经创建过面板
  320. if (document.querySelector('.qh-assistant-panel')) {
  321. console.log('[模块注入] 面板已存在,不重复创建');
  322. return;
  323. }
  324.  
  325. const panel = document.createElement('div');
  326. panel.className = 'qh-assistant-panel';
  327. panel.innerHTML = `
  328. <div class="qh-assistant-title">岐黄天使刷课助手 v1.3.0</div>
  329. <div class="qh-assistant-content">
  330. <div>状态: 调试模式</div>
  331. <div>当前页面: ${window.location.href}</div>
  332. </div>
  333. <button class="qh-assistant-btn" id="qh-debug-btn">调试信息</button>
  334. `;
  335. document.body.appendChild(panel);
  336.  
  337. // 添加调试按钮事件
  338. document.getElementById('qh-debug-btn').addEventListener('click', function() {
  339. console.log('[调试] 当前页面信息:', {
  340. 'URL': window.location.href,
  341. '已加载模块': Array.from(window.moduleStatus.loaded),
  342. '待加载模块': Array.from(window.moduleStatus.pending),
  343. 'window.qh': window.qh
  344. });
  345. alert('调试信息已输出到控制台');
  346. });
  347.  
  348. console.log('[模块注入] createPanel 函数执行完成');
  349. };
  350. console.log('[模块注入] 已注入 createPanel 函数');
  351. }
  352.  
  353. // 注入utils模块
  354. if (!window.checkPageType) {
  355. window.checkPageType = function() {
  356. console.log('[模块注入] 执行注入的 checkPageType 函数');
  357. console.log('[页面检查] 当前页面URL:', window.location.href);
  358. };
  359. console.log('[模块注入] 已注入 checkPageType 函数');
  360. }
  361.  
  362. console.log('[调试加载器] 模块函数注入完成');
  363. }
  364.  
  365. // 导出模块函数
  366. window.debugLoader = {
  367. checkModuleLoaded,
  368. checkModuleFile,
  369. loadModuleWithGM,
  370. checkAllModules,
  371. loadAllModules,
  372. injectModuleFunctions
  373. };
  374.  
  375. // 自动执行检查和加载
  376. setTimeout(() => {
  377. console.log('[调试加载器] 开始自动检查和加载模块');
  378.  
  379. // 先注入基本函数
  380. injectModuleFunctions();
  381.  
  382. // 然后检查和加载模块
  383. checkAllModules()
  384. .then(() => loadAllModules())
  385. .then(() => {
  386. console.log('[调试加载器] 模块检查和加载完成');
  387.  
  388. // 如果仍有未加载的模块,使用注入的函数
  389. if (window.moduleStatus.pending.size > 0) {
  390. console.log('[调试加载器] 仍有未加载的模块,使用注入的函数');
  391. window.moduleStatus.loaded.add('styles');
  392. window.moduleStatus.loaded.add('ui');
  393. window.moduleStatus.loaded.add('utils');
  394. window.moduleStatus.pending.delete('styles');
  395. window.moduleStatus.pending.delete('ui');
  396. window.moduleStatus.pending.delete('utils');
  397. }
  398. })
  399. .catch(error => {
  400. console.error('[调试加载器] 模块检查和加载出错:', error);
  401. console.log('[调试加载器] 使用注入的函数作为备用');
  402. injectModuleFunctions();
  403. });
  404. }, 1000);
  405.  
  406. console.log('[调试加载器] 模块已加载');
  407. })();

QingJ © 2025

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