MathsOnline HACKS!! {CHEAT} {HACKS} {EXPLOIT} {API} {DECOMPILED}

Fixed prediction: uses correct + incorrect from payload

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         MathsOnline HACKS!! {CHEAT} {HACKS} {EXPLOIT} {API} {DECOMPILED}
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  Fixed prediction: uses correct + incorrect from payload
// @author       Phil 🥹👍 & DynaHacks
// @license      MIT
// @match        *://*.mathsonline.com.au/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // ---------- GLOBALS ----------
    let latestAnswers = [];
    let hudContainer = null;
    let hudContent = null;
    let isHidden = false;
    let progressData = { pointsCompleted: 0, pointsRequired: 0, totalCorrect: 0, totalIncorrect: 0 };
    let cachedSvgContent = '';
    let svgVisible = false;

    let dynamicValues = {
        userQuestionSetId: null,
        worksheetId: null,
        taskId: null,
        menuId: null,
        diagnosticTypeId: null,
        tutorial: null,
        tutorialMaster: null,
        svgInteractiveId: null
    };

    // ---------- STYLES ----------
    const styles = `
        #hacks-hud {
            position: fixed;
            top: 20px;
            right: 20px;
            width: 340px;
            background: rgba(20, 20, 20, 0.95);
            color: #ffffff;
            border: 1px solid #00ff00;
            border-radius: 8px;
            font-family: monospace;
            box-shadow: 0 0 15px rgba(0, 255, 0, 0.2);
            z-index: 999999;
            transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
            user-select: none;
            font-size: 12px;
        }
        #hacks-hud-header {
            background: #111;
            padding: 8px 12px;
            font-weight: bold;
            font-size: 12px;
            border-bottom: 1px solid #333;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: grab;
        }
        #hacks-hud-header:active { cursor: grabbing; }
        #hacks-hud-title { color: #00ff00; font-size: 11px; }
        #hacks-hud-btn-group { display: flex; gap: 6px; }
        .hacks-hud-btn {
            background: #333;
            border: 1px solid #555;
            color: #aaa;
            padding: 2px 8px;
            border-radius: 3px;
            cursor: pointer;
            font-size: 10px;
            font-family: monospace;
        }
        .hacks-hud-btn:hover { background: #444; color: #fff; }
        #hacks-hud-spoof-btn { border-color: #00ff00; color: #00ff00; }
        #hacks-hud-spoof-btn:hover { background: #00ff00; color: #000; }
        #hacks-hud-svg-btn { border-color: #ffaa00; color: #ffaa00; }
        #hacks-hud-svg-btn:hover { background: #ffaa00; color: #000; }
        #hacks-hud-body { padding: 10px 12px; max-height: 350px; overflow-y: auto; font-size: 11px; }
        .hacks-answer-row {
            display: flex;
            justify-content: space-between;
            padding: 4px 0;
            border-bottom: 1px solid #222;
        }
        .hacks-answer-row:last-child { border-bottom: none; }
        .hacks-label { color: #888; }
        .hacks-val { color: #00ff00; font-weight: bold; }
        .hacks-progress {
            background: #111;
            padding: 6px 10px;
            border-radius: 4px;
            margin-bottom: 8px;
            font-size: 11px;
            border-left: 2px solid #00ff00;
        }
        .hacks-progress-bar {
            background: #222;
            height: 4px;
            border-radius: 2px;
            margin-top: 4px;
            overflow: hidden;
        }
        .hacks-progress-bar-fill {
            height: 100%;
            background: #00ff00;
            border-radius: 2px;
            transition: width 0.3s ease;
        }
        .hacks-hidden-hud {
            opacity: 0 !important;
            pointer-events: none !important;
            transform: scale(0.95) translateY(-10px);
        }
        .hacks-progress-text {
            display: flex;
            justify-content: space-between;
            color: #aaa;
        }
        .hacks-progress-text span:first-child { color: #00ff00; }
        .hacks-progress-text span:last-child { color: #888; }
        .hacks-status-ok { color: #00ff00; }
        .hacks-status-warning { color: #ffaa00; }
        .hacks-section-title {
            color: #888;
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 1px;
            margin: 8px 0 4px 0;
            border-bottom: 1px solid #222;
            padding-bottom: 2px;
        }
        .hacks-prediction {
            margin-top: 6px;
            border-top: 1px solid #222;
            padding-top: 6px;
        }
        .hacks-prediction-label {
            color: #888;
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        .hacks-prediction-value {
            font-weight: bold;
            font-size: 14px;
            color: #00ff00;
        }
    `;

    function injectStyles() {
        if (document.getElementById('hacks-styles')) return;
        const styleSheet = document.createElement('style');
        styleSheet.id = 'hacks-styles';
        styleSheet.innerText = styles;
        document.head.appendChild(styleSheet);
    }

    // ---------- PREDICTION ----------
    function updatePrediction() {
        const totalCorrect = parseInt(progressData.totalCorrect) || 0;
        const totalIncorrect = parseInt(progressData.totalIncorrect) || 0;
        const totalAnswered = totalCorrect + totalIncorrect;
        const pointsRequired = parseInt(progressData.pointsRequired) || 1;
        const pointsCompleted = parseInt(progressData.pointsCompleted) || 0;

        const container = document.getElementById('hacks-prediction-value');
        if (!container) return;

        if (totalAnswered === 0) {
            container.textContent = '—';
            container.style.color = '#888';
            return;
        }

        const accuracy = totalCorrect / totalAnswered;
        const predicted = Math.round(accuracy * pointsRequired);
        const finalPrediction = Math.min(predicted, pointsRequired);

        container.textContent = `${finalPrediction} / ${pointsRequired} (${Math.round(accuracy * 100)}%)`;
        container.style.color = accuracy >= 0.8 ? '#00ff00' : accuracy >= 0.5 ? '#ffaa00' : '#ff6b6b';
    }

    // ---------- SVG TOGGLE ----------
    function toggleSVG() {
        const container = document.getElementById('hacks-answers-container');
        if (!container) return;
        const existing = document.getElementById('hacks-svg-placeholder');
        if (existing) {
            existing.remove();
            return;
        }
        const div = document.createElement('div');
        div.id = 'hacks-svg-placeholder';
        div.style.cssText = 'color:#888;font-size:11px;margin-top:6px;padding:6px;border:1px solid #333;border-radius:4px;background:#111;';
        div.textContent = 'SVG toggle — no SVG available (or not implemented in this version)';
        container.appendChild(div);
    }

    // ---------- DETECTION ----------
    function getTutorialFromPage() {
        const urlParams = new URLSearchParams(window.location.search);
        let tutorial = urlParams.get('tutorial') || urlParams.get('tutorialId');
        if (!tutorial) {
            const pathParts = window.location.pathname.split('/');
            for (let i = 0; i < pathParts.length; i++) {
                if (pathParts[i] === 'lessons' && pathParts[i+1]) {
                    tutorial = pathParts[i+2] || pathParts[i+1];
                    break;
                }
            }
        }
        if (!tutorial && typeof window.tutorial !== 'undefined') tutorial = window.tutorial;
        if (!tutorial && window.currentQuestionSet) tutorial = window.currentQuestionSet.tutorial;
        return tutorial || null;
    }

    function getTutorialMasterFromPage() {
        const urlParams = new URLSearchParams(window.location.search);
        let tutorialMaster = urlParams.get('tutorialMaster') || urlParams.get('tutorialmaster');
        if (!tutorialMaster && typeof window.tutorialMaster !== 'undefined') tutorialMaster = window.tutorialMaster;
        if (!tutorialMaster && window.currentQuestionSet) tutorialMaster = window.currentQuestionSet.tutorialMaster;
        if (!tutorialMaster) {
            for (let key in window) {
                if (key.toLowerCase().includes('tutorialmaster') || key.toLowerCase().includes('tutorial_master')) {
                    const val = window[key];
                    if (typeof val === 'string' && /^\d+$/.test(val)) {
                        tutorialMaster = val;
                        break;
                    }
                }
            }
        }
        return tutorialMaster || null;
    }

    // ---------- HUD ----------
    function createHUD() {
        if (document.getElementById('hacks-hud')) return;

        hudContainer = document.createElement('div');
        hudContainer.id = 'hacks-hud';

        hudContainer.innerHTML = `
            <div id="hacks-hud-header">
                <span id="hacks-hud-title">MathsOnline Hacks v2.8.6</span>
                <div id="hacks-hud-btn-group">
                    <button class="hacks-hud-btn" id="hacks-hud-spoof-btn">SPOOF</button>
                    <button class="hacks-hud-btn" id="hacks-hud-svg-btn">SVG</button>
                    <button class="hacks-hud-btn" id="hacks-hud-toggle-btn">HIDE</button>
                </div>
            </div>
            <div id="hacks-hud-body">
                <div id="hacks-progress-container" style="display:none;"></div>
                <div id="hacks-answers-container">
                    <div style="color: #888; text-align: center;">Awaiting question...</div>
                </div>
                <div class="hacks-prediction">
                    <div class="hacks-prediction-label">📊 PREDICTED SCORE</div>
                    <div id="hacks-prediction-value" class="hacks-prediction-value">—</div>
                </div>
            </div>
        `;

        document.documentElement.appendChild(hudContainer);
        hudContent = document.getElementById('hacks-hud-body');

        document.getElementById('hacks-hud-toggle-btn').addEventListener('click', toggleHUD);
        document.getElementById('hacks-hud-spoof-btn').addEventListener('click', spoofAnswers);
        document.getElementById('hacks-hud-svg-btn').addEventListener('click', toggleSVG);

        makeDraggable(hudContainer);
        console.log('[HUD] Created v2.8.6');
    }

    function ensureHUD() {
        if (!document.getElementById('hacks-hud')) {
            console.log('[HUD] Re-injecting...');
            createHUD();
            if (isHidden && hudContainer) {
                hudContainer.classList.add('hacks-hidden-hud');
            }
        }
    }

    const observer = new MutationObserver(() => ensureHUD());
    observer.observe(document.documentElement, { childList: true, subtree: true });
    setInterval(ensureHUD, 3000);

    function makeDraggable(element) {
        const header = document.getElementById('hacks-hud-header');
        if (!header) return;
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

        header.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            if (e.target.classList && e.target.classList.contains('hacks-hud-btn')) return;
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            element.style.top = (element.offsetTop - pos2) + "px";
            element.style.left = (element.offsetLeft - pos1) + "px";
            element.style.right = "auto";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    function toggleHUD() {
        isHidden = !isHidden;
        if (hudContainer) {
            hudContainer.classList.toggle('hacks-hidden-hud', isHidden);
        }
    }

    window.addEventListener('keydown', (e) => {
        if (e.key.toLowerCase() === 'h' && !e.ctrlKey && !e.metaKey) {
            toggleHUD();
        }
    });

    // ---------- UPDATE FUNCTIONS ----------
    function updateProgress(pointsCompleted, pointsRequired, totalCorrect, totalIncorrect) {
        progressData.pointsCompleted = pointsCompleted;
        progressData.pointsRequired = pointsRequired;
        progressData.totalCorrect = totalCorrect;
        progressData.totalIncorrect = totalIncorrect;

        const progressContainer = document.getElementById('hacks-progress-container');
        if (!progressContainer) return;

        if (pointsRequired > 0) {
            progressContainer.style.display = 'block';
            const percent = Math.min((pointsCompleted / pointsRequired) * 100, 100);
            progressContainer.innerHTML = `
                <div class="hacks-progress">
                    <div class="hacks-progress-text">
                        <span>${pointsCompleted}</span>
                        <span>/${pointsRequired} points</span>
                        <span style="color:#888;">✔ ${totalCorrect} | ✘ ${totalIncorrect}</span>
                    </div>
                    <div class="hacks-progress-bar">
                        <div class="hacks-progress-bar-fill" style="width:${percent}%;"></div>
                    </div>
                </div>
            `;
        } else {
            progressContainer.style.display = 'none';
        }

        updatePrediction();
    }

    function updateHUD(answers) {
        if (!hudContent) return;

        const answersContainer = document.getElementById('hacks-answers-container');
        if (!answersContainer) return;

        if (!answers || answers.length === 0) {
            answersContainer.innerHTML = `<div style="color: #888; text-align: center;">⏳ No answers captured yet.</div>`;
            return;
        }

        let html = `<div class="hacks-section-title">Answers</div>`;
        answers.forEach((item, idx) => {
            html += `
                <div class="hacks-answer-row">
                    <span class="hacks-label">Q${idx+1}:</span>
                    <span class="hacks-val">${item.Answer}</span>
                </div>
            `;
        });
        html += `<div style="margin-top:6px;text-align:right;font-size:10px;color:#555;">${answers.length} answer(s) ready</div>`;
        answersContainer.innerHTML = html;
        latestAnswers = answers;
    }

    // ---------- INTERCEPTOR ----------
    function analyzeAndProcess(rawText) {
        const trimmed = rawText.trim();
        if (trimmed.startsWith('{') && (trimmed.includes('"components"') || trimmed.includes('"userQuestionSetId"'))) {
            try {
                const data = JSON.parse(trimmed);

                if (data.userQuestionSetId) dynamicValues.userQuestionSetId = data.userQuestionSetId;
                if (data.worksheetId) dynamicValues.worksheetId = data.worksheetId;
                if (data.taskId) dynamicValues.taskId = data.taskId;
                if (data.menuId) dynamicValues.menuId = data.menuId;
                if (data.diagnosticTypeId) dynamicValues.diagnosticTypeId = data.diagnosticTypeId;
                if (data.tutorial) dynamicValues.tutorial = data.tutorial;
                if (data.tutorialMaster) dynamicValues.tutorialMaster = data.tutorialMaster;
                if (data.svgInteractiveId) dynamicValues.svgInteractiveId = data.svgInteractiveId;

                if (data.pointsCompleted !== undefined) {
                    updateProgress(
                        parseInt(data.pointsCompleted) || 0,
                        parseInt(data.pointsRequired) || 0,
                        parseInt(data.correct) || 0,
                        parseInt(data.incorrect) || 0
                    );
                }

                if (data && data.components) {
                    const answersFound = [];
                    data.components.forEach(comp => {
                        if (comp.ComponentTypeID === "2" && comp.Data) {
                            try {
                                const parsedData = JSON.parse(comp.Data);
                                if (parsedData.Answers) {
                                    answersFound.push({
                                        ComponentID: comp.ComponentID,
                                        Answer: parsedData.Answers
                                    });
                                }
                            } catch (innerErr) {}
                        }
                    });
                    if (answersFound.length > 0) {
                        updateHUD(answersFound);
                    }
                }
            } catch (e) {}
        }
    }

    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        const response = await originalFetch(...args);
        try {
            const clone = response.clone();
            const text = await clone.text();
            analyzeAndProcess(text);
        } catch (e) {}
        return response;
    };

    const originalOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
        this.addEventListener('readystatechange', function() {
            if (this.readyState === 4 && this.status === 200) {
                try {
                    analyzeAndProcess(this.responseText);
                } catch (e) {}
            }
        });
        return originalOpen.apply(this, arguments);
    };

    // ---------- SPOOF ----------
    async function spoofAnswers() {
        if (!latestAnswers || latestAnswers.length === 0) {
            alert('No answers captured yet. Wait for a question to load.');
            return;
        }

        const tutorial = dynamicValues.tutorial || getTutorialFromPage();
        const tutorialMaster = dynamicValues.tutorialMaster || getTutorialMasterFromPage();
        const userQuestionSetId = dynamicValues.userQuestionSetId;
        const worksheetId = dynamicValues.worksheetId || '0';
        const taskId = dynamicValues.taskId || '0';
        const menuId = dynamicValues.menuId || '102';
        const diagnosticTypeId = dynamicValues.diagnosticTypeId || '0';
        const svgInteractiveId = dynamicValues.svgInteractiveId || null;

        if (!userQuestionSetId) {
            alert('No userQuestionSetId captured. Wait for a question to load first.');
            return;
        }

        if (!tutorial || !tutorialMaster) {
            alert('Could not detect tutorial or tutorialMaster.');
            return;
        }

        const inputData = [{
            questionId: 1,
            inputs: latestAnswers.map((item, idx) => ({
                id: `input${idx+1}`,
                value: item.Answer,
                correct: "true"
            })),
            checkboxes: [],
            radiobuttons: [],
            selectables: [],
            draggables: [],
            marks: latestAnswers.map((item, idx) => ({
                id: `mark${idx+1}`,
                correct: "true"
            })),
            solutions: []
        }];

        const payload = {
            userQuestionSetId: userQuestionSetId,
            svgInteractiveId: svgInteractiveId,
            tutorial: tutorial,
            tutorialMaster: tutorialMaster,
            menuId: menuId,
            worksheetId: worksheetId,
            taskId: taskId,
            diagnosticTypeId: diagnosticTypeId,
            userQuestionSetTypeId: '7',
            difficulty: '1',
            correct: latestAnswers.length,
            incorrect: 0,
            duration: Math.floor(8000 + Math.random() * 15000),
            data: JSON.stringify(inputData)
        };

        try {
            const submitRes = await fetch(
                `https://www.mathsonline.com.au/ajax/svg_interactives/submitResult?r=${Math.random()}`,
                {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    body: new URLSearchParams(payload)
                }
            );

            const rawText = await submitRes.text();

            try {
                const result = JSON.parse(rawText);

                if (result.pointsCompleted !== undefined) {
                    updateProgress(
                        parseInt(result.pointsCompleted) || 0,
                        parseInt(result.pointsRequired) || 0,
                        parseInt(result.correct) || 0,
                        parseInt(result.incorrect) || 0
                    );
                }

                alert(`Submitted ${latestAnswers.length} answer(s)! Points: ${progressData.pointsCompleted}/${progressData.pointsRequired}`);
                setTimeout(() => window.location.reload(), 800);
            } catch (parseError) {
                alert(`Server error:\n${rawText.substring(0, 100)}`);
            }
        } catch (e) {
            alert('Spoof failed — check console.');
        }
    }

    // ---------- INIT ----------
    window.addEventListener('DOMContentLoaded', () => {
        injectStyles();
        createHUD();
        console.log('[INIT] Tutorial:', getTutorialFromPage(), 'Master:', getTutorialMasterFromPage());
    });

    console.log('%c[MathsOnline ULTIMATE] Loaded v2.8.6', 'color: #00ff00; font-weight: bold;');
})();