Timer freezing; Text test form support
This commit is contained in:
parent
ef1275e408
commit
f4323c16b3
1 changed files with 274 additions and 156 deletions
430
user.js
430
user.js
|
@ -2,7 +2,7 @@
|
|||
// @name Sorryops
|
||||
// @name:ru Сориупс
|
||||
// @namespace https://git.disroot.org/electromagneticcyclone/sorryops
|
||||
// @version 20240424.2
|
||||
// @version 20240427.1
|
||||
// @description Collect and reuse ORIOKS test answers
|
||||
// @description:ru Скрипт для сбора и переиспользования ответов на тесты ОРИОКС
|
||||
// @icon https://orioks.miet.ru/favicon.ico
|
||||
|
@ -21,18 +21,23 @@
|
|||
// @updateURL https://update.greasyfork.org/scripts/481036/Sorryops.meta.js
|
||||
// ==/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",
|
||||
accumulator_prefix: "Accumulated results prefix (test number)",
|
||||
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)",
|
||||
},
|
||||
|
@ -40,13 +45,16 @@ var all_labels = {
|
|||
l: "Русский",
|
||||
settings_title: "Настройки",
|
||||
script_language: "Язык",
|
||||
auto_answer: "Автоответчик",
|
||||
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: "Собирать отчёты в одно поле",
|
||||
accumulator_prefix: "Префикс перенесённого отчёта (номер теста)",
|
||||
auto_continue: "Автопродолжение (ОПАСНО!!! Отключается через час. Нажмите `d`, чтобы остановить)",
|
||||
auto_restart: "Автоперезапуск (ОПАСНО!!! Отключается через час. Нажмите `d`, чтобы остановить. Убедитесь, что количество попыток неограничено)",
|
||||
},
|
||||
|
@ -67,6 +75,10 @@ if (labels == undefined) {
|
|||
labels = all_labels.ru;
|
||||
}
|
||||
|
||||
/* End Labels */
|
||||
|
||||
/* Config */
|
||||
|
||||
var config = new GM_config({
|
||||
id: 'config',
|
||||
title: labels.settings_title,
|
||||
|
@ -74,20 +86,33 @@ var config = new GM_config({
|
|||
script_language: {
|
||||
label: labels.script_language,
|
||||
type: 'select',
|
||||
options: [ '-', all_labels.en.l, all_labels.ru.l ],
|
||||
options: [
|
||||
'-',
|
||||
all_labels.en.l,
|
||||
all_labels.ru.l,
|
||||
],
|
||||
default: '-',
|
||||
},
|
||||
auto_answer: {
|
||||
label: labels.auto_answer,
|
||||
type: 'select',
|
||||
options: [ 'No', 'First', 'Random' ],
|
||||
default: 'No',
|
||||
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',
|
||||
|
@ -108,11 +133,6 @@ var config = new GM_config({
|
|||
type: 'checkbox',
|
||||
default: false,
|
||||
},
|
||||
accumulator_prefix: {
|
||||
label: labels.accumulator_prefix,
|
||||
type: 'text',
|
||||
default: "",
|
||||
},
|
||||
auto_continue: {
|
||||
label: labels.auto_continue,
|
||||
type: 'checkbox',
|
||||
|
@ -134,6 +154,7 @@ var config = new GM_config({
|
|||
},
|
||||
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);
|
||||
}
|
||||
|
@ -164,20 +185,55 @@ var config = new GM_config({
|
|||
},
|
||||
});
|
||||
|
||||
var answers = [];
|
||||
var variant, hash;
|
||||
var testID = (() => {
|
||||
var url = document.URL;
|
||||
url = url.slice(url.indexOf("idKM=") + 5);
|
||||
url = url.slice(0, url.indexOf("&"));
|
||||
return url;
|
||||
})();
|
||||
|
||||
GM_registerMenuCommand('Script Settings', () => {
|
||||
GM_registerMenuCommand(labels.settings_title, () => {
|
||||
config.open();
|
||||
});
|
||||
|
||||
window.addEventListener('load', actionFunction);
|
||||
/* 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();
|
||||
|
@ -189,6 +245,24 @@ window.onkeydown = (e) => {
|
|||
}
|
||||
};
|
||||
|
||||
/* 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) {
|
||||
|
@ -197,138 +271,6 @@ function hashCode(s) {
|
|||
}, 0);
|
||||
}
|
||||
|
||||
function update_variant() {
|
||||
var i, pbox;
|
||||
var chosen_answer = "";
|
||||
for (i = 0; i < answers.length; i++) {
|
||||
chosen_answer += answers[i].checked ? answers[i].value : "";
|
||||
}
|
||||
chosen_answer = chosen_answer.split('').sort().join('');
|
||||
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);
|
||||
}
|
||||
|
||||
function test_form_handler() {
|
||||
var i;
|
||||
var objects = new Object();
|
||||
var boxes = document.getElementsByTagName('input');
|
||||
var form = document.getElementById('testform-answer');
|
||||
for (i = 0; i < boxes.length; i++) {
|
||||
if (boxes[i].type === 'checkbox' | boxes[i].type === 'radio') {
|
||||
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]);
|
||||
}
|
||||
const auto_answer = config.get('auto_answer');
|
||||
var answer;
|
||||
if (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 == 'First') {
|
||||
answers[0].click();
|
||||
}
|
||||
variant = document.getElementById('w0').parentNode.textContent;
|
||||
variant = variant.slice(variant.indexOf("Вопрос:"));
|
||||
hash = hashCode(variant);
|
||||
update_variant();
|
||||
form.addEventListener('click', 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 = config.get('accumulator_prefix');
|
||||
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);
|
||||
}
|
||||
|
||||
function DB_cleaner() {
|
||||
var clear = GM_getValue('clear_tests', new Object());
|
||||
var tests = GM_getValue('tests', new Object());
|
||||
|
@ -360,7 +302,183 @@ function press_continue_btn() {
|
|||
}
|
||||
}
|
||||
|
||||
function actionFunction() {
|
||||
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("Вопрос:")) {
|
||||
|
|
Loading…
Reference in a new issue