Dò Đáp Án LMS 360 (UPDATE VER)

Dò đáp án đúng...

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Dò Đáp Án LMS 360 (UPDATE VER)
// @namespace    http://tampermonkey.net/
// @version      4.3
// @description  Dò đáp án đúng...
// @author       V Quan Người đã test: H Nam, K Ngoc, ...
// @match        https://lms360.edu.vn/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let hasCopied = false; // Biến kiểm tra xem đã dò đáp án chưa
    let currentQuestion = ""; // Biến để lưu câu hỏi hiện tại
    let isPanelOpen = true; // Biến kiểm soát mở/đóng bảng
    let autoCheckEnabled = false; // Biến kiểm soát tự động dò đáp án

    // Hàm tạo tên ngẫu nhiên với tối đa 10 ký tự
    function generateRandomName() {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        let name = '';
        for (let i = 0; i < 10; i++) {
            name += chars.charAt(Math.floor(Math.random() * chars.length));
        }
        return name;
    }

    // Lấy tên ngẫu nhiên
    const nameText = generateRandomName();

    // Tạo bảng thông báo
    const infoBox = document.createElement('div');
    infoBox.style.position = 'fixed';
    infoBox.style.top = '50px';
    infoBox.style.right = '10px';
    infoBox.style.padding = '10px';
    infoBox.style.backgroundColor = 'white';
    infoBox.style.border = '1px solid #ccc';
    infoBox.style.zIndex = '9999';
    infoBox.style.cursor = 'move'; // Để có thể di chuyển bảng
    infoBox.style.width = '250px'; // Đặt kích thước cố định cho bảng
    infoBox.style.transition = 'max-height 0.5s ease-in-out, opacity 0.5s ease-in-out'; // Hiệu ứng đóng mở mượt mà cho cả chiều cao và độ mờ
    infoBox.style.maxHeight = '500px'; // Mở rộng khi hiển thị
    infoBox.style.overflow = 'hidden'; // Ẩn nội dung khi đóng
    infoBox.style.opacity = '1'; // Đảm bảo bảng được hiển thị ban đầu

    // Tạo tiêu đề cho bảng với tên người dùng
    const titleBar = document.createElement('div');
    titleBar.style.fontWeight = 'bold';
    titleBar.style.marginBottom = '10px';
    titleBar.innerHTML = `Dò Đáp Án (<span style="color: black; font-weight: bold;">${nameText}</span>)`; // Chèn tên ngẫu nhiên màu đen vào

    // Tạo nút Dò và hiển thị đáp án cạnh nhau
    const checkButtonContainer = document.createElement('div');
    checkButtonContainer.style.display = 'flex'; // Bố trí theo hàng ngang

    const checkButton = document.createElement('button');
    checkButton.innerText = 'Dò';
    checkButton.style.marginTop = '10px';
    checkButton.style.padding = '5px 10px';
    checkButton.style.cursor = 'pointer';

    const answerDisplay = document.createElement('div');
    answerDisplay.style.marginLeft = '10px'; // Khoảng cách giữa nút Dò và đáp án
    answerDisplay.style.fontWeight = 'bold';
    answerDisplay.style.color = 'green';

    checkButtonContainer.appendChild(checkButton);
    checkButtonContainer.appendChild(answerDisplay);

    // Tạo nút mở/đóng nằm bên ngoài bảng
    const externalToggleButton = document.createElement('button');
    externalToggleButton.innerText = 'Mở/Đóng Dò Đáp Án';
    externalToggleButton.style.position = 'fixed';
    externalToggleButton.style.top = '10px';
    externalToggleButton.style.right = '10px';
    externalToggleButton.style.padding = '5px 10px';
    externalToggleButton.style.cursor = 'pointer';
    externalToggleButton.style.zIndex = '10000';

    // Tạo checkbox tùy chọn tự động dò đáp án
    const autoCheckLabel = document.createElement('label');
    autoCheckLabel.style.display = 'block';
    autoCheckLabel.style.marginTop = '10px';
    autoCheckLabel.innerHTML = 'Tự động dò đáp án + AUTO'; // Thêm " + AUTO"

    const autoCheckBox = document.createElement('input');
    autoCheckBox.type = 'checkbox';
    autoCheckBox.style.marginLeft = '5px';

    autoCheckLabel.appendChild(autoCheckBox);

    // Hàm kiểm tra câu hỏi hiện tại để reset khi thay đổi
    function checkCurrentQuestion(iframeDoc) {
        const questionElement = iframeDoc.querySelector(".h5p-question-content");
        if (questionElement) {
            const newQuestion = questionElement.innerText || ""; // Lấy nội dung câu hỏi hiện tại
            if (newQuestion !== currentQuestion) {
                currentQuestion = newQuestion;
                hasCopied = false; // Reset biến khi câu hỏi thay đổi
                answerDisplay.innerHTML = ""; // Xóa nội dung hiển thị đáp án
            }
        }
    }

    // Hàm dò đáp án
    function findCorrectAnswer() {
        const iframe = document.querySelector('iframe'); // Chọn iframe đầu tiên
        if (!iframe) {
            answerDisplay.innerHTML = 'Không tìm thấy iframe.';
            return;
        }

        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; // Truy cập tài liệu của iframe

        checkCurrentQuestion(iframeDoc); // Kiểm tra nếu câu hỏi đã thay đổi

        if (hasCopied) return; // Ngăn việc dò lại nếu đã dò rồi

        // Hàm dò định kỳ (cho trường hợp DOM không tải ngay lập tức)
        function periodicCheck() {
            // Sử dụng JS path cố định để tìm câu trả lời đúng (JS path cũ)
            let correctAnswer = iframeDoc.querySelector("body > div > div > div.h5p-question-content > div > div.h5p-sc-set.h5p-sc-animate > div.h5p-sc-slide.h5p-sc.h5p-sc-current-slide > ul > li.h5p-sc-alternative.h5p-sc-is-correct");

            if (!correctAnswer) {
                // Nếu không tìm thấy đáp án đúng theo JS path cũ, thử với JS path mới
                correctAnswer = iframeDoc.querySelector("body > div > div > div.h5p-video-wrapper.h5p-video.hardware-accelerated > div > div > div > div > div.h5p-question-content > div > div.h5p-sc-set.h5p-sc-animate > div.h5p-sc-slide.h5p-sc.h5p-sc-current-slide > ul > li.h5p-sc-alternative.h5p-sc-is-correct");
            }

            if (correctAnswer) {
                const answerText = correctAnswer.querySelector('.h5p-sc-label p').innerText; // Lấy nội dung đáp án đúng

                if (autoCheckEnabled) {
                    correctAnswer.click(); // Tự động chọn đáp án đúng nếu đã bật tùy chọn tự động
                }

                // Kiểm tra xem có hình ảnh không
                const imgElement = correctAnswer.querySelector('img');
                if (imgElement) {
                    const imgSrc = imgElement.src;

                    if (imgSrc.startsWith('data:image/svg+xml')) {
                        const svgImage = document.createElement('img');
                        svgImage.src = imgSrc;
                        svgImage.style.maxWidth = '50px'; // Điều chỉnh kích thước tối đa của ảnh
                        svgImage.style.marginLeft = '10px'; // Khoảng cách giữa chữ và hình ảnh

                        const textNode = document.createTextNode(`Đáp án: ${answerText} - Hình ảnh: `);
                        answerDisplay.appendChild(textNode);
                        answerDisplay.appendChild(svgImage);
                    } else {
                        answerDisplay.innerHTML = `Đáp án: ${answerText} - Ảnh không phải SVG.`;
                    }
                } else {
                    answerDisplay.innerHTML = `Đáp án: ${answerText}`; // Hiển thị đáp án nếu không có hình ảnh
                }
                hasCopied = true; // Đánh dấu là đã tìm thấy đáp án
            } else {
                answerDisplay.innerHTML = 'Không tìm thấy đáp án. Tiếp tục dò...';
                setTimeout(periodicCheck, 1000); // Thử lại sau 1 giây nếu chưa tìm thấy
            }
        }

        // Khởi động dò đáp án định kỳ
        periodicCheck();
    }

    // Khi nhấn nút Dò, thực hiện tìm kiếm đáp án
    checkButton.onclick = findCorrectAnswer;

    // Khi nhấn nút mở/đóng bảng
    externalToggleButton.onclick = function() {
        isPanelOpen = !isPanelOpen;
        if (isPanelOpen) {
            infoBox.style.maxHeight = '500px'; // Mở bảng
            infoBox.style.opacity = '1';
        } else {
            infoBox.style.maxHeight = '0'; // Đóng bảng
            infoBox.style.opacity = '0';
        }
    };

    // Khi nhấn checkbox tự động dò đáp án
    autoCheckBox.onchange = function() {
        autoCheckEnabled = autoCheckBox.checked; // Cập nhật trạng thái tự động dò
        if (autoCheckEnabled) {
            findCorrectAnswer(); // Tự động dò nếu tùy chọn được bật
        }
    };

    // Cho phép di chuyển bảng bằng chuột
    let offsetX = 0, offsetY = 0, isDragging = false;

    titleBar.onmousedown = function(e) {
        isDragging = true;
        offsetX = e.clientX - infoBox.getBoundingClientRect().left;
        offsetY = e.clientY - infoBox.getBoundingClientRect().top;
    };

    document.onmousemove = function(e) {
        if (isDragging) {
            infoBox.style.left = `${e.clientX - offsetX}px`;
            infoBox.style.top = `${e.clientY - offsetY}px`;
        }
    };

    document.onmouseup = function() {
        isDragging = false;
    };

    // Thêm các phần tử vào trang
    infoBox.appendChild(titleBar);
    infoBox.appendChild(checkButtonContainer);
    infoBox.appendChild(autoCheckLabel);
    document.body.appendChild(infoBox);
    document.body.appendChild(externalToggleButton);
})();