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})();