feat: add excises solver
This commit is contained in:
parent
cc3e2c1b10
commit
de58fa6687
1 changed files with 160 additions and 2 deletions
162
script.js
162
script.js
|
|
@ -1,4 +1,4 @@
|
|||
(function autoClickSequential() {
|
||||
(async function autoClickSequential() {
|
||||
// Настройки
|
||||
const CLICK_DELAY = 800;
|
||||
const CHECK_INTERVAL = 500;
|
||||
|
|
@ -335,11 +335,169 @@
|
|||
console.log(`🖱️ Кнопок нажато: ${clickCount}`);
|
||||
}
|
||||
|
||||
function handleAssociatedProgramsPage() {
|
||||
const cards = document.querySelectorAll('button.card.course-card');
|
||||
for (const card of cards) {
|
||||
const isCompleted = card.querySelector('.course-card__info-item_active');
|
||||
if (!isCompleted) {
|
||||
const title = card.querySelector('.course-card__title')?.textContent?.trim() || '(без названия)';
|
||||
console.log(`🎯 Найдена непройденная программа: "${title}"`);
|
||||
card.click();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
console.log('✅ Все программы пройдены');
|
||||
return false;
|
||||
}
|
||||
|
||||
async function waitForModal() {
|
||||
return new Promise(resolve => {
|
||||
const startTime = Date.now();
|
||||
const interval = setInterval(() => {
|
||||
const el = document.querySelector('#portals .skills-modal_visible');
|
||||
if (el) { clearInterval(interval); resolve(el); }
|
||||
else if (Date.now() - startTime > MAX_WAIT_TIME) { clearInterval(interval); resolve(null); }
|
||||
}, CHECK_INTERVAL);
|
||||
});
|
||||
}
|
||||
|
||||
async function handleCourseModal() {
|
||||
console.log('🔍 Ищем непройденную тему в модалке...');
|
||||
const modal = await waitForModal();
|
||||
if (!modal) { console.log('⚠️ Модальное окно не появилось'); return false; }
|
||||
|
||||
// Шаг 1.js: найти и кликнуть первую тему без course-navigation-topic_solved
|
||||
const topics = modal.querySelectorAll('a.course-navigation-topic');
|
||||
let clickedTopic = false;
|
||||
for (const topic of topics) {
|
||||
if (!topic.classList.contains('course-navigation-topic_solved')) {
|
||||
const title = topic.querySelector('.course-navigation-item__title')?.textContent?.trim() || '(без названия)';
|
||||
console.log(`📂 Тема: "${title}"`);
|
||||
topic.click();
|
||||
clickedTopic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!clickedTopic) { console.log('✅ Все темы пройдены'); return false; }
|
||||
|
||||
// Шаг 2: ждём пока появятся уроки внутри темы
|
||||
await sleep(CLICK_DELAY);
|
||||
const startTime = Date.now();
|
||||
let lesson = null;
|
||||
while (Date.now() - startTime < MAX_WAIT_TIME) {
|
||||
const lessons = modal.querySelectorAll('a.course-navigation-lesson');
|
||||
for (const l of lessons) {
|
||||
if (!l.classList.contains('course-navigation-lesson_status_solved')) {
|
||||
lesson = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lesson) break;
|
||||
await sleep(CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
if (!lesson) { console.log('⚠️ Непройденный урок не найден'); return false; }
|
||||
|
||||
const lessonTitle = lesson.querySelector('.course-navigation-item__title')?.textContent?.trim() || '(без названия)';
|
||||
console.log(`📚 Урок: "${lessonTitle}"`);
|
||||
lesson.click();
|
||||
return true;
|
||||
}
|
||||
|
||||
function insertSolutionIntoMonaco(code) {
|
||||
const editors = window.monaco.editor.getEditors();
|
||||
if (!editors || editors.length === 0) {
|
||||
console.log('⚠️ Monaco редактор не найден');
|
||||
return false;
|
||||
}
|
||||
const editor = editors[0];
|
||||
const model = editor.getModel();
|
||||
if (!model) {
|
||||
console.log('⚠️ Monaco модель не найдена');
|
||||
return false;
|
||||
}
|
||||
const fullRange = model.getFullModelRange();
|
||||
editor.executeEdits('auto-solution', [{
|
||||
range: fullRange,
|
||||
text: code,
|
||||
forceMoveMarkers: true,
|
||||
}]);
|
||||
editor.focus();
|
||||
console.log('✅ Решение вставлено в редактор');
|
||||
return true;
|
||||
}
|
||||
|
||||
async function fetchAnswerPanes() {
|
||||
const html = await fetch(window.location.href).then(r => r.text());
|
||||
const match = html.match(/"answer_panes":(\[.*?\]),"has_author_solution"/);
|
||||
if (!match) return null;
|
||||
try {
|
||||
return JSON.parse(match[1]);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleTrainerPage() {
|
||||
console.log('💡 Загружаем исходник страницы для поиска решения...');
|
||||
const answerPanes = await fetchAnswerPanes();
|
||||
|
||||
if (!answerPanes || answerPanes.length === 0) {
|
||||
console.log('ℹ️ Авторского решения нет для этой задачи');
|
||||
return false;
|
||||
}
|
||||
|
||||
const solution = answerPanes[0].content;
|
||||
if (!solution) {
|
||||
console.log('ℹ️ Контент решения пустой');
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`💡 Найдено решение (${answerPanes[0].name}), вставляем...`);
|
||||
insertSolutionIntoMonaco(solution);
|
||||
|
||||
await sleep(CLICK_DELAY);
|
||||
|
||||
const checkBtn = document.querySelector('button.trainer-footer__check-button');
|
||||
if (checkBtn) {
|
||||
checkBtn.click();
|
||||
console.log('✅ Нажата кнопка "Проверить", ждём результата...');
|
||||
} else {
|
||||
console.log('⚠️ Кнопка "Проверить" не найдена');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ждём кнопку "Далее" без ограничения по времени
|
||||
let nextBtn = null;
|
||||
let elapsed = 0;
|
||||
while (!nextBtn) {
|
||||
await sleep(CHECK_INTERVAL);
|
||||
elapsed += CHECK_INTERVAL;
|
||||
nextBtn = document.querySelector('button.trainer-footer__solution-button');
|
||||
if (elapsed % 10000 === 0) {
|
||||
console.log(`⏳ Ожидаем результат проверки... (${elapsed / 1000}с)`);
|
||||
}
|
||||
}
|
||||
nextBtn.click();
|
||||
console.log('➡️ Нажата кнопка "Далее"');
|
||||
return true;
|
||||
}
|
||||
|
||||
window.stopAutoClick = function() {
|
||||
isRunning = false;
|
||||
console.log('⏹ Остановлено');
|
||||
};
|
||||
|
||||
console.log('💡 Для остановки: stopAutoClick()');
|
||||
run();
|
||||
|
||||
if (window.location.pathname.includes('/profile/associated-programs-android-st-v2')) {
|
||||
const found = handleAssociatedProgramsPage();
|
||||
if (found) {
|
||||
await handleCourseModal();
|
||||
}
|
||||
} else if (window.location.pathname.includes('/trainer/')) {
|
||||
await handleTrainerPage();
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
})();
|
||||
Loading…
Add table
Reference in a new issue