您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
send a POST request based on the fetch text in the input box
// ==UserScript== // @name Webwork Autofill // @namespace http://tampermonkey.net/ // @version 0.1 // @description send a POST request based on the fetch text in the input box // @author You // @match webwork.math.ust.hk/* // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== (function () { 'use strict'; var dodebug = false; var Advanced_Recursion = false; // Create the input box var inputBox = document.createElement('textarea'); inputBox.id = 'fetchText'; inputBox.rows = 1; inputBox.cols = 200; var inputBoxMin = document.createElement('textarea'); inputBoxMin.id = 'boxMin'; inputBoxMin.rows = 1; inputBoxMin.cols = 4; inputBoxMin.textContent = '-7'; var inputBoxMax = document.createElement('textarea'); inputBoxMax.id = 'boxMax'; inputBoxMax.rows = 1; inputBoxMax.cols = 4; inputBoxMax.textContent = '7'; var inputInterval = document.createElement('textarea'); inputInterval.id = 'boxInterval'; inputInterval.rows = 1; inputInterval.cols = 4; inputInterval.textContent = '50'; var CorrectAns = document.createElement('div'); CorrectAns.id = 'CorrectAns'; CorrectAns.style.border = '1px solid black'; CorrectAns.textContent = 'Correct Answers: '; CorrectAns.onclick = function() { resultList = {}; CorrectAns.textContent = 'Correct Answers: '; localStorage.setItem('resultList',JSON.stringify(resultList)); }; // Create the button var button = document.createElement('button'); button.textContent = 'Send POST request'; button.onclick = function () { // Get the fetch text from the input box var fetchText = document.getElementById('fetchText').value; executeFetchCommand(fetchText); }; // Add the input box and the button after the specified element var element = document.getElementById('problem-nav'); element.parentNode.insertBefore(inputBox, element.nextSibling); element.parentNode.insertBefore(button, inputBox.nextSibling); element.parentNode.insertBefore(inputBoxMin, button.nextSibling); element.parentNode.insertBefore(inputBoxMax, inputBoxMin.nextSibling); element.parentNode.insertBefore(inputInterval, inputBoxMax.nextSibling); element.parentNode.insertBefore(CorrectAns, inputInterval.nextSibling); var resultList = {}; var localItems = ['fetchText', 'boxMin', 'boxMax', 'boxInterval']; function getLocalItem(localItems){ localItems.forEach(function (item){ if (localStorage.getItem(item) !== null) { document.getElementById(item).value = localStorage.getItem(item); } }) if (localStorage.getItem('resultList') !== null){ resultList = JSON.parse(localStorage.getItem('resultList')); CorrectAns.textContent = 'Correct Answers: '+JSON.stringify(resultList); } } getLocalItem(localItems); function debugoutput(text){ if (dodebug){ console.log(text); } } var executed = 0; var submitted = 0; function executeFetchCommand(fetchCommand) { // Remove semicolon from the end of the command fetchCommand = fetchCommand.trim(); if (fetchCommand.endsWith(';')) { fetchCommand = fetchCommand.slice(0, -1); } // Get all answer input boxes var answerInputs = document.querySelectorAll('input.codeshard'); var answerIds = []; answerInputs.forEach(function(input) { if (input.previousSibling && input.previousSibling.checked) { answerIds.push(input.id); } }); answerIds = answerIds; var min = Number(document.getElementById('boxMin').value); var max = Number(document.getElementById('boxMax').value); var interval = Number(document.getElementById('boxInterval').value); var current_empty_answers = (answerIds.length-Object.keys(resultList).length); var current_filled_answers = Object.keys(resultList).length; var max_cases = Advanced_Recursion ? (max-min+1)**current_empty_answers : (max-min+1)*current_empty_answers; console.log("current empty answers: "+current_empty_answers); var progress = document.createElement('progress'); progress.id = 'ProgressBar' progress.value = 0; progress.max = (max-min+1)**current_empty_answers; var progtxt = document.createElement('div'); progtxt.id = 'progresstext'; progtxt.style.border = '1px solid black'; progtxt.textContent = `${submitted} (submitted) / ${executed} (executed) / ${max_cases} (max)`; element.parentNode.insertBefore(progress, CorrectAns.nextSibling); element.parentNode.insertBefore(progtxt, progress.nextSibling); function replaceAnswerInFetchCommand(fetchCommand, answerId, answerValue) { //console.log("received AnsID/Ans: "+ answerId+"/"+answerValue) // Create a regular expression to find the answer in the fetch command var regex = new RegExp('(?<=name=\\\\"'+answerId+'\\\\"\\\\r\\\\n\\\\r\\\\n).*?(?=\\\\r\\\\n)', 'g'); // Replace the answer in the fetch command var newFetchCommand = fetchCommand.replace(regex, answerValue); return newFetchCommand; }; // Try all combinations of answers console.log('answerIds:'); console.log(answerIds); function recurseFor(recurseCommand, ansIndex){ debugoutput('ansIndex = ' + ansIndex); if (ansIndex>=0) { if (('Box'+(ansIndex+1)) in resultList){ var value = resultList['Box'+(ansIndex+1)]; debugoutput('skipping with '+ value + ' in Box'+ (ansIndex+1)); document.getElementById(answerIds[ansIndex]).value = value; recurseCommand = replaceAnswerInFetchCommand(recurseCommand, answerIds[ansIndex], value); recurseFor(recurseCommand, ansIndex-1); }else{ for (var i = min; i<=max; i++) { debugoutput('For Delay: ansIndex = ' + ansIndex+' Power='+Math.max(ansIndex-current_filled_answers,0)); var timeout = (max-min+1)**(Math.max(ansIndex-current_filled_answers,0))*(i-min)*interval; debugoutput('setting delay for Depth '+ (ansIndex-1) + ' with '+ timeout+'ms'); setTimeout(function (recurseCommand,ansIndex,i){ document.getElementById(answerIds[ansIndex]).value = i; recurseCommand = replaceAnswerInFetchCommand(recurseCommand, answerIds[ansIndex], i); recurseFor(recurseCommand, ansIndex-1); },timeout, recurseCommand, ansIndex, i); // to set time interval for each fetch // numBranch**(maxDepth-Depth)*Branch_i*TARGET_INTERVAL } } }else{ submitted+=1; progtxt.textContent = `${submitted} (submitted) / ${executed} (executed) / ${max_cases} (max)`; if (!dodebug){ eval(recurseCommand); } } }; var answer_list = []; answerIds.forEach(function(item,index){ answer_list[index] = max; }); debugoutput('initial answer_list: '+JSON.stringify(answer_list)); //TODOOO: ALL TOGETHER, NO SEPERATION function recurse(ansIndex, ansValue){ debugoutput(`ansIndex = ${ansIndex}, ansValue = ${ansValue}`); debugoutput(answer_list); if (ansIndex<0){ return; } else if(ansValue<min){ recurse(ansIndex-1, max); } else{ if (('Box'+(ansIndex+1)) in resultList){ ansValue = resultList['Box'+(ansIndex+1)]; answer_list[ansIndex] = ansValue; document.getElementById(answerIds[ansIndex]).value = ansValue; recurse(ansIndex-1, max); }else{ answer_list[ansIndex] = ansValue; document.getElementById(answerIds[ansIndex]).value = ansValue; //Fill to the textbox answer_list.forEach(function (item,index){ recurseCommand = replaceAnswerInFetchCommand(recurseCommand, answerIds[index], item); }); if (!dodebug){ submitted+=1; progtxt.textContent = `${submitted} (submitted) / ${executed} (executed) / ${max_cases} (max)`; eval(recurseCommand); } debugoutput(`sleep ${interval}ms for next call`); setTimeout(recurse, interval, ansIndex, ansValue-1); } } }; function AdvancedRecurse(ansIndex, ansValue){ debugoutput(`ansIndex = ${ansIndex}, ansValue = ${ansValue}`); debugoutput(`start:`+answer_list.join()); if (ansIndex<0){ return; } else if(ansValue<min){ return; } else{ /*if (('Box'+(ansIndex+1)) in resultList){ ansValue = resultList['Box'+(ansIndex+1)]; answer_list[ansIndex] = ansValue; document.getElementById(answerIds[ansIndex]).value = ansValue; AdvancedRecurse(ansIndex-1, max); }else{*/ AdvancedRecurse(ansIndex -1, ansValue); answer_list[ansIndex] = ansValue; debugoutput(`Added: `+answer_list); document.getElementById(answerIds[ansIndex]).value = ansValue; //Fill to the textbox answer_list.forEach(function (item,index){ recurseCommand = replaceAnswerInFetchCommand(recurseCommand, answerIds[index], item); }); if (!dodebug){ submitted+=1; progtxt.textContent = `${submitted} (submitted) / ${executed} (executed) / ${max_cases} (max)`; eval(recurseCommand); } debugoutput(`sleep ${interval}ms for next call`); setTimeout(AdvancedRecurse, interval, ansIndex , ansValue -1); //} } }; fetchCommand = `function fetchWithRetry(retryCount = 5) { return ` + fetchCommand + `.then(response => response.text()) .then(data => { let parser = new DOMParser(); let htmlDoc = parser.parseFromString(data, 'text/html'); let rows = htmlDoc.querySelectorAll('.attemptResults tr'); let enteredArray = []; let resultArray = []; for(let i = 1; i < rows.length; i++) { // skip the header row let entered = rows[i].children[0].textContent; let result = rows[i].children[2].textContent; if (result === 'correct') { resultList['Box'+i] = entered; CorrectAns.textContent = 'Correct Answers (click to reset) : '+JSON.stringify(resultList); localStorage.setItem('resultList',JSON.stringify(resultList)); } enteredArray.push(entered); resultArray.push(result); } console.log('Entered: ' + enteredArray.join(', ')); console.log('Result: ' + resultArray.join(', ')); executed+=1; progtxt.textContent = \`\${submitted} (submitted) / \${executed} (executed) / \${max_cases} (max)\`; progress.value = executed; }) .catch((error) => { var delay = 1000; delay+= Math.random()*2000; console.error('Unable to fetch! Retry remaining: ' + retryCount + ' in '+ delay+'ms '); if (retryCount >= 1) { return setTimeout(delay,fetchWithRetry,retryCount - 1); } }); } fetchWithRetry();`; var recurseCommand = fetchCommand; if (Advanced_Recursion) { AdvancedRecurse(answerIds.length-1, max); }else { recurse(answerIds.length-1, max); } } // Add checkboxes to all answer input boxes var answerInputs = document.querySelectorAll('input.codeshard'); answerInputs.forEach(function(input,index) { var checkbox = document.createElement('input'); checkbox.type = 'checkbox'; input.parentNode.insertBefore(checkbox, input); checkbox.checked = true; }); function setLocalItem(localItems){ localItems.forEach(function (item){ document.getElementById(item).addEventListener('change', function() { localStorage.setItem(item, this.value); }); }); document.getElementById('CorrectAns').addEventListener('change', function() { localStorage.setItem('resultList',JSON.stringify(resultList)); }); } setLocalItem(localItems); })();