بۇ قوليازمىنى بىۋاسىتە قاچىلاشقا بولمايدۇ. بۇ باشقا قوليازمىلارنىڭ ئىشلىتىشى ئۈچۈن تەمىنلەنگەن ئامبار بولۇپ، ئىشلىتىش ئۈچۈن مېتا كۆرسەتمىسىگە قىستۇرىدىغان كود: // @require https://update.greasyfork.org/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
// ==UserScript==
// @name 岐黄天使刷课助手 - 调试加载器模块
// @namespace http://tampermonkey.net/qhtx-modules
// @version 1.3.0
// @description 岐黄天使刷课助手的调试与模块状态监控器,用于 @require 架构下的模块状态跟踪和调试支持。
// @author AI助手
// ==/UserScript==
/**
* 调试加载器模块 - 重构版本
*
* 此模块已重构以适配基于 GreasyFork @require 指令的生产架构:
* - 移除了所有本地开发服务器 (192.168.1.6:9999) 的 HTTP 请求
* - 保留模块状态跟踪系统,用于监控 @require 加载的模块状态
* - 提供备用函数注入功能,用于调试和开发场景
* - 与 main.user.js 的增强错误处理机制完全兼容
*
* 架构说明:
* - 所有模块现在通过 Tampermonkey 的 @require 机制从 GreasyFork 加载
* - 版本控制通过 URL 查询参数 (?v=x.x.x&t=timestamp) 实现
* - 此调试加载器仅负责状态监控和备用功能提供
*/
(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;
}
/**
* 检查模块文件 (已重构)
*
* 此函数已重构为不执行实际的 HTTP 请求。
* 在 @require 架构下,模块由 Tampermonkey 自动加载,
* 此函数仅用于兼容性和调试目的。
*
* @param {string} moduleName - 模块名称
* @returns {Promise} - 始终返回成功的 Promise
*/
function checkModuleFile(moduleName) {
console.log(`[模块检查] 模块 ${moduleName} 应通过 @require 从 GreasyFork 加载,跳过本地检查`);
return Promise.resolve({
module: moduleName,
content: '@require-loaded',
status: 200,
source: 'greasyfork-require'
});
}
/**
* 加载模块 (已重构)
*
* 此函数已重构为不执行实际的模块加载。
* 在 @require 架构下,模块由 Tampermonkey 在脚本启动时自动加载,
* 此函数仅用于兼容性和状态跟踪目的。
*
* @param {string} moduleName - 模块名称
* @returns {Promise} - 始终返回成功的 Promise
*/
function loadModuleWithGM(moduleName) {
console.log(`[模块加载] 模块 ${moduleName} 应通过 @require 从 GreasyFork 自动加载,跳过手动加载`);
return Promise.resolve({
module: moduleName,
loaded: true,
source: 'greasyfork-require',
timestamp: Date.now()
});
}
/**
* 检查所有模块 (已重构)
*
* 此函数已重构为不执行实际的模块检查。
* 在 @require 架构下,模块状态检查通过检测全局函数是否存在来实现。
*
* @returns {Promise} - 返回模块状态检查结果
*/
function checkAllModules() {
console.log('[模块检查] @require 架构下的模块状态检查');
// 检查关键模块函数是否已加载
const moduleChecks = [
{ name: 'styles', func: 'applyStyles' },
{ name: 'ui', func: 'createPanel' },
{ name: 'utils', func: 'checkPageType' },
{ name: 'questionBank', func: 'getQuestionList' },
{ name: 'autoAnswer', func: 'startAutoAnswer' },
{ name: 'videoPlayer', func: 'toggleAutoLearn' }
];
const results = moduleChecks.map(check => {
const isLoaded = typeof window[check.func] === 'function';
const status = isLoaded ? 'loaded' : 'pending';
if (isLoaded) {
window.moduleStatus.loaded.add(check.name);
window.moduleStatus.pending.delete(check.name);
} else {
window.moduleStatus.pending.add(check.name);
}
return {
module: check.name,
function: check.func,
status: status,
loaded: isLoaded
};
});
console.log('[模块检查] @require 模块状态检查完成:', results);
return Promise.resolve(results);
}
/**
* 加载所有模块 (已重构)
*
* 此函数已重构为不执行实际的模块加载。
* 在 @require 架构下,模块由 Tampermonkey 自动加载,
* 此函数仅用于状态同步和兼容性目的。
*
* @returns {Promise} - 返回模块加载状态结果
*/
function loadAllModules() {
console.log('[模块加载] @require 架构下的模块状态同步');
// 重新检查模块状态,确保状态同步
return checkAllModules().then(results => {
const loadedModules = results.filter(r => r.loaded);
const pendingModules = results.filter(r => !r.loaded);
console.log(`[模块加载] 模块状态同步完成:`, {
total: results.length,
loaded: loadedModules.length,
pending: pendingModules.length,
loadedModules: loadedModules.map(m => m.module),
pendingModules: pendingModules.map(m => m.module)
});
return results;
});
}
/**
* 注入备用模块函数到全局作用域
*
* 此函数提供备用的模块函数实现,用于以下场景:
* - @require 模块加载失败时的降级方案
* - 开发和调试阶段的基本功能支持
* - 确保核心功能在任何情况下都能正常工作
*
* 注意:这些是简化的备用实现,功能有限
*/
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
};
/**
* 自动执行模块状态检查和备用函数准备
*
* 在 @require 架构下,此函数主要用于:
* - 检查 @require 加载的模块状态
* - 在需要时提供备用函数
* - 与 main.user.js 的初始化流程协调
*/
setTimeout(() => {
console.log('[调试加载器] @require 架构下的模块状态检查开始');
// 首先检查 @require 模块的加载状态
checkAllModules()
.then(results => {
const loadedCount = results.filter(r => r.loaded).length;
const totalCount = results.length;
console.log(`[调试加载器] @require 模块状态检查完成: ${loadedCount}/${totalCount} 已加载`);
// 如果有模块未加载,提供备用函数
if (loadedCount < totalCount) {
console.log('[调试加载器] 检测到未加载的模块,准备备用函数');
injectModuleFunctions();
// 更新状态,标记备用函数已提供
results.forEach(result => {
if (!result.loaded) {
window.moduleStatus.loaded.add(result.module + '-fallback');
console.log(`[调试加载器] 为 ${result.module} 提供了备用函数`);
}
});
} else {
console.log('[调试加载器] 所有 @require 模块已正常加载,无需备用函数');
}
return loadAllModules();
})
.then(() => {
console.log('[调试加载器] 模块状态同步完成');
})
.catch(error => {
console.error('[调试加载器] 模块状态检查出错:', error);
console.log('[调试加载器] 启用备用函数作为安全措施');
injectModuleFunctions();
});
}, 500); // 减少延迟,因为 @require 模块应该已经加载
console.log('[调试加载器] 模块已加载 - @require 架构兼容版本');
})();