您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Collect and reuse ORIOKS test answers
当前为
// ==UserScript== // @name Sorryops // @name:ru Сориупс // @namespace https://git.disroot.org/electromagneticcyclone/sorryops // @version 20240427.1 // @description Collect and reuse ORIOKS test answers // @description:ru Скрипт для сбора и переиспользования ответов на тесты ОРИОКС // @icon https://orioks.miet.ru/favicon.ico // @author electromagneticcyclone & angelbeautifull // @license Unlicense // @supportURL https://git.disroot.org/electromagneticcyclone/sorryops // @match https://orioks.miet.ru/student/student/test* // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_setClipboard // @require https://openuserjs.org/src/libs/sizzle/GM_config.js // @run-at document-start // ==/UserScript== /* Labels */ var all_labels = { en: { l: "English", settings_title: "Settings", script_language: "Language", auto_answer: "Auto answer", auto_answer_no: "No", auto_answer_first: "First", auto_answer_random: "Random", display_answer: "Display answer near variant", stop_timer: "Freeze and hide timer", register_keyboard_keys: "Register hotkeys", copy_answers: "Copy results to the clipboard", append_question_number: "Show question numbers in the final report", accumulator_enable: "Accumulate test results in one field", auto_continue: "Auto continue (DANGEROUS!!! Will be disabled after an hour. Press `d` to disable)", auto_restart: "Auto restart (DANGEROUS!!! Will be disabled after an hour. Press `d` to disable. Make sure you have infinite attempts)", }, ru: { l: "Русский", settings_title: "Настройки", script_language: "Язык", auto_answer: "Автовыбор ответа", auto_answer_no: "Нет", auto_answer_first: "Первый", auto_answer_random: "Случайный", display_answer: "Отображать ответ рядом с вариантом", stop_timer: "Заморозить и скрыть таймер", register_keyboard_keys: "Горячие клавиши", copy_answers: "Копировать результаты в буфер обмена", append_question_number: "Отображать номер вопроса в финальном отчёте", accumulator_enable: "Собирать отчёты в одно поле", auto_continue: "Автопродолжение (ОПАСНО!!! Отключается через час. Нажмите `d`, чтобы остановить)", auto_restart: "Автоперезапуск (ОПАСНО!!! Отключается через час. Нажмите `d`, чтобы остановить. Убедитесь, что количество попыток неограничено)", }, }; var labels = all_labels[(() => { var lang = GM_getValue('language', "-"); if (!lang || (lang == "-")) { lang = navigator.language || navigator.userLanguage; } for (var l in all_labels) { if (lang.includes(l)) { return l; } } })()]; if (labels == undefined) { labels = all_labels.ru; } /* End Labels */ /* Config */ var config = new GM_config({ id: 'config', title: labels.settings_title, fields: { script_language: { label: labels.script_language, type: 'select', options: [ '-', all_labels.en.l, all_labels.ru.l, ], default: '-', }, auto_answer: { label: labels.auto_answer, type: 'select', options: [ labels.auto_answer_no, labels.auto_answer_first, labels.auto_answer_random, ], default: labels.auto_answer_no, }, display_answer: { label: labels.display_answer, type: 'checkbox', default: true, }, stop_timer: { label: labels.stop_timer, type: 'checkbox', default: true, }, register_keyboard_keys: { label: labels.register_keyboard_keys, type: 'checkbox', default: true, }, copy_answers: { label: labels.copy_answers, type: 'checkbox', default: false, }, append_question_number: { label: labels.append_question_number, type: 'checkbox', default: true, }, accumulator_enable: { label: labels.accumulator_enable, type: 'checkbox', default: false, }, auto_continue: { label: labels.auto_continue, type: 'checkbox', default: false, }, auto_continue_time: { type: 'hidden', default: 0, }, auto_restart: { label: labels.auto_restart, type: 'checkbox', default: false, }, auto_restart_time: { type: 'hidden', default: 0, }, }, events: { init: function() { GM_setValue('stop_timer', this.get('stop_timer')); if (this.get('auto_continue') && (this.get('auto_answer') == "No")) { this.set('auto_continue', false); } if (this.get('accumulator_enable') == false) { GM_setValue('accumulated_answers', ""); } switch (this.get('script_language')) { case all_labels.en.l: GM_setValue('language', "en"); break; case all_labels.ru.l: GM_setValue('language', "ru"); break; default: GM_setValue('language', "-"); break; } }, save: function(forgotten) { this.set('auto_continue_time', Date.now()); this.set('auto_restart_time', Date.now()); if (this.isOpen && this.get('auto_continue') && (this.get('auto_answer') == "No")) { this.set('auto_continue', false); alert("Can't automatically continue without answer."); } this.init(); }, }, }); GM_registerMenuCommand(labels.settings_title, () => { config.open(); }); /* End Config */ /* Server */ // Local function S_setValue(field, value) { var v = GM_getValue("server", value); } // Local function S_getValue(field, default_value) { var v = GM_getValue("server", default_value); } /* End Server */ /* Stop timer */ if (GM_getValue('stop_timer', true)) { var i, pbox; var pboxes = document.getElementsByTagName('p'); for (i = 0; i < pboxes.length; i++) { pbox = pboxes[i]; if (pbox.textContent.includes("Осталось:")) { pbox.parentNode.remove(); document.getElementsByTagName('hr')[0].remove(); var injectFakeTimer = function(window) { window.setInterval = (f, t) => { return window.setInterval(f, 10^999); }; } var scriptFakeTimer = document.createElement('script'); scriptFakeTimer.setAttribute("type", "application/javascript"); scriptFakeTimer.textContent = '(' + injectFakeTimer + ')(window);'; document.body.appendChild(scriptFakeTimer); break; } } } /* End Stop timer */ /* Events */ window.addEventListener('load', main); window.onkeydown = (e) => { if ((e.key == "Enter") && config.get('register_keyboard_keys')) { press_continue_btn(); } if (e.key == "d") { config.set('auto_continue', false); config.set('auto_restart', false); config.save(); } }; /* End Events */ /* Page properties */ // const success = -1487162948; var answers = []; var variant, hash, type; var testID = (() => { var url = document.URL; url = url.slice(url.indexOf("idKM=") + 5); url = url.slice(0, url.indexOf("&")); return url; })(); /* End properties */ /* Functions */ // https://stackoverflow.com/a/15710692 function hashCode(s) { return s.split("").reduce(function(a, b) { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0); } function DB_cleaner() { var clear = GM_getValue('clear_tests', new Object()); var tests = GM_getValue('tests', new Object()); for (var test in clear) { delete tests[test]; } GM_setValue('tests', tests); GM_setValue('clear_tests', new Object()); } function press_continue_btn() { var i; var buttons = document.getElementsByTagName('button'); var button = undefined; for (i = 0; i < buttons.length; i++) { var btn = buttons[i]; if (btn.textContent.includes("Пройти") || btn.textContent.includes("Продолжить")) { button = btn; break; } } if (button === undefined) { return; } if (button.textContent.includes("Пройти")) { window.location.replace(button.parentNode.href); } else if (button.textContent.includes("Продолжить")) { button.click(); } } function calculate_variant_hash() { variant = document.getElementById('w0').parentNode.textContent; variant = variant.slice(variant.indexOf("Вопрос:")); hash = hashCode(variant); } function update_variant() { var i, pbox; var chosen_answer = ""; switch (type) { case 'checkbox': case 'radio': { for (i = 0; i < answers.length; i++) { chosen_answer += answers[i].checked ? answers[i].value : ""; } chosen_answer = chosen_answer.split('').sort().join(''); } break; case 'text': { for (i = 0; i < answers.length; i++) { chosen_answer += "[" + answers[i].value + "]"; } } } var pboxes = document.getElementsByTagName('p'); const display_answer = config.get('display_answer'); for (i = 0; i < pboxes.length; i++) { pbox = pboxes[i]; if (pbox.textContent.includes("Вопрос:")) { pbox.innerHTML = "<i>(Вариант <input onfocus='this.select();' id='variant' value='" + hash + (display_answer == true ? (" " + chosen_answer) : "") + "' readonly>)</i><br>Вопрос:"; break; } } var question_num = undefined; for (i = 0; i < pboxes.length; i++) { pbox = pboxes[i]; if (pbox.textContent.includes("Текущий вопрос: ")) { question_num = pbox.textContent.slice(variant.indexOf("Текущий вопрос: ") + 16); break; } } var tests = GM_getValue('tests', new Object()); if (tests[testID] === undefined) { tests[testID] = new Object(); } tests[testID][hash] = [question_num, chosen_answer]; GM_setValue('tests', tests); } /* End Functions */ /* Handlers */ function test_form_handler() { var i; var boxes = []; var objects = new Object(); var form = document.getElementById('testform-answer'); var manual_form = document.getElementById('testform-answer-0'); if (form != null) { boxes = form.getElementsByTagName('input'); } else if (manual_form != null) { i = 1; while (manual_form != null) { boxes.push(manual_form); manual_form = document.getElementById('testform-answer-' + i++); } console.log(boxes); } type = boxes[0].type; console.log(type); switch (type) { case 'checkbox': case 'radio': { for (i = 0; i < boxes.length; i++) { var answerHash = hashCode(boxes[i].parentNode.innerText) var span = document.createElement('span'); span.innerHTML = boxes[i].type === 'radio' && boxes[i].value == "1" ? "<b>" + boxes[i].value + ")</b> " : boxes[i].value + ") "; boxes[i].parentNode.insertBefore(span, boxes[i]); objects[boxes[i].value] = boxes[i]; } const sorted_objects = Object.keys(objects).sort().reduce( (obj, key) => { obj[key] = objects[key]; return obj; }, {} ); for (var key in sorted_objects) { sorted_objects[key].parentNode.remove(); form.appendChild(sorted_objects[key].parentNode); answers.push(sorted_objects[key]); } calculate_variant_hash(); var correct_answer = S_getValue(testID + "." + hash + ".correct", undefined); var incorrect_answers = S_getValue(testID + "." + hash + ".incorrect", undefined); const auto_answer = config.get('auto_answer'); if (auto_answer == labels.auto_answer_random) { if (answers[0].type === 'radio') { var chosen_answer = Math.floor(Math.random() * answers.length); answers[chosen_answer].click(); } else { var pick = Math.floor(Math.random() * (Math.pow(2, answers.length) - 1)) + 1; for (i = 0; i < answers.length; i++) { if(pick & Math.pow(2, i)) { answers[i].click(); } } } } else if (auto_answer == labels.auto_answer_first) { answers[0].click(); } } break; case 'text': { answers = boxes; calculate_variant_hash(); } break; } update_variant(); for (i = 0; i < answers.length; i++) { answers[i].addEventListener('change', update_variant); } } function result_page_handler() { var i; var correct = variant.slice(variant.indexOf("Число верных ответов: ") + 22); correct = correct.slice(0, correct.indexOf("\n")); var test = GM_getValue('tests', new Object())[testID]; if (test === undefined) { return; } var printer = ""; var sorted_test = []; for (var hash in test) { sorted_test.push([hash].concat(test[hash])); } sorted_test.sort((a, b) => {return a[1] - b[1]}); console.log(sorted_test); for (i = 0; i < sorted_test.length; i++) { printer += (config.get('append_question_number') ? (sorted_test[i][1] + ") ") : "") + sorted_test[i][0] + " " + sorted_test[i][2] + "\n"; } printer += correct; if (config.get('copy_answers')) { GM_setClipboard(printer); } if (config.get('accumulator_enable')) { var acc = GM_getValue('accumulated_answers', ""); if (acc != "") { acc += "\n\n"; } var prefix = testID; if (prefix != "") { acc += prefix + "\n"; } acc += printer; GM_setValue('accumulated_answers', acc); printer = acc; } printer = "<textarea readonly style='resize:none; width:fit-content; height:fit-content' rows='" + String(Object.keys(test).length + 1) + "' cols='50' onfocus='this.select();' id='answers'>" + printer + "</textarea>"; var pboxes = document.getElementsByTagName('p'); for (i = 0; i < pboxes.length; i++) { var pbox = pboxes[i]; if (pbox.textContent.includes("Попытка ")) { pbox.outerHTML += printer; break; } } var clear = GM_getValue('clear_tests', new Object()); clear[testID] = true; GM_setValue('clear_tests', clear); } /* End Handlers */ function main() { var old_time, cur_time; variant = document.getElementById('w0').parentNode.textContent; if (variant.includes("Вопрос:")) { DB_cleaner(); test_form_handler(); if (config.get('auto_continue')) { old_time = config.get('auto_continue_time'); cur_time = Date.now(); if (cur_time - old_time > 60 * 60 * 1000) { config.set('auto_continue', false); } else { press_continue_btn(); } } } else if (variant.includes("Результат прохождения теста:")) { result_page_handler(); if (config.get('auto_restart')) { old_time = config.get('auto_restart_time'); cur_time = Date.now(); if (cur_time - old_time > 60 * 60 * 1000) { config.set('auto_restart', false); } else { press_continue_btn(); } } } }