Kahoot Cheat (Beta) (Working Dec 2024)

Skibidi Toilet approved, made by floidAI

目前為 2024-12-06 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Kahoot Cheat (Beta) (Working Dec 2024)
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.02
  5. // @description Skibidi Toilet approved, made by floidAI
  6. // @author You
  7. // @match https://kahoot.it/*
  8. // @grant GM.xmlHttpRequest
  9. // @run-at document-idle
  10. // @license Unlicense
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. const selectors = [
  17. 'answer-0',
  18. 'answer-1',
  19. 'answer-2',
  20. 'answer-3'
  21. ];
  22. const questionSelector = '.question-title__Title-sc-12qj0yr-1';
  23. const imageAnswerSelector = '[data-functional-selector="image-answer"]';
  24.  
  25. let quizData = null;
  26. let currentUrl = location.href;
  27.  
  28. const observeUrlChange = () => {
  29. setInterval(() => {
  30. if (location.href !== currentUrl) {
  31. currentUrl = location.href;
  32. if (currentUrl === 'https://kahoot.it/gameblock') {
  33. extractAndSendData();
  34. }
  35. }
  36. }, 500);
  37. };
  38.  
  39. const extractAndSendData = () => {
  40. const questionElement = document.querySelector(questionSelector);
  41. const answerElements = selectors
  42. .map(selector => document.querySelector(`[data-functional-selector="${selector}"]`))
  43. .filter(el => el);
  44.  
  45. if (questionElement && answerElements.length > 0) {
  46. const question = questionElement.innerText.trim();
  47. const answers = answerElements.map(el => el.innerText.trim());
  48.  
  49. if (quizData) {
  50. processQuestionData(question, answers);
  51. } else {
  52. const query = question;
  53. const apiUrl = `https://create.kahoot.it/rest/kahoots/?query=${encodeURIComponent(query)}&limit=20&orderBy=relevance&cursor=0&searchCluster=1&includeExtendedCounters=false&inventoryItemId=ANY`;
  54.  
  55. GM.xmlHttpRequest({
  56. method: 'GET',
  57. url: apiUrl,
  58. onload: function (response) {
  59. const jsonResponse = JSON.parse(response.responseText);
  60. if (jsonResponse.entities && jsonResponse.entities.length > 0) {
  61. const quizId = jsonResponse.entities[0].card.uuid;
  62. const quizDetailsUrl = `https://create.kahoot.it/rest/kahoots/${quizId}/card/?includeKahoot=true`;
  63.  
  64. GM.xmlHttpRequest({
  65. method: 'GET',
  66. url: quizDetailsUrl,
  67. onload: function (response) {
  68. quizData = JSON.parse(response.responseText);
  69. processQuestionData(question, answers);
  70. },
  71. onerror: function (error) {
  72. console.error('Error fetching quiz details:', error);
  73. }
  74. });
  75. } else {
  76. console.error('No matching quizzes found.');
  77. }
  78. },
  79. onerror: function (error) {
  80. console.error('Error making API request:', error);
  81. }
  82. });
  83. }
  84. } else {
  85. console.error('Required elements not found or no answers available.');
  86. }
  87. };
  88.  
  89. const processQuestionData = (question, answers) => {
  90. let matchedQuestion = quizData.kahoot.questions.find(questionInData => {
  91. return questionInData.question.trim() === question;
  92. });
  93.  
  94. if (!matchedQuestion) {
  95. console.warn('Exact match failed. Attempting fuzzy matching...');
  96. matchedQuestion = fuzzyMatchQuestion(question);
  97. }
  98.  
  99. if (matchedQuestion) {
  100. const correctChoice = matchedQuestion.choices.find(choice => choice.correct);
  101.  
  102. if (correctChoice) {
  103. if (correctChoice.image) {
  104. highlightCorrectImageAnswer(correctChoice.image.id);
  105. } else {
  106. const correctAnswerText = correctChoice.answer.trim();
  107. answers.forEach((answerText, index) => {
  108. if (answerText === correctAnswerText) {
  109. const answerElement = document.querySelector(`[data-functional-selector="answer-${index}"]`);
  110. if (answerElement) {
  111. answerElement.innerText = answerText + '.';
  112. }
  113. }
  114. });
  115. }
  116. }
  117. } else {
  118. console.error('No matching question found in quiz data.');
  119. }
  120. };
  121.  
  122. const highlightCorrectImageAnswer = (imageId) => {
  123. const imageElements = document.querySelectorAll(imageAnswerSelector);
  124. imageElements.forEach(imgElement => {
  125. const ariaLabel = imgElement.getAttribute('aria-label');
  126. if (ariaLabel && ariaLabel.includes(imageId)) {
  127. imgElement.style.border = '5px solid green';
  128. }
  129. });
  130. };
  131.  
  132. const fuzzyMatchQuestion = (inputQuestion) => {
  133. const threshold = 0.8;
  134. const similarity = (str1, str2) => {
  135. const normalize = s => s.toLowerCase().replace(/\s+/g, '');
  136. str1 = normalize(str1);
  137. str2 = normalize(str2);
  138. const length = Math.max(str1.length, str2.length);
  139. if (!length) return 1;
  140. const editDistance = levenshtein(str1, str2);
  141. return 1 - editDistance / length;
  142. };
  143.  
  144. const levenshtein = (a, b) => {
  145. const matrix = Array.from({ length: a.length + 1 }, (_, i) => Array(b.length + 1).fill(0));
  146. for (let i = 0; i <= a.length; i++) matrix[i][0] = i;
  147. for (let j = 0; j <= b.length; j++) matrix[0][j] = j;
  148. for (let i = 1; i <= a.length; i++) {
  149. for (let j = 1; j <= b.length; j++) {
  150. matrix[i][j] = Math.min(
  151. matrix[i - 1][j] + 1,
  152. matrix[i][j - 1] + 1,
  153. matrix[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
  154. );
  155. }
  156. }
  157. return matrix[a.length][b.length];
  158. };
  159.  
  160. let bestMatch = null;
  161. let bestScore = 0;
  162.  
  163. quizData.kahoot.questions.forEach(questionInData => {
  164. const score = similarity(inputQuestion, questionInData.question);
  165. if (score >= threshold && score > bestScore) {
  166. bestMatch = questionInData;
  167. bestScore = score;
  168. }
  169. });
  170.  
  171. return bestMatch;
  172. };
  173.  
  174. observeUrlChange();
  175. })();