您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
此脚本受版权保护,禁止未经授权的修改和分发,否则负法律责任
当前为
// ==UserScript== // @name 阿西吧抢 // @namespace http://tampermonkey.net/ // @version 0.6 // @description 此脚本受版权保护,禁止未经授权的修改和分发,否则负法律责任 // @author 晓星翼翼 // @license All Rights Reserved // @copyright 2024, 晓星翼翼 // @match https://docs.qq.com/form/* // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function() { 'use strict'; let myInfo = { name: GM_getValue('userInfo_name', ''), class: GM_getValue('userInfo_class', ''), number: GM_getValue('userInfo_number', '') }; const hashedKey = '413c05ba9f2feb8109e371acd4dc0f257d150376a8fd6dba427cfc15ad56636c'; const keyExpiration = 4320 * 60 * 60 * 1000; let hasFilledForm = false; let autoSubmitEnabled = GM_getValue('autoSubmitEnabled', false); let autoFillEnabled = GM_getValue('autoFillEnabled', true); let keyVerified = false; let lastVerificationTime = GM_getValue('lastVerificationTime', 0); let userInfoSet = GM_getValue('userInfoSet', false); function sha256(message) { const encoder = new TextEncoder(); const data = encoder.encode(message); return crypto.subtle.digest('SHA-256', data) .then(hash => { return Array.from(new Uint8Array(hash)) .map(b => b.toString(16).padStart(2, '0')) .join(''); }); } function checkKeyValidity() { const now = Date.now(); if (lastVerificationTime && (now - lastVerificationTime < keyExpiration)) { keyVerified = true; return true; } return false; } function checkUserInfo() { return userInfoSet && myInfo.name && myInfo.class && myInfo.number; } function createInfoDialog(isFirstTime = false) { const existingDialog = document.getElementById('userInfoDialog'); if (existingDialog) { existingDialog.remove(); } const dialog = document.createElement('div'); dialog.id = 'userInfoDialog'; dialog.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; border: 1px solid #ccc; padding: 20px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.3); z-index: 10000; width: 350px; font-family: Arial, sans-serif; `; dialog.innerHTML = ` <h3 style="margin-top: 0; color: #333;">${isFirstTime ? '首次设置个人信息' : '修改个人信息'}</h3> <p style="color: #666; font-size: 14px;">请输入您的个人信息,这些信息将用于自动填写表单</p> <div style="margin: 15px 0;"> <label style="display: block; margin-bottom: 5px; color: #333; font-size: 14px;">姓名:</label> <input type="text" id="nameInput" value="${myInfo.name}" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box;"> </div> <div style="margin: 15px 0;"> <label style="display: block; margin-bottom: 5px; color: #333; font-size: 14px;">班级:</label> <input type="text" id="classInput" value="${myInfo.class}" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box;"> </div> <div style="margin: 15px 0;"> <label style="display: block; margin-bottom: 5px; color: #333; font-size: 14px;">学号:</label> <input type="text" id="numberInput" value="${myInfo.number}" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box;"> </div> <div style="text-align: right; margin-top: 20px;"> ${!isFirstTime ? '<button id="cancelInfoButton" style="background: #f5f5f5; border: 1px solid #ddd; padding: 8px 16px; margin-right: 10px; border-radius: 3px; cursor: pointer;">取消</button>' : ''} <button id="saveInfoButton" style="background: #4285f4; color: white; border: none; padding: 8px 16px; border-radius: 3px; cursor: pointer;">保存</button> </div> <p id="infoError" style="color: red; font-size: 12px; margin-top: 10px; display: none;">请填写完整的信息</p> `; document.body.appendChild(dialog); const overlay = document.createElement('div'); overlay.id = 'infoDialogOverlay'; overlay.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); z-index: 9999; `; document.body.appendChild(overlay); if (!isFirstTime) { document.getElementById('cancelInfoButton').addEventListener('click', () => { dialog.remove(); overlay.remove(); }); } document.getElementById('saveInfoButton').addEventListener('click', () => saveUserInfo(isFirstTime)); [document.getElementById('nameInput'), document.getElementById('classInput'), document.getElementById('numberInput')].forEach(input => { input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { saveUserInfo(isFirstTime); } }); }); setTimeout(() => { document.getElementById('nameInput').focus(); }, 100); } function saveUserInfo(isFirstTime = false) { const nameInput = document.getElementById('nameInput'); const classInput = document.getElementById('classInput'); const numberInput = document.getElementById('numberInput'); const errorMsg = document.getElementById('infoError'); const name = nameInput.value.trim(); const className = classInput.value.trim(); const number = numberInput.value.trim(); // 验证必填字段 if (!name || !className || !number) { errorMsg.style.display = 'block'; return; } // 保存信息 myInfo = { name, class: className, number }; GM_setValue('userInfo_name', name); GM_setValue('userInfo_class', className); GM_setValue('userInfo_number', number); GM_setValue('userInfoSet', true); userInfoSet = true; // 关闭对话框 document.getElementById('userInfoDialog').remove(); const overlay = document.getElementById('infoDialogOverlay'); if (overlay) overlay.remove(); // 显示成功消息 updateStatus(`个人信息已保存:${name} - ${className} - ${number}`, true); // 如果是首次设置,继续初始化流程 if (isFirstTime) { setTimeout(() => { if (checkKeyValidity()) { init(); addControlButtons(); } else { createKeyDialog(); } }, 1000); } else { // 重置填写状态,允许重新填写 hasFilledForm = false; } } function createKeyDialog() { const existingDialog = document.getElementById('keyVerificationDialog'); if (existingDialog) { existingDialog.remove(); } const dialog = document.createElement('div'); dialog.id = 'keyVerificationDialog'; dialog.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; border: 1px solid #ccc; padding: 20px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.3); z-index: 10000; width: 300px; font-family: Arial, sans-serif; `; dialog.innerHTML = ` <h3 style="margin-top: 0; color: #333;">请输入密钥</h3> <p style="color: #666; font-size: 14px;">请输入正确的密钥以使用此脚本功能</p> <input type="password" id="keyInput" style="width: 100%; padding: 8px; margin: 10px 0; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box;"> <div style="text-align: right;"> <button id="cancelKeyButton" style="background: #f5f5f5; border: 1px solid #ddd; padding: 5px 10px; margin-right: 10px; border-radius: 3px; cursor: pointer;">取消</button> <button id="submitKeyButton" style="background: #4285f4; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer;">确认</button> </div> <p id="keyError" style="color: red; font-size: 12px; margin-top: 10px; display: none;">密钥错误,请重试</p> `; document.body.appendChild(dialog); // 添加背景遮罩 const overlay = document.createElement('div'); overlay.id = 'keyDialogOverlay'; overlay.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); z-index: 9999; `; document.body.appendChild(overlay); document.getElementById('cancelKeyButton').addEventListener('click', () => { dialog.remove(); overlay.remove(); }); document.getElementById('submitKeyButton').addEventListener('click', verifyKey); document.getElementById('keyInput').addEventListener('keypress', (e) => { if (e.key === 'Enter') { verifyKey(); } }); setTimeout(() => { document.getElementById('keyInput').focus(); }, 100); } function verifyKey() { const keyInput = document.getElementById('keyInput'); const errorMsg = document.getElementById('keyError'); sha256(keyInput.value).then(inputHash => { if (inputHash === hashedKey) { keyVerified = true; lastVerificationTime = Date.now(); GM_setValue('lastVerificationTime', lastVerificationTime); document.getElementById('keyVerificationDialog').remove(); document.getElementById('keyDialogOverlay').remove(); init(); addControlButtons(); updateStatus('密钥验证成功!', true); } else { errorMsg.style.display = 'block'; keyInput.value = ''; keyInput.focus(); } }).catch(error => { console.error('哈希计算错误:', error); errorMsg.textContent = '验证过程中出错,请重试'; errorMsg.style.display = 'block'; }); } function createFloatingWindow() { const floatingWindow = document.createElement('div'); floatingWindow.id = 'autoFillStatus'; floatingWindow.style.cssText = ` position: fixed; top: 135px; right: 250px; background-color: rgba(0, 0, 0, 0.8); color: white; padding: 10px; border-radius: 5px; z-index: 9999; font-size: 14px; min-width: 200px; box-shadow: 0 2px 10px rgba(0,0,0,0.2); opacity: 0.3; transition: opacity 0.3s; `; document.body.appendChild(floatingWindow); floatingWindow.onmouseenter = () => { floatingWindow.style.opacity = '1'; }; floatingWindow.onmouseleave = () => { floatingWindow.style.opacity = '0.3'; }; return floatingWindow; } function updateStatus(message, success = true) { const statusDiv = document.getElementById('autoFillStatus') || createFloatingWindow(); statusDiv.innerHTML = ` <div style="margin-bottom: 5px;">自动填写状态:</div> <div style="color: ${success ? '#4CAF50' : '#FF5252'}">${message}</div> <div style="font-size: 12px; margin-top: 5px; color: #ccc;">当前信息: ${myInfo.name} - ${myInfo.class}</div> `; } function findInputsByText() { const allInputs = Array.from(document.querySelectorAll('.form-simple-main textarea')); const result = { nameInput: null, classInput: null, numberInput: null }; allInputs.forEach(textarea => { let questionText = ''; let currentElement = textarea; while (currentElement && !questionText) { const prevElement = currentElement.previousElementSibling; if (prevElement) { questionText = prevElement.textContent.trim(); } currentElement = currentElement.parentElement; } if (questionText.includes('01') || questionText.includes('姓名')) { result.nameInput = textarea; } if (questionText.includes('02') || questionText.includes('班级')) { result.classInput = textarea; } if (questionText.includes('03') || questionText.includes('学号')) { result.numberInput = textarea; } }); return result; } function simulateUserInput(element, value) { element.focus(); element.value = ''; element.dispatchEvent(new Event('input', { bubbles: true })); element.value = value; element.dispatchEvent(new InputEvent('input', { bubbles: true, cancelable: true, inputType: 'insertText', data: value })); element.dispatchEvent(new Event('change', { bubbles: true })); element.blur(); element.dispatchEvent(new Event('focusout', { bubbles: true })); element.dispatchEvent(new Event('keyup', { bubbles: true })); element.dispatchEvent(new Event('keydown', { bubbles: true })); } function autoSubmit() { const submitButton = document.querySelector('button[type="button"]'); if (submitButton) { submitButton.click(); setTimeout(() => { const confirmButton = document.querySelector('.dui-modal-footer-ok'); if (confirmButton) { confirmButton.click(); updateStatus('表单已自动提交!'); } else { updateStatus('未找到确认按钮', false); } }, 50); } else { updateStatus('未找到提交按钮', false); } } function fillForm() { if (hasFilledForm) { return; } const inputs = findInputsByText(); let availableFields = 0;// 计算实际可用的输入框数量 let filledCount = 0; if (inputs.nameInput) availableFields++; if (inputs.classInput) availableFields++; if (inputs.numberInput) availableFields++; if (availableFields === 0) { updateStatus('未找到任何输入框', false); return; } function checkAndSubmit() { if (filledCount === availableFields) { // 使用实际的字段数量进行比较 updateStatus('所有可用字段填写完成!'); hasFilledForm = true; if (autoSubmitEnabled) { setTimeout(autoSubmit, 50); } } } if (inputs.nameInput) { setTimeout(() => { simulateUserInput(inputs.nameInput, myInfo.name); filledCount++; checkAndSubmit(); }, 10); } if (inputs.classInput) { setTimeout(() => { simulateUserInput(inputs.classInput, myInfo.class); filledCount++; checkAndSubmit(); }, 10); } if (inputs.numberInput) { setTimeout(() => { simulateUserInput(inputs.numberInput, myInfo.number); filledCount++; checkAndSubmit(); }, 10); } if (availableFields === 0) { updateStatus('未找到任何匹配的输入框', false); } } function addControlButtons() { const buttonContainer = document.createElement('div'); buttonContainer.id = 'controlButtonsContainer'; buttonContainer.style.cssText = ` position: fixed; top: 200px; right: 300px; display: flex; flex-direction: column; gap: 10px; z-index: 9999; `; const fillButton = document.createElement('button'); fillButton.innerHTML = `填写模式: ${autoFillEnabled ? '自动' : '手动'}`; fillButton.style.cssText = ` padding: 5px 10px; background-color: ${autoFillEnabled ? '#FFA500' : '#2196F3'}; color: white; border: none; border-radius: 3px; cursor: pointer; opacity: 0.3; transition: opacity 0.3s; `; const submitToggle = document.createElement('button'); submitToggle.innerHTML = `自动提交: ${autoSubmitEnabled ? '开启' : '关闭'}`; submitToggle.style.cssText = ` padding: 5px 10px; background-color: ${autoSubmitEnabled ? '#4CAF50' : '#FF5252'}; color: white; border: none; border-radius: 3px; cursor: pointer; opacity: 0.3; transition: opacity 0.30s; `; const submitNowButton = document.createElement('button'); submitNowButton.innerHTML = '立即提交'; submitNowButton.style.cssText = ` padding: 5px 10px; background-color: #2196F3; color: white; border: none; border-radius: 3px; cursor: pointer; opacity: 0.3; transition: opacity 0.30s; `; const editInfoButton = document.createElement('button'); editInfoButton.innerHTML = '修改信息'; editInfoButton.style.cssText = ` padding: 5px 10px; background-color: #9C27B0; color: white; border: none; border-radius: 3px; cursor: pointer; opacity: 0.3; transition: opacity 0.30s; `; const resetKeyButton = document.createElement('button'); resetKeyButton.innerHTML = '重置密钥'; resetKeyButton.style.cssText = ` padding: 5px 10px; background-color: #FF9800; color: white; border: none; border-radius: 3px; cursor: pointer; opacity: 0.3; transition: opacity 0.30s; `; // 悬浮窗效果 [fillButton, submitToggle, submitNowButton, editInfoButton, resetKeyButton].forEach(button => { button.onmouseenter = () => { button.style.opacity = '1'; }; button.onmouseleave = () => { button.style.opacity = '0.3'; }; }); // 模式切换 fillButton.onclick = () => { autoFillEnabled = !autoFillEnabled; GM_setValue('autoFillEnabled', autoFillEnabled); // 使用 GM_setValue 保存设置 fillButton.innerHTML = `填写模式: ${autoFillEnabled ? '自动' : '手动'}`; fillButton.style.backgroundColor = autoFillEnabled ? '#FFA500' : '#2196F3'; updateStatus(`当前模式: ${autoFillEnabled ? '自动填写' : '手动填写'}`); // 自动模式切换后立马执行 if (autoFillEnabled && !hasFilledForm) { fillForm(); } }; submitToggle.onclick = () => { autoSubmitEnabled = !autoSubmitEnabled; GM_setValue('autoSubmitEnabled', autoSubmitEnabled);// 使用 GM_setValue 保存设置 submitToggle.innerHTML = `自动提交: ${autoSubmitEnabled ? '开启' : '关闭'}`; submitToggle.style.backgroundColor = autoSubmitEnabled ? '#4CAF50' : '#FF5252'; if (autoSubmitEnabled && hasFilledForm) { autoSubmit(); } }; submitNowButton.onclick = () => { autoSubmit(); }; editInfoButton.onclick = () => { createInfoDialog(false); }; resetKeyButton.onclick = () => { // 重置密钥验证状态 keyVerified = false; GM_setValue('lastVerificationTime', 0); // 移除控制按钮 document.getElementById('controlButtonsContainer').remove(); // 重新显示密钥验证对话框 createKeyDialog(); updateStatus('已重置密钥验证状态,请重新验证', false); }; buttonContainer.appendChild(fillButton); buttonContainer.appendChild(submitToggle); buttonContainer.appendChild(submitNowButton); buttonContainer.appendChild(editInfoButton); buttonContainer.appendChild(resetKeyButton); document.body.appendChild(buttonContainer); } function init() { if (!document.getElementById('autoFillStatus')) { createFloatingWindow(); } if (document.readyState === 'complete') { updateStatus('正在查找表单...'); if (autoFillEnabled) { fillForm(); } else { updateStatus('当前为手动填写模式'); } } else { updateStatus('等待页面加载...', false); setTimeout(init, 10); } } // 主入口 setTimeout(() => { // 首先检查是否已设置个人信息 if (!checkUserInfo()) { createFloatingWindow(); updateStatus('首次使用,请设置个人信息', false); createInfoDialog(true); return; } // 检查是否已验证过密钥且在有效期内 if (checkKeyValidity()) { init(); addControlButtons(); updateStatus('密钥已验证,脚本已启动', true); } else { createFloatingWindow(); updateStatus('请输入密钥验证', false); createKeyDialog(); } }, 100); // 额外检查 setTimeout(() => { if (keyVerified && !hasFilledForm && document.getElementById('autoFillStatus')) { init(); } }, 200); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址