2023-11-29 16:30:05 +01:00
|
|
|
|
// ==UserScript==
|
2024-04-24 19:31:14 +02:00
|
|
|
|
// @name Sorryops
|
|
|
|
|
// @name:ru Сориупс
|
|
|
|
|
// @namespace https://git.disroot.org/electromagneticcyclone/sorryops
|
2024-05-03 20:19:09 +02:00
|
|
|
|
// @version 20240503.2
|
2024-04-24 19:31:14 +02:00
|
|
|
|
// @description Collect and reuse ORIOKS test answers
|
|
|
|
|
// @description:ru Скрипт для сбора и переиспользования ответов на тесты ОРИОКС
|
2024-05-03 19:44:14 +02:00
|
|
|
|
// @icon https://sorryops.ru/favicon.ico
|
2024-04-24 19:31:14 +02:00
|
|
|
|
// @author electromagneticcyclone & angelbeautifull
|
2024-04-29 07:30:45 +02:00
|
|
|
|
// @license GPL-3.0-or-later
|
2024-04-24 19:31:14 +02:00
|
|
|
|
// @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
|
2024-04-29 07:30:45 +02:00
|
|
|
|
// @grant GM_xmlhttpRequest
|
2024-04-30 17:08:00 +02:00
|
|
|
|
// @grant GM_openInTab
|
2024-04-24 19:31:14 +02:00
|
|
|
|
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js
|
2024-04-29 07:30:45 +02:00
|
|
|
|
// @connect sorryops.ru
|
2024-04-24 19:31:14 +02:00
|
|
|
|
// @run-at document-start
|
2024-05-03 20:19:09 +02:00
|
|
|
|
// @downloadURL https://update.greasyfork.org/scripts/481036/Sorryops.user.js
|
|
|
|
|
// @updateURL https://update.greasyfork.org/scripts/481036/Sorryops.meta.js
|
2023-11-29 16:30:05 +01:00
|
|
|
|
// ==/UserScript==
|
|
|
|
|
|
2024-04-30 17:08:00 +02:00
|
|
|
|
/* Version */
|
2024-05-03 20:19:09 +02:00
|
|
|
|
const VERSION = "20240503.2";
|
2024-04-30 17:08:00 +02:00
|
|
|
|
/* End Version */
|
|
|
|
|
|
2024-04-29 07:30:45 +02:00
|
|
|
|
/* Charset */
|
|
|
|
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
|
|
|
/* End Charset */
|
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
/* Labels */
|
|
|
|
|
|
2024-04-29 07:30:45 +02:00
|
|
|
|
const all_labels = {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
en: {
|
|
|
|
|
l: "English",
|
|
|
|
|
settings_title: "Settings",
|
|
|
|
|
script_language: "Language",
|
2024-04-29 07:30:45 +02:00
|
|
|
|
show_user_id: "Show user ID",
|
|
|
|
|
user_id: "User ID (keep private)",
|
|
|
|
|
server: "Sync answers with server (leave blank to disable)",
|
2024-05-01 11:23:23 +02:00
|
|
|
|
wait_server_response: "Wait server response",
|
2024-04-24 19:23:20 +02:00
|
|
|
|
auto_answer: "Auto answer",
|
2024-04-27 11:38:11 +02:00
|
|
|
|
auto_answer_no: "No",
|
|
|
|
|
auto_answer_first: "First",
|
|
|
|
|
auto_answer_random: "Random",
|
2024-05-02 14:05:31 +02:00
|
|
|
|
auto_answer_not_greedy: "Choose a known answer if there are more wrong answers than that number",
|
2024-05-02 22:09:40 +02:00
|
|
|
|
auto_answer_greed_level: "Number of randomly answered questions",
|
2024-04-29 07:30:45 +02:00
|
|
|
|
display_values: "Answers variant",
|
|
|
|
|
display_values_ori: "ORIOKS",
|
|
|
|
|
display_values_sorry: "Sorry",
|
|
|
|
|
display_values_both: "Both",
|
2024-04-24 19:23:20 +02:00
|
|
|
|
display_answer: "Display answer near variant",
|
2024-04-27 11:38:11 +02:00
|
|
|
|
stop_timer: "Freeze and hide timer",
|
2024-04-24 19:23:20 +02:00
|
|
|
|
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: "Язык",
|
2024-04-29 07:30:45 +02:00
|
|
|
|
show_user_id: "Показать индетификатор пользователя",
|
|
|
|
|
user_id: "Индетификатор (держать в секрете)",
|
|
|
|
|
server: "Синхронизировать ответы с сервером (оставить пустым для отключения)",
|
2024-05-01 11:23:23 +02:00
|
|
|
|
wait_server_response: "Ждать ответа сервера",
|
2024-04-27 11:38:11 +02:00
|
|
|
|
auto_answer: "Автовыбор ответа",
|
|
|
|
|
auto_answer_no: "Нет",
|
|
|
|
|
auto_answer_first: "Первый",
|
|
|
|
|
auto_answer_random: "Случайный",
|
2024-05-02 14:05:31 +02:00
|
|
|
|
auto_answer_not_greedy: "Выбирать известный ответ, если неправильных больше этого числа",
|
2024-05-02 22:09:40 +02:00
|
|
|
|
auto_answer_greed_level: "Количество вопросов, на которые будет случайный ответ",
|
2024-04-29 07:30:45 +02:00
|
|
|
|
display_values: "Вариант отображения ответов",
|
|
|
|
|
display_values_ori: "ОРИОКС",
|
|
|
|
|
display_values_sorry: "Сори",
|
|
|
|
|
display_values_both: "Оба",
|
2024-04-24 19:23:20 +02:00
|
|
|
|
display_answer: "Отображать ответ рядом с вариантом",
|
2024-04-27 11:38:11 +02:00
|
|
|
|
stop_timer: "Заморозить и скрыть таймер",
|
2024-04-24 19:23:20 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
/* End Labels */
|
|
|
|
|
|
|
|
|
|
/* Config */
|
|
|
|
|
|
2024-04-10 19:29:18 +02:00
|
|
|
|
var config = new GM_config({
|
|
|
|
|
id: 'config',
|
2024-04-24 19:23:20 +02:00
|
|
|
|
title: labels.settings_title,
|
2024-04-10 19:29:18 +02:00
|
|
|
|
fields: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
script_language: {
|
|
|
|
|
label: labels.script_language,
|
|
|
|
|
type: 'select',
|
2024-04-27 11:38:11 +02:00
|
|
|
|
options: [
|
|
|
|
|
'-',
|
|
|
|
|
all_labels.en.l,
|
|
|
|
|
all_labels.ru.l,
|
|
|
|
|
],
|
2024-04-24 19:23:20 +02:00
|
|
|
|
default: '-',
|
|
|
|
|
},
|
2024-04-29 07:30:45 +02:00
|
|
|
|
show_user_id: {
|
|
|
|
|
label: labels.show_user_id,
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
user_id: {
|
|
|
|
|
label: labels.user_id + (GM_getValue("show_user_id", false) ? "" : "<input readonly value='******'>"),
|
|
|
|
|
type: GM_getValue("show_user_id", false) ? 'text' : 'hidden',
|
|
|
|
|
save: false,
|
|
|
|
|
default: '',
|
|
|
|
|
},
|
2024-05-01 11:23:23 +02:00
|
|
|
|
valid_user_id: {
|
|
|
|
|
type: 'hidden',
|
|
|
|
|
default: '',
|
|
|
|
|
},
|
2024-04-29 07:30:45 +02:00
|
|
|
|
server: {
|
|
|
|
|
label: labels.server,
|
|
|
|
|
type: 'text',
|
|
|
|
|
default: '',
|
|
|
|
|
},
|
2024-05-01 11:23:23 +02:00
|
|
|
|
wait_server_response: {
|
|
|
|
|
label: labels.wait_server_response,
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: true,
|
2024-04-29 07:30:45 +02:00
|
|
|
|
},
|
2024-04-10 19:18:48 +02:00
|
|
|
|
auto_answer: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.auto_answer,
|
2024-04-10 19:18:48 +02:00
|
|
|
|
type: 'select',
|
2024-04-27 11:38:11 +02:00
|
|
|
|
options: [
|
|
|
|
|
labels.auto_answer_no,
|
|
|
|
|
labels.auto_answer_first,
|
|
|
|
|
labels.auto_answer_random,
|
|
|
|
|
],
|
|
|
|
|
default: labels.auto_answer_no,
|
2024-04-10 19:18:48 +02:00
|
|
|
|
},
|
2024-05-02 12:57:09 +02:00
|
|
|
|
auto_answer_not_greedy: {
|
|
|
|
|
label: labels.auto_answer_not_greedy,
|
2024-05-02 14:05:31 +02:00
|
|
|
|
type: 'number',
|
|
|
|
|
default: -1,
|
2024-05-02 12:57:09 +02:00
|
|
|
|
},
|
2024-05-02 22:09:40 +02:00
|
|
|
|
auto_answer_greed_level: {
|
|
|
|
|
label: labels.auto_answer_greed_level,
|
|
|
|
|
type: 'number',
|
|
|
|
|
default: -1,
|
|
|
|
|
},
|
2024-04-29 07:30:45 +02:00
|
|
|
|
display_values: {
|
|
|
|
|
label: labels.display_values,
|
|
|
|
|
type: 'select',
|
|
|
|
|
options: [
|
|
|
|
|
labels.display_values_ori,
|
|
|
|
|
labels.display_values_sorry,
|
|
|
|
|
labels.display_values_both,
|
|
|
|
|
],
|
|
|
|
|
default: labels.display_values_ori,
|
|
|
|
|
},
|
2024-04-21 21:50:51 +02:00
|
|
|
|
display_answer: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.display_answer,
|
2024-04-21 21:50:51 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: true,
|
|
|
|
|
},
|
2024-04-27 11:38:11 +02:00
|
|
|
|
stop_timer: {
|
|
|
|
|
label: labels.stop_timer,
|
|
|
|
|
type: 'checkbox',
|
2024-04-29 07:30:45 +02:00
|
|
|
|
default: false,
|
2024-04-27 11:38:11 +02:00
|
|
|
|
},
|
2024-04-22 18:32:46 +02:00
|
|
|
|
register_keyboard_keys: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.register_keyboard_keys,
|
2024-04-22 18:32:46 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: true,
|
|
|
|
|
},
|
|
|
|
|
copy_answers: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.copy_answers,
|
2024-04-22 18:32:46 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
append_question_number: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.append_question_number,
|
2024-04-22 18:32:46 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: true,
|
|
|
|
|
},
|
|
|
|
|
accumulator_enable: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.accumulator_enable,
|
2024-04-22 18:32:46 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
auto_continue: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.auto_continue,
|
2024-04-22 18:32:46 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
auto_continue_time: {
|
|
|
|
|
type: 'hidden',
|
|
|
|
|
default: 0,
|
|
|
|
|
},
|
|
|
|
|
auto_restart: {
|
2024-04-24 19:23:20 +02:00
|
|
|
|
label: labels.auto_restart,
|
2024-04-22 18:32:46 +02:00
|
|
|
|
type: 'checkbox',
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
auto_restart_time: {
|
|
|
|
|
type: 'hidden',
|
|
|
|
|
default: 0,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
events: {
|
|
|
|
|
init: function() {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
var valid_user_id = this.get('valid_user_id');
|
|
|
|
|
if (!validate_user_id(valid_user_id)) {
|
|
|
|
|
valid_user_id = generate_user_id();
|
|
|
|
|
}
|
|
|
|
|
this.set('user_id', valid_user_id);
|
|
|
|
|
this.set('valid_user_id', valid_user_id);
|
|
|
|
|
GM_setValue('show_user_id', this.get('show_user_id'));
|
2024-04-27 11:38:11 +02:00
|
|
|
|
GM_setValue('stop_timer', this.get('stop_timer'));
|
2024-04-22 18:32:46 +02:00
|
|
|
|
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', "");
|
|
|
|
|
}
|
2024-04-24 19:23:20 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
2024-04-22 18:32:46 +02:00
|
|
|
|
},
|
|
|
|
|
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.");
|
|
|
|
|
}
|
2024-04-29 07:30:45 +02:00
|
|
|
|
if (!validate_user_id(forgotten['user_id'])) {
|
|
|
|
|
this.set('user_id', this.get('valid_user_id'))
|
|
|
|
|
alert('User ID is invalid!');
|
|
|
|
|
} else {
|
|
|
|
|
this.set('valid_user_id', forgotten['user_id'])
|
|
|
|
|
}
|
2024-04-24 19:23:20 +02:00
|
|
|
|
this.init();
|
2024-04-22 18:32:46 +02:00
|
|
|
|
},
|
2024-04-10 19:18:48 +02:00
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
GM_registerMenuCommand(labels.settings_title, () => {
|
2024-04-10 19:18:48 +02:00
|
|
|
|
config.open();
|
2024-04-21 21:50:51 +02:00
|
|
|
|
});
|
2024-04-10 19:18:48 +02:00
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
/* End Config */
|
|
|
|
|
|
|
|
|
|
/* Server */
|
|
|
|
|
|
2024-04-29 07:30:45 +02:00
|
|
|
|
function send_to_server(results) {
|
|
|
|
|
var server = config.get('server');
|
|
|
|
|
if (server != '') {
|
|
|
|
|
GM_xmlhttpRequest({
|
|
|
|
|
method: 'POST',
|
|
|
|
|
url: 'https://' + server,
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
data: JSON.stringify(results),
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 07:30:45 +02:00
|
|
|
|
function fetch_from_server(path, func) {
|
|
|
|
|
var server = config.get('server');
|
2024-04-30 20:46:53 +02:00
|
|
|
|
var fetched_data = GM_getValue('fetched_data');
|
2024-05-03 20:19:09 +02:00
|
|
|
|
if ((fetched_data == undefined) || (fetched_data.forbidden == true)) {
|
2024-04-30 20:46:53 +02:00
|
|
|
|
fetched_data = {};
|
|
|
|
|
}
|
2024-05-01 11:55:29 +02:00
|
|
|
|
if ((server != '') && (Object.keys(fetched_data).length == 0)) {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
GM_xmlhttpRequest({
|
|
|
|
|
method: 'GET',
|
2024-05-03 19:44:14 +02:00
|
|
|
|
url: 'https://' + server + '/' + path + '?uid=' + config.get('user_id') + "&sid=" + student_name,
|
2024-05-02 12:57:09 +02:00
|
|
|
|
timeout: 1000,
|
2024-04-29 07:30:45 +02:00
|
|
|
|
onload: function (response) {
|
|
|
|
|
var text = response.responseText;
|
2024-05-02 12:57:09 +02:00
|
|
|
|
if (response.status == 404) {
|
|
|
|
|
fetched_data = {version: VERSION};
|
|
|
|
|
GM_setValue('fetched_data', fetched_data);
|
|
|
|
|
func(fetched_data);
|
2024-05-03 20:19:09 +02:00
|
|
|
|
} else if (response.status == 403) {
|
|
|
|
|
fetched_data = {version: VERSION, forbidden: true};
|
|
|
|
|
forbidden = true;
|
|
|
|
|
GM_setValue('fetched_data', fetched_data);
|
|
|
|
|
func(fetched_data);
|
2024-05-02 12:57:09 +02:00
|
|
|
|
} else if (!text.includes("{")) {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
func({});
|
|
|
|
|
} else {
|
2024-04-30 20:46:53 +02:00
|
|
|
|
fetched_data = JSON.parse(text);
|
|
|
|
|
GM_setValue('fetched_data', fetched_data);
|
|
|
|
|
func(fetched_data);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onerror: function (e) {
|
|
|
|
|
func({});
|
|
|
|
|
},
|
|
|
|
|
onabort: function (e) {
|
|
|
|
|
func({});
|
|
|
|
|
},
|
|
|
|
|
ontimeout: function (e) {
|
|
|
|
|
func({});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
2024-04-30 20:46:53 +02:00
|
|
|
|
func(fetched_data);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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) {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
window.setInterval = (f, t, its_me = false) => {
|
|
|
|
|
return window.setInterval(f, its_me ? t : 10^999);
|
2024-04-27 11:38:11 +02:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
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);
|
2024-04-22 18:32:46 +02:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-11-29 16:30:05 +01:00
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
/* End Events */
|
|
|
|
|
|
|
|
|
|
/* Page properties */
|
|
|
|
|
|
|
|
|
|
// const success = -1487162948;
|
|
|
|
|
var answers = [];
|
2024-05-01 11:23:23 +02:00
|
|
|
|
var sorted_objects_value = [];
|
2024-04-30 20:46:53 +02:00
|
|
|
|
var variant, hash, type, correct, incorrect, version;
|
2024-05-03 19:44:14 +02:00
|
|
|
|
var student_name = "";
|
2024-05-03 20:19:09 +02:00
|
|
|
|
var forbidden = false;
|
2024-05-01 11:23:23 +02:00
|
|
|
|
var prev_new_answer_f = false;
|
|
|
|
|
var new_answer_f = false;
|
2024-04-27 11:38:11 +02:00
|
|
|
|
var testID = (() => {
|
|
|
|
|
var url = document.URL;
|
|
|
|
|
url = url.slice(url.indexOf("idKM=") + 5);
|
|
|
|
|
url = url.slice(0, url.indexOf("&"));
|
|
|
|
|
return url;
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
/* End properties */
|
|
|
|
|
|
|
|
|
|
/* Functions */
|
|
|
|
|
|
2024-04-29 20:40:49 +02:00
|
|
|
|
function comb(s, blacklist = []) {
|
|
|
|
|
var result = [];
|
|
|
|
|
for (var i = 1; i < (1 << s.length); i++) {
|
|
|
|
|
var temp = '';
|
|
|
|
|
for (var j = 0; j < s.length; j++) {
|
|
|
|
|
if (i & Math.pow(2, j)) {
|
|
|
|
|
temp += s[j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
temp = "{" + temp + "}";
|
|
|
|
|
if (!blacklist.includes(temp)) {
|
|
|
|
|
result.push(temp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 07:30:45 +02:00
|
|
|
|
// https://github.com/ajayyy/maze-utils/blob/036086403f675b8fea0e22065f26ba534e351562/src/setup.ts
|
|
|
|
|
function generate_user_id(length = 36) {
|
|
|
|
|
var i;
|
|
|
|
|
var result = "";
|
|
|
|
|
const cryptoFuncs = typeof window === "undefined" ? crypto : window.crypto;
|
|
|
|
|
if (cryptoFuncs && cryptoFuncs.getRandomValues) {
|
|
|
|
|
const values = new Uint32Array(length);
|
|
|
|
|
cryptoFuncs.getRandomValues(values);
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
|
result += charset[values[i] % charset.length];
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
|
result += charset[Math.floor(Math.random() * charset.length)];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function validate_user_id(uid, length = 36) {
|
|
|
|
|
var i;
|
|
|
|
|
if (uid.length != length) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
|
if (!charset.includes(uid[i])) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-10 15:31:06 +02:00
|
|
|
|
// https://stackoverflow.com/a/15710692
|
2024-04-29 07:30:45 +02:00
|
|
|
|
function hashCode(s, return_num = false) {
|
|
|
|
|
var result = "";
|
|
|
|
|
var h = s.split("").reduce(function(a, b) {
|
2024-04-10 19:18:48 +02:00
|
|
|
|
a = ((a << 5) - a) + b.charCodeAt(0);
|
|
|
|
|
return a & a;
|
|
|
|
|
}, 0);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
if (return_num) {
|
|
|
|
|
return h;
|
|
|
|
|
}
|
|
|
|
|
while (h != 0) {
|
|
|
|
|
result += charset[((h % charset.length) + charset.length) % charset.length];
|
|
|
|
|
h = Math.floor(Math.abs(h) / charset.length) * (h / Math.abs(h));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function set_to_clear(id, exec_if_not_cleared) {
|
|
|
|
|
var clear = GM_getValue('clear_tests', new Object());
|
|
|
|
|
if (!clear[id]) {
|
|
|
|
|
exec_if_not_cleared();
|
|
|
|
|
}
|
|
|
|
|
clear[id] = true;
|
|
|
|
|
GM_setValue('clear_tests', clear);
|
2024-04-10 15:31:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-21 21:50:51 +02:00
|
|
|
|
function update_variant() {
|
2024-04-22 18:32:46 +02:00
|
|
|
|
var i, pbox;
|
2024-04-29 20:40:49 +02:00
|
|
|
|
var status = "Неизвестен";
|
2024-04-21 21:50:51 +02:00
|
|
|
|
var chosen_answer = "";
|
2024-04-27 11:38:11 +02:00
|
|
|
|
switch (type) {
|
|
|
|
|
case 'checkbox':
|
|
|
|
|
case 'radio': {
|
|
|
|
|
for (i = 0; i < answers.length; i++) {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
chosen_answer += answers[i].checked ? answers[i].sorry_value : "";
|
2024-04-27 11:38:11 +02:00
|
|
|
|
}
|
|
|
|
|
chosen_answer = chosen_answer.split('').sort().join('');
|
2024-04-29 07:30:45 +02:00
|
|
|
|
if (type == 'checkbox') {
|
|
|
|
|
chosen_answer = "{" + chosen_answer + "}";
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
} break;
|
|
|
|
|
case 'text': {
|
|
|
|
|
for (i = 0; i < answers.length; i++) {
|
|
|
|
|
chosen_answer += "[" + answers[i].value + "]";
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-21 21:50:51 +02:00
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
new_answer_f = true;
|
2024-05-01 11:55:29 +02:00
|
|
|
|
if ((version != VERSION) && (version !== undefined)) {
|
2024-04-30 20:46:53 +02:00
|
|
|
|
status = "<span style='color: red;'>Скрипт устарел</span>";
|
2024-04-30 20:52:00 +02:00
|
|
|
|
GM_setValue('fetched_data', {});
|
2024-04-30 20:46:53 +02:00
|
|
|
|
} else if (version === undefined) {
|
2024-05-01 11:37:45 +02:00
|
|
|
|
if (config.get('wait_server_response')) {
|
|
|
|
|
status = "<span style='color: blue;'>Ожидание ответа</span>";
|
|
|
|
|
} else {
|
|
|
|
|
status = "<span style='color: red;'>Нет соединения</span>";
|
|
|
|
|
}
|
2024-05-03 20:19:09 +02:00
|
|
|
|
} else if (forbidden) {
|
|
|
|
|
status = "<span style='color: red;'>Доступ запрещён</span>";
|
2024-04-30 20:46:53 +02:00
|
|
|
|
} else if (chosen_answer == correct) {
|
2024-04-29 20:40:49 +02:00
|
|
|
|
status = "<span style='color: green;'>Верно</span>";
|
2024-05-01 11:23:23 +02:00
|
|
|
|
new_answer_f = false;
|
2024-04-29 20:40:49 +02:00
|
|
|
|
} else if (incorrect.includes(chosen_answer)) {
|
|
|
|
|
status = "<span style='color: red;'>Неверно</span>";
|
2024-05-01 11:23:23 +02:00
|
|
|
|
new_answer_f = false;
|
2024-04-29 20:40:49 +02:00
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
GM_setValue('new_answer_f', prev_new_answer_f || new_answer_f);
|
2024-04-21 21:50:51 +02:00
|
|
|
|
var pboxes = document.getElementsByTagName('p');
|
|
|
|
|
const display_answer = config.get('display_answer');
|
|
|
|
|
for (i = 0; i < pboxes.length; i++) {
|
2024-04-22 18:32:46 +02:00
|
|
|
|
pbox = pboxes[i];
|
2024-04-21 21:50:51 +02:00
|
|
|
|
if (pbox.textContent.includes("Вопрос:")) {
|
2024-04-29 20:40:49 +02:00
|
|
|
|
pbox.innerHTML = "<i>(Вариант <input onfocus='this.select();' id='variant' value='" + hash + (display_answer == true ? (" " + chosen_answer) : "") + "' readonly>)</i>";
|
|
|
|
|
if (config.get('server') != '') {
|
|
|
|
|
pbox.innerHTML += "<br>Статус: " + status;
|
|
|
|
|
}
|
|
|
|
|
pbox.innerHTML += "<br>Вопрос:";
|
2024-04-21 21:50:51 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-22 18:32:46 +02:00
|
|
|
|
var question_num = undefined;
|
|
|
|
|
for (i = 0; i < pboxes.length; i++) {
|
|
|
|
|
pbox = pboxes[i];
|
|
|
|
|
if (pbox.textContent.includes("Текущий вопрос: ")) {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
question_num = pbox.textContent.slice(variant.indexOf("Текущий вопрос: ") + 16).trim();
|
2024-04-22 18:32:46 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-29 07:30:45 +02:00
|
|
|
|
if (hash !== undefined) {
|
|
|
|
|
var tests = GM_getValue('tests', new Object());
|
|
|
|
|
if (tests[testID] === undefined) {
|
|
|
|
|
tests[testID] = new Object();
|
|
|
|
|
}
|
|
|
|
|
tests[testID][hash] = [question_num, chosen_answer, answers.length];
|
|
|
|
|
GM_setValue('tests', tests);
|
2024-04-21 21:50:51 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-02 12:57:09 +02:00
|
|
|
|
function color_answers() {
|
|
|
|
|
var answer, correct_element, incorrect_element, sorry_val;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'radio': {
|
|
|
|
|
for (answer in answers) {
|
|
|
|
|
if (answers[answer].sorry_value == correct) {
|
|
|
|
|
if (!answers[answer].sorry_colored && (version !== undefined)) {
|
|
|
|
|
correct_element = answers[answer].parentNode;
|
|
|
|
|
sorry_val = answers[answer].sorry_value;
|
|
|
|
|
correct_element.innerHTML = "<span style='color: green;'>" + correct_element.innerHTML + "</span>";
|
|
|
|
|
answers[answer] = correct_element.getElementsByTagName('input')[0];
|
|
|
|
|
answers[answer].sorry_value = sorry_val;
|
|
|
|
|
answers[answer].sorry_colored = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (incorrect.includes(answers[answer].sorry_value)) {
|
|
|
|
|
if (!answers[answer].sorry_colored && (version !== undefined)) {
|
|
|
|
|
incorrect_element = answers[answer].parentNode;
|
|
|
|
|
sorry_val = answers[answer].sorry_value;
|
|
|
|
|
incorrect_element.innerHTML = "<span style='color: red;'>" + incorrect_element.innerHTML + "</span>";
|
|
|
|
|
answers[answer] = incorrect_element.getElementsByTagName('input')[0];
|
|
|
|
|
answers[answer].sorry_value = sorry_val;
|
|
|
|
|
answers[answer].sorry_colored = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case 'checkbox': {
|
|
|
|
|
for (answer in answers) {
|
|
|
|
|
if (correct != undefined) {
|
|
|
|
|
if (correct.includes(answers[answer].sorry_value)) {
|
2024-05-01 11:55:29 +02:00
|
|
|
|
if (!answers[answer].sorry_colored && (version !== undefined)) {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
correct_element = answers[answer].parentNode;
|
|
|
|
|
sorry_val = answers[answer].sorry_value;
|
|
|
|
|
correct_element.innerHTML = "<span style='color: green;'>" + correct_element.innerHTML + "</span>";
|
|
|
|
|
answers[answer] = correct_element.getElementsByTagName('input')[0];
|
|
|
|
|
answers[answer].sorry_value = sorry_val;
|
|
|
|
|
answers[answer].sorry_colored = true;
|
|
|
|
|
}
|
2024-05-02 12:57:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function auto_answer() {
|
|
|
|
|
var answer, chosen_answer, sorry_val, correct_element, incorrect_element;
|
|
|
|
|
const auto_answer = config.get('auto_answer');
|
|
|
|
|
function pick_answer(picked) {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'radio': {
|
|
|
|
|
for (answer in answers) {
|
|
|
|
|
if (answers[answer].sorry_value == picked) {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
answers[answer].click();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case 'checkbox': {
|
|
|
|
|
for (answer in answers) {
|
2024-05-02 12:57:09 +02:00
|
|
|
|
if (picked.includes(answers[answer].sorry_value)) {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
answers[answer].click();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case 'text': {
|
2024-05-02 12:57:09 +02:00
|
|
|
|
var corr = picked.slice(1, picked.length - 1).split('][');
|
2024-05-01 11:23:23 +02:00
|
|
|
|
for (i = 0; (i < answers.leght) && (i < corr.length); i++) {
|
|
|
|
|
answers[i].placeholder = corr[i];
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
}
|
2024-05-02 12:57:09 +02:00
|
|
|
|
}
|
2024-05-02 22:09:40 +02:00
|
|
|
|
var greed = GM_getValue('greed');
|
|
|
|
|
if (greed === undefined) {
|
|
|
|
|
greed = 99999;
|
|
|
|
|
}
|
2024-05-02 12:57:09 +02:00
|
|
|
|
if (correct != undefined) {
|
|
|
|
|
pick_answer(correct);
|
2024-05-01 11:23:23 +02:00
|
|
|
|
} else if (auto_answer == labels.auto_answer_random) {
|
2024-05-02 22:09:40 +02:00
|
|
|
|
if ((incorrect.length >= Math.max(config.get('auto_answer_not_greedy'), 1)) &&
|
|
|
|
|
((config.get('auto_answer_not_greedy') > 0) || (greed <= 0))) {
|
|
|
|
|
chosen_answer = Math.floor(Math.random() * incorrect.length);
|
|
|
|
|
pick_answer(incorrect[chosen_answer]);
|
|
|
|
|
} else {
|
|
|
|
|
GM_setValue('greed', greed - 1);
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'radio': {
|
|
|
|
|
var possible_answers = [];
|
|
|
|
|
for (answer in answers) {
|
|
|
|
|
if (incorrect.includes(answers[answer].sorry_value) == false) {
|
|
|
|
|
possible_answers.push(answer);
|
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
}
|
2024-05-02 22:09:40 +02:00
|
|
|
|
chosen_answer = Math.floor(Math.random() * possible_answers.length);
|
|
|
|
|
answers[possible_answers[chosen_answer]].click();
|
|
|
|
|
} break;
|
|
|
|
|
case 'checkbox': {
|
|
|
|
|
var combs = comb(charset.slice(0, answers.length), incorrect);
|
|
|
|
|
var pick = combs[Math.floor(Math.random() * combs.length)];
|
|
|
|
|
for (i = 0; i < answers.length; i++) {
|
|
|
|
|
if(pick.includes(answers[i].sorry_value)) {
|
|
|
|
|
answers[i].click();
|
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
}
|
2024-05-02 22:09:40 +02:00
|
|
|
|
} break;
|
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
}
|
|
|
|
|
} else if (auto_answer == labels.auto_answer_first) {
|
|
|
|
|
Object.values(sorted_objects_value)[0].click();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
|
2024-05-01 11:23:23 +02:00
|
|
|
|
function parse_server_data(server_data) {
|
2024-04-30 20:46:53 +02:00
|
|
|
|
version = server_data.version;
|
2024-05-01 11:55:29 +02:00
|
|
|
|
if ((version !== VERSION) && (version !== undefined)) {
|
2024-04-30 17:08:00 +02:00
|
|
|
|
console.warn("Sorryops is outdated");
|
|
|
|
|
server_data = {};
|
|
|
|
|
GM_openInTab("https://greasyfork.org/en/scripts/481036-sorryops");
|
|
|
|
|
config.set('auto_continue', false);
|
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
if (server_data.hasOwnProperty('correct')) {
|
|
|
|
|
correct = server_data.correct;
|
|
|
|
|
if (correct === undefined) {
|
|
|
|
|
correct = undefined;
|
|
|
|
|
} else if (correct.hasOwnProperty(hash)) {
|
|
|
|
|
correct = correct[hash];
|
|
|
|
|
} else {
|
|
|
|
|
correct = undefined;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
correct = undefined;
|
|
|
|
|
}
|
|
|
|
|
if (server_data.hasOwnProperty('incorrect')) {
|
|
|
|
|
incorrect = server_data.incorrect;
|
|
|
|
|
if (incorrect === undefined) {
|
|
|
|
|
incorrect = [];
|
|
|
|
|
} else if (incorrect.hasOwnProperty(hash)) {
|
|
|
|
|
incorrect = incorrect[hash];
|
|
|
|
|
} else {
|
|
|
|
|
incorrect = [];
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
incorrect = [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function auto_continue() {
|
|
|
|
|
var old_time, cur_time;
|
|
|
|
|
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 {
|
2024-05-01 11:37:45 +02:00
|
|
|
|
press_continue_btn();
|
2024-05-01 11:23:23 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function auto_restart() {
|
|
|
|
|
var old_time, cur_time;
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* End Functions */
|
|
|
|
|
|
|
|
|
|
/* Handlers */
|
|
|
|
|
|
2024-05-01 11:55:29 +02:00
|
|
|
|
function test_form_handler(server_response) {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
var i, key, answer, sorry_val;
|
|
|
|
|
var complicated_hash_f = false;
|
2024-04-27 11:38:11 +02:00
|
|
|
|
var boxes = [];
|
2024-04-29 07:30:45 +02:00
|
|
|
|
var sorted_objects;
|
|
|
|
|
var objects_hash = new Object();
|
|
|
|
|
var objects_value = new Object();
|
2024-04-10 13:58:41 +02:00
|
|
|
|
var form = document.getElementById('testform-answer');
|
2024-04-27 11:38:11 +02:00
|
|
|
|
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++);
|
2023-11-29 16:30:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
type = boxes[0].type;
|
2024-04-30 20:46:53 +02:00
|
|
|
|
for (i = 0; i < boxes.length; i++) {
|
|
|
|
|
if (boxes[i].parentNode.innerHTML.includes("<img")) {
|
|
|
|
|
complicated_hash_f = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
switch (type) {
|
|
|
|
|
case 'checkbox':
|
|
|
|
|
case 'radio': {
|
|
|
|
|
for (i = 0; i < boxes.length; i++) {
|
2024-04-30 20:46:53 +02:00
|
|
|
|
boxes[i].hash = hashCode(complicated_hash_f ? boxes[i].parentNode.innerHTML : boxes[i].parentNode.innerText, true);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
objects_hash[boxes[i].hash] = boxes[i];
|
|
|
|
|
objects_value[boxes[i].value] = boxes[i];
|
2024-04-27 11:38:11 +02:00
|
|
|
|
}
|
2024-04-29 07:30:45 +02:00
|
|
|
|
const sorted_objects_hash = Object.keys(objects_hash).sort().reduce(
|
|
|
|
|
(obj, key) => {
|
|
|
|
|
obj[key] = objects_hash[key];
|
|
|
|
|
return obj;
|
|
|
|
|
}, {}
|
|
|
|
|
);
|
2024-05-01 11:23:23 +02:00
|
|
|
|
sorted_objects_value = Object.keys(objects_value).sort().reduce(
|
2024-04-27 11:38:11 +02:00
|
|
|
|
(obj, key) => {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
obj[key] = objects_value[key];
|
2024-04-27 11:38:11 +02:00
|
|
|
|
return obj;
|
|
|
|
|
}, {}
|
|
|
|
|
);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
i = 0;
|
|
|
|
|
sorted_objects = sorted_objects_hash;
|
|
|
|
|
for (key in sorted_objects) {
|
2024-04-27 11:38:11 +02:00
|
|
|
|
sorted_objects[key].parentNode.remove();
|
|
|
|
|
form.appendChild(sorted_objects[key].parentNode);
|
|
|
|
|
}
|
|
|
|
|
calculate_variant_hash();
|
2024-05-01 11:55:29 +02:00
|
|
|
|
parse_server_data(server_response);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
for (key in sorted_objects) {
|
|
|
|
|
sorted_objects[key].sorry_value = charset[i++];
|
|
|
|
|
var span = document.createElement('span');
|
|
|
|
|
var disp_val;
|
|
|
|
|
switch (config.get('display_values')) {
|
|
|
|
|
case labels.display_values_ori:
|
|
|
|
|
disp_val = sorted_objects[key].value;
|
|
|
|
|
break;
|
|
|
|
|
case labels.display_values_sorry:
|
|
|
|
|
disp_val = sorted_objects[key].sorry_value;
|
|
|
|
|
break;
|
|
|
|
|
case labels.display_values_both:
|
|
|
|
|
disp_val = sorted_objects[key].value + ":" + sorted_objects[key].sorry_value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
span.innerHTML = disp_val + ") ";
|
|
|
|
|
sorted_objects[key].parentNode.insertBefore(span, sorted_objects[key]);
|
|
|
|
|
answers.push(sorted_objects[key]);
|
|
|
|
|
}
|
|
|
|
|
if (config.get('display_values') == labels.display_values_ori) {
|
|
|
|
|
for (key in sorted_objects_value) {
|
|
|
|
|
sorted_objects_value[key].parentNode.remove();
|
|
|
|
|
form.appendChild(sorted_objects_value[key].parentNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
} break;
|
|
|
|
|
case 'text': {
|
|
|
|
|
answers = boxes;
|
|
|
|
|
calculate_variant_hash();
|
|
|
|
|
} break;
|
2024-04-10 19:18:48 +02:00
|
|
|
|
}
|
2024-05-02 12:57:09 +02:00
|
|
|
|
color_answers();
|
2024-05-01 11:23:23 +02:00
|
|
|
|
auto_answer();
|
2024-04-21 21:50:51 +02:00
|
|
|
|
update_variant();
|
2024-04-27 11:38:11 +02:00
|
|
|
|
for (i = 0; i < answers.length; i++) {
|
|
|
|
|
answers[i].addEventListener('change', update_variant);
|
|
|
|
|
}
|
2024-04-21 21:50:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function result_page_handler() {
|
2024-04-22 18:32:46 +02:00
|
|
|
|
var i;
|
2024-05-01 11:23:23 +02:00
|
|
|
|
var correct_num = variant.slice(variant.indexOf("Число верных ответов: ") + 22);
|
|
|
|
|
var all_num = variant.slice(variant.indexOf("Число неверных ответов: ") + 24);
|
|
|
|
|
correct_num = correct_num.slice(0, correct_num.indexOf("\n")).trim();
|
|
|
|
|
all_num = all_num.slice(0, all_num.indexOf("\n")).trim();
|
|
|
|
|
all_num = (parseInt(all_num) + parseInt(correct_num)).toString();
|
2024-04-22 18:32:46 +02:00
|
|
|
|
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]});
|
|
|
|
|
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";
|
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
printer += correct_num;
|
2024-04-22 18:32:46 +02:00
|
|
|
|
if (config.get('copy_answers')) {
|
|
|
|
|
GM_setClipboard(printer);
|
|
|
|
|
}
|
|
|
|
|
if (config.get('accumulator_enable')) {
|
|
|
|
|
var acc = GM_getValue('accumulated_answers', "");
|
|
|
|
|
if (acc != "") {
|
|
|
|
|
acc += "\n\n";
|
|
|
|
|
}
|
2024-04-27 11:38:11 +02:00
|
|
|
|
var prefix = testID;
|
2024-04-22 18:32:46 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-29 07:30:45 +02:00
|
|
|
|
set_to_clear(testID, () => {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
if (GM_getValue('new_answer_f')) {
|
|
|
|
|
send_to_server({
|
|
|
|
|
type: "test_results",
|
|
|
|
|
uid: config.get('user_id'),
|
2024-05-03 19:44:14 +02:00
|
|
|
|
sid: student_name,
|
2024-05-01 11:23:23 +02:00
|
|
|
|
id: testID,
|
|
|
|
|
answers: sorted_test,
|
|
|
|
|
correct: correct_num,
|
|
|
|
|
all: all_num,
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-30 20:46:53 +02:00
|
|
|
|
GM_setValue('fetched_data', {});
|
2024-05-01 11:23:23 +02:00
|
|
|
|
GM_setValue('new_answer_f', false);
|
2024-05-02 22:39:01 +02:00
|
|
|
|
var greed = config.get('auto_answer_greed_level');
|
2024-05-02 22:09:40 +02:00
|
|
|
|
if (greed < 0) {
|
|
|
|
|
greed = 99999;
|
|
|
|
|
}
|
|
|
|
|
GM_setValue('greed', greed);
|
2024-04-29 07:30:45 +02:00
|
|
|
|
});
|
2024-04-22 18:32:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
/* End Handlers */
|
2024-04-21 21:50:51 +02:00
|
|
|
|
|
2024-04-27 11:38:11 +02:00
|
|
|
|
function main() {
|
2024-05-03 19:44:14 +02:00
|
|
|
|
var abox;
|
|
|
|
|
var aboxes = document.getElementsByTagName('a');
|
|
|
|
|
for (abox in aboxes) {
|
|
|
|
|
if ((aboxes[abox].className == 'dropdown-toggle') && aboxes[abox].href.endsWith('#') && !(aboxes[abox].title == 'Уведомления и объявления')) {
|
|
|
|
|
student_name = hashCode(aboxes[abox].innerText);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-21 21:50:51 +02:00
|
|
|
|
variant = document.getElementById('w0').parentNode.textContent;
|
2024-05-01 11:23:23 +02:00
|
|
|
|
prev_new_answer_f = !!GM_getValue('new_answer_f');
|
2024-04-21 21:50:51 +02:00
|
|
|
|
if (variant.includes("Вопрос:")) {
|
2024-04-29 07:30:45 +02:00
|
|
|
|
fetch_from_server(testID, (server_response) => {
|
|
|
|
|
DB_cleaner();
|
2024-05-01 11:55:29 +02:00
|
|
|
|
test_form_handler(server_response);
|
|
|
|
|
if (config.get('wait_server_response') && (version === undefined)) {
|
2024-05-01 11:23:23 +02:00
|
|
|
|
window.setInterval(() => {fetch_from_server(testID, (server_response) => {
|
|
|
|
|
if (version === undefined) {
|
|
|
|
|
parse_server_data(server_response);
|
2024-05-02 12:57:09 +02:00
|
|
|
|
color_answers();
|
|
|
|
|
if (config.get('auto_continue')) {
|
|
|
|
|
auto_answer();
|
|
|
|
|
}
|
2024-05-01 11:23:23 +02:00
|
|
|
|
update_variant();
|
|
|
|
|
if (version === VERSION) {
|
|
|
|
|
auto_continue();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 11:37:45 +02:00
|
|
|
|
})}, 1000, true);
|
2024-05-01 11:23:23 +02:00
|
|
|
|
} else {
|
|
|
|
|
auto_continue();
|
2024-04-22 18:32:46 +02:00
|
|
|
|
}
|
2024-04-29 07:30:45 +02:00
|
|
|
|
});
|
2024-04-22 18:32:46 +02:00
|
|
|
|
} else if (variant.includes("Результат прохождения теста:")) {
|
2024-04-21 21:50:51 +02:00
|
|
|
|
result_page_handler();
|
2024-05-01 11:23:23 +02:00
|
|
|
|
auto_restart();
|
2024-04-10 15:31:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|