完成扩展

This commit is contained in:
dela
2026-01-10 16:53:02 +08:00
parent 9eba656dbd
commit 97b162939e
31 changed files with 8436 additions and 0 deletions

View File

@@ -0,0 +1,229 @@
/**
* Content Script Loader
* Dynamically injects enabled modules into the page context
*/
// Module instances registry
const moduleInstances = new Map();
// Module metadata
const MODULE_METADATA = {
captchaSolver: {
filename: 'CaptchaSolverModule.js',
className: 'CaptchaSolverModule',
instanceKey: '__captchaSolverInstance'
},
hcaptchaBypass: {
filename: 'HCaptchaBypassModule.js',
className: 'HCaptchaBypassModule',
instanceKey: '__hcaptchaBypassInstance'
},
threeDSecure: {
filename: 'ThreeDSecureHandlerModule.js',
className: 'ThreeDSecureHandlerModule',
instanceKey: '__threeDSecureInstance'
},
gogPayment: {
filename: 'GogPaymentHandlerModule.js',
className: 'GogPaymentHandlerModule',
instanceKey: '__gogPaymentInstance'
},
autoFill: {
filename: 'AutoFillHandlerModule.js',
className: 'AutoFillHandlerModule',
instanceKey: '__autoFillInstance'
},
fetchSpy: {
filename: 'FetchInterceptorModule.js',
className: 'FetchInterceptorModule',
instanceKey: '__fetchSpyInstance'
},
paymentHandler: {
filename: 'PaymentHandlerModule.js',
className: 'PaymentHandlerModule',
instanceKey: '__paymentHandlerInstance'
}
};
// Initialize content script
console.log('[ContentScript] Initializing...');
// Load enabled modules
loadEnabledModules();
// Listen for config changes from background
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'CONFIG_CHANGED') {
console.log('[ContentScript] Config changed, reloading modules...');
handleConfigChange(message.changes);
}
sendResponse({ success: true });
});
// Listen for module events from page context
window.addEventListener('message', (event) => {
// Only accept messages from same window
if (event.source !== window) return;
const message = event.data;
// Forward module events to background
if (message && typeof message === 'object' && message.type && message.type.startsWith('CAPTCHA_SOLVER_') ||
message.type === 'CARD_GENERATED' ||
message.type === 'FORM_FILLED' ||
message.type === 'PAYMENT_CAPTURED') {
chrome.runtime.sendMessage({
type: 'MODULE_EVENT',
payload: message
}).catch(err => {
console.error('[ContentScript] Failed to send event to background:', err);
});
}
});
/**
* Load all enabled modules from storage
*/
async function loadEnabledModules() {
try {
const config = await chrome.storage.sync.get(['modules', 'globalSettings', 'apiKeys']);
console.log('[ContentScript] Loaded config:', config);
// Check master switch
if (!config.globalSettings?.masterEnabled) {
console.log('[ContentScript] Master switch disabled, skipping module load');
return;
}
// Load each enabled module
for (const [moduleName, moduleConfig] of Object.entries(config.modules || {})) {
if (moduleConfig.enabled) {
await loadModule(moduleName, moduleConfig.config, config.apiKeys);
}
}
console.log('[ContentScript] All enabled modules loaded');
} catch (error) {
console.error('[ContentScript] Failed to load modules:', error);
}
}
/**
* Load a single module
*/
async function loadModule(moduleName, config, apiKeys) {
if (moduleInstances.has(moduleName)) {
console.log(`[ContentScript] Module ${moduleName} already loaded`);
return;
}
const metadata = MODULE_METADATA[moduleName];
if (!metadata) {
console.error(`[ContentScript] Unknown module: ${moduleName}`);
return;
}
console.log(`[ContentScript] Loading module: ${moduleName}`);
try {
// Inject module script into page context
const script = document.createElement('script');
script.src = chrome.runtime.getURL(`content/modules/${metadata.filename}`);
script.onload = () => {
console.log(`[ContentScript] Module script loaded: ${moduleName}`);
// Initialize module in page context via postMessage
window.postMessage({
type: 'INIT_MODULE',
moduleName,
className: metadata.className,
instanceKey: metadata.instanceKey,
config: {
...config,
apiKey: apiKeys?.[config.apiService] || config.apiKey
}
}, '*');
};
script.onerror = (error) => {
console.error(`[ContentScript] Failed to load module script: ${moduleName}`, error);
};
// Inject before any page scripts
(document.head || document.documentElement).appendChild(script);
moduleInstances.set(moduleName, { metadata, script });
} catch (error) {
console.error(`[ContentScript] Error loading module ${moduleName}:`, error);
}
}
/**
* Unload a module
*/
function unloadModule(moduleName) {
const instance = moduleInstances.get(moduleName);
if (!instance) {
console.log(`[ContentScript] Module ${moduleName} not loaded`);
return;
}
console.log(`[ContentScript] Unloading module: ${moduleName}`);
// Send destroy message to page context
window.postMessage({
type: 'DESTROY_MODULE',
moduleName,
instanceKey: instance.metadata.instanceKey
}, '*');
// Remove script element
if (instance.script && instance.script.parentNode) {
instance.script.parentNode.removeChild(instance.script);
}
moduleInstances.delete(moduleName);
}
/**
* Handle configuration changes
*/
async function handleConfigChange(changes) {
// Reload config from storage
const config = await chrome.storage.sync.get(['modules', 'globalSettings', 'apiKeys']);
// Handle master switch
if (changes.globalSettings) {
if (!config.globalSettings.masterEnabled) {
// Master disabled - unload all modules
console.log('[ContentScript] Master switch disabled, unloading all modules');
for (const moduleName of moduleInstances.keys()) {
unloadModule(moduleName);
}
return;
}
}
// Handle individual module changes
if (changes.modules) {
for (const [moduleName, moduleConfig] of Object.entries(config.modules || {})) {
const wasEnabled = moduleInstances.has(moduleName);
const shouldBeEnabled = moduleConfig.enabled && config.globalSettings?.masterEnabled;
if (shouldBeEnabled && !wasEnabled) {
// Load module
await loadModule(moduleName, moduleConfig.config, config.apiKeys);
} else if (!shouldBeEnabled && wasEnabled) {
// Unload module
unloadModule(moduleName);
} else if (shouldBeEnabled && wasEnabled) {
// Module config changed - reload
unloadModule(moduleName);
await loadModule(moduleName, moduleConfig.config, config.apiKeys);
}
}
}
}
console.log('[ContentScript] Initialized');