Miacademy Answer Cheat

Automatically marks all answers as correct

Size

11.4 KB

Version

1.1.1

Created

Nov 18, 2025

Updated

24 days ago

1// ==UserScript==
2// @name		Miacademy Answer Cheat
3// @description		Automatically marks all answers as correct
4// @version		1.1.1
5// @match		https://*.miacademy.co/*
6// @icon		https://miacademy.co/generated/static-images/miacademy/shared/favicon.ico
7// @grant		GM.xmlhttpRequest
8// ==/UserScript==
9(function() {
10    'use strict';
11
12    console.log('Miacademy Answer Cheat loaded - Version 2.0');
13
14    // Strategy 1: Intercept and modify all network requests
15    const originalFetch = window.fetch;
16    window.fetch = async function(...args) {
17        console.log('Fetch intercepted:', args[0]);
18        const response = await originalFetch.apply(this, args);
19        
20        const url = typeof args[0] === 'string' ? args[0] : args[0]?.url;
21        
22        // Check if this might be an answer validation request
23        if (url && (url.includes('Practice') || url.includes('answer') || url.includes('submit') || url.includes('check') || url.includes('validate') || url.includes('Question'))) {
24            console.log('Intercepted potential answer validation:', url);
25            
26            try {
27                const clonedResponse = response.clone();
28                const text = await clonedResponse.text();
29                console.log('Response text:', text);
30                
31                let data;
32                try {
33                    data = JSON.parse(text);
34                } catch (e) {
35                    console.log('Response is not JSON');
36                    return response;
37                }
38                
39                console.log('Original response data:', data);
40                
41                // Deep clone and modify the data
42                const modifiedData = JSON.parse(JSON.stringify(data));
43                
44                // Try to find and modify any validation fields
45                function makeCorrect(obj) {
46                    if (typeof obj !== 'object' || obj === null) return;
47                    
48                    for (let key in obj) {
49                        if (typeof obj[key] === 'object' && obj[key] !== null) {
50                            makeCorrect(obj[key]);
51                        }
52                        
53                        // Modify any field that might indicate correctness
54                        const lowerKey = key.toLowerCase();
55                        if (lowerKey.includes('correct') || lowerKey.includes('iscorrect')) {
56                            obj[key] = true;
57                            console.log('Modified field:', key, '=', true);
58                        }
59                        if (lowerKey.includes('wrong') || lowerKey.includes('incorrect') || lowerKey.includes('error')) {
60                            obj[key] = false;
61                            console.log('Modified field:', key, '=', false);
62                        }
63                        if (lowerKey.includes('score') || lowerKey.includes('points')) {
64                            if (typeof obj[key] === 'number') {
65                                obj[key] = 100;
66                                console.log('Modified field:', key, '=', 100);
67                            }
68                        }
69                        if (lowerKey.includes('result') || lowerKey.includes('status')) {
70                            if (typeof obj[key] === 'string') {
71                                obj[key] = 'correct';
72                                console.log('Modified field:', key, '=', 'correct');
73                            }
74                        }
75                    }
76                }
77                
78                makeCorrect(modifiedData);
79                console.log('Modified response data:', modifiedData);
80                
81                // Return modified response
82                return new Response(JSON.stringify(modifiedData), {
83                    status: response.status,
84                    statusText: response.statusText,
85                    headers: response.headers
86                });
87            } catch (e) {
88                console.error('Error modifying response:', e);
89            }
90        }
91        
92        return response;
93    };
94
95    // Strategy 2: Intercept XMLHttpRequest
96    const originalXHROpen = XMLHttpRequest.prototype.open;
97    const originalXHRSend = XMLHttpRequest.prototype.send;
98    
99    XMLHttpRequest.prototype.open = function(method, url, ...rest) {
100        this._url = url;
101        this._method = method;
102        console.log('XHR opened:', method, url);
103        return originalXHROpen.apply(this, [method, url, ...rest]);
104    };
105    
106    XMLHttpRequest.prototype.send = function(body) {
107        console.log('XHR send:', this._method, this._url, body);
108        
109        if (this._url && (this._url.includes('Practice') || this._url.includes('answer') || this._url.includes('submit') || this._url.includes('check') || this._url.includes('Question'))) {
110            console.log('Intercepted XHR answer validation:', this._url);
111            
112            const originalOnReadyStateChange = this.onreadystatechange;
113            const originalOnLoad = this.onload;
114            
115            this.addEventListener('readystatechange', function() {
116                if (this.readyState === 4 && this.status === 200) {
117                    try {
118                        const data = JSON.parse(this.responseText);
119                        console.log('XHR Original response:', data);
120                        
121                        // Modify the response
122                        function makeCorrect(obj) {
123                            if (typeof obj !== 'object' || obj === null) return;
124                            
125                            for (let key in obj) {
126                                if (typeof obj[key] === 'object' && obj[key] !== null) {
127                                    makeCorrect(obj[key]);
128                                }
129                                
130                                const lowerKey = key.toLowerCase();
131                                if (lowerKey.includes('correct') || lowerKey.includes('iscorrect')) {
132                                    obj[key] = true;
133                                }
134                                if (lowerKey.includes('wrong') || lowerKey.includes('incorrect') || lowerKey.includes('error')) {
135                                    obj[key] = false;
136                                }
137                                if (lowerKey.includes('score') || lowerKey.includes('points')) {
138                                    if (typeof obj[key] === 'number') obj[key] = 100;
139                                }
140                                if (lowerKey.includes('result') || lowerKey.includes('status')) {
141                                    if (typeof obj[key] === 'string') obj[key] = 'correct';
142                                }
143                            }
144                        }
145                        
146                        makeCorrect(data);
147                        console.log('XHR Modified response:', data);
148                        
149                        // Override the response
150                        Object.defineProperty(this, 'responseText', {
151                            writable: true,
152                            value: JSON.stringify(data)
153                        });
154                        Object.defineProperty(this, 'response', {
155                            writable: true,
156                            value: this.responseType === 'json' ? data : JSON.stringify(data)
157                        });
158                    } catch (e) {
159                        console.log('Could not parse XHR response as JSON');
160                    }
161                }
162            });
163        }
164        
165        return originalXHRSend.apply(this, arguments);
166    };
167
168    // Strategy 3: Monitor DOM for incorrect feedback and change it
169    function monitorFeedback() {
170        const observer = new MutationObserver((mutations) => {
171            mutations.forEach((mutation) => {
172                mutation.addedNodes.forEach((node) => {
173                    if (node.nodeType === 1) {
174                        // Look for incorrect indicators
175                        const incorrectElements = node.querySelectorAll ? 
176                            node.querySelectorAll('[class*="incorrect"], [class*="wrong"], [class*="error"], [class*="Incorrect"], [class*="Wrong"], [class*="Error"]') : [];
177                        
178                        incorrectElements.forEach(el => {
179                            console.log('Found incorrect element, modifying:', el.className);
180                            // Remove incorrect classes
181                            el.className = el.className.replace(/incorrect|wrong|error/gi, 'correct');
182                            // Hide red X or error icons
183                            if (el.querySelector('svg, img, i')) {
184                                el.style.display = 'none';
185                            }
186                        });
187                        
188                        // Check the node itself
189                        if (node.className && typeof node.className === 'string') {
190                            if (node.className.match(/incorrect|wrong|error/i)) {
191                                console.log('Found incorrect node, modifying:', node.className);
192                                node.className = node.className.replace(/incorrect|wrong|error/gi, 'correct');
193                            }
194                        }
195                    }
196                });
197                
198                // Check for attribute changes
199                if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
200                    const target = mutation.target;
201                    if (target.className && typeof target.className === 'string') {
202                        if (target.className.match(/incorrect|wrong|error/i)) {
203                            console.log('Class changed to incorrect, fixing:', target.className);
204                            target.className = target.className.replace(/incorrect|wrong|error/gi, 'correct');
205                        }
206                    }
207                }
208            });
209        });
210        
211        observer.observe(document.body, {
212            childList: true,
213            subtree: true,
214            attributes: true,
215            attributeFilter: ['class', 'style']
216        });
217        
218        console.log('DOM monitoring active');
219    }
220
221    // Strategy 4: Override any validation functions in window scope
222    function hookValidationFunctions() {
223        // Look for common validation function names
224        const validationNames = ['validateAnswer', 'checkAnswer', 'submitAnswer', 'verifyAnswer', 'isCorrect', 'checkCorrect'];
225        
226        validationNames.forEach(name => {
227            if (window[name] && typeof window[name] === 'function') {
228                const original = window[name];
229                window[name] = function(...args) {
230                    console.log(`Intercepted ${name} function call`);
231                    const result = original.apply(this, args);
232                    console.log('Original result:', result);
233                    // Always return true/correct
234                    return typeof result === 'boolean' ? true : result;
235                };
236            }
237        });
238    }
239
240    // Initialize all strategies
241    if (document.readyState === 'loading') {
242        document.addEventListener('DOMContentLoaded', () => {
243            monitorFeedback();
244            hookValidationFunctions();
245        });
246    } else {
247        monitorFeedback();
248        hookValidationFunctions();
249    }
250
251    console.log('Miacademy Answer Cheat fully active - all strategies enabled!');
252})();
Miacademy Answer Cheat | Robomonkey