├── KaHack!.meta.js ├── KaHack!.user.js ├── LICENSE └── README.md /KaHack!.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name KaHack! 3 | // @version 1.0.25 4 | // @namespace https://github.com/jokeri2222 5 | // @description A hack for kahoot.it! 6 | // @updateURL https://github.com/jokeri2222/Kahoot-Hack/raw/main/KaHack!.meta.js 7 | // @downloadURL https://github.com/jokeri2222/Kahoot-Hack/raw/main/KaHack!.user.js 8 | // @author jokeri2222; https://github.com/jokeri2222 9 | // @match https://kahoot.it/* 10 | // @icon https://www.google.com/s2/favicons?sz=64&domain=kahoot.it 11 | // @grant none 12 | // ==/UserScript== 13 | -------------------------------------------------------------------------------- /KaHack!.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name KaHack! 3 | // @version 1.0.25 4 | // @namespace https://github.com/jokeri2222 5 | // @description A hack for kahoot.it! 6 | // @updateURL https://github.com/jokeri2222/KaHack/raw/main/KaHack!.meta.js 7 | // @downloadURL https://github.com/jokeri2222/KaHack/raw/main/KaHack!.user.js 8 | // @author jokeri2222; https://github.com/jokeri2222 9 | // @match https://kahoot.it/* 10 | // @icon https://www.google.com/s2/favicons?sz=64&domain=kahoot.it 11 | // @grant none 12 | // ==/UserScript== 13 | var Version = '1.0.25' 14 | 15 | var questions = []; 16 | var info = { 17 | numQuestions: 0, 18 | questionNum: -1, 19 | lastAnsweredQuestion: -1, 20 | defaultIL:true, 21 | ILSetQuestion:-1, 22 | }; 23 | var PPT = 950; 24 | var Answered_PPT = 950; 25 | var autoAnswer = false; 26 | var showAnswers = false; 27 | var inputLag = 100; 28 | 29 | function FindByAttributeValue(attribute, value, element_type) { 30 | element_type = element_type || "*"; 31 | var All = document.getElementsByTagName(element_type); 32 | for (var i = 0; i < All.length; i++) { 33 | if (All[i].getAttribute(attribute) == value) { return All[i]; } 34 | } 35 | } 36 | 37 | const uiElement = document.createElement('div'); 38 | uiElement.className = 'floating-ui'; 39 | uiElement.style.position = 'absolute'; 40 | uiElement.style.top = '5%'; 41 | uiElement.style.left = '5%'; 42 | uiElement.style.width = '33vw'; 43 | uiElement.style.height = 'auto'; 44 | uiElement.style.backgroundColor = '#381272'; 45 | uiElement.style.borderRadius = '1vw'; 46 | uiElement.style.boxShadow = '0px 0px 10px 0px rgba(0, 0, 0, 0.5)'; 47 | uiElement.style.zIndex = '9999'; 48 | 49 | const handle = document.createElement('div'); 50 | handle.className = 'handle'; 51 | handle.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 52 | handle.style.fontSize = '1.5vw'; 53 | handle.textContent = 'KaHack!'; 54 | handle.style.color = 'white'; 55 | handle.style.width = '97.5%'; 56 | handle.style.height = '2.5vw'; 57 | handle.style.backgroundColor = '#321066'; 58 | handle.style.borderRadius = '1vw 1vw 0 0'; 59 | handle.style.cursor = 'grab'; 60 | handle.style.textAlign = 'left'; 61 | handle.style.paddingLeft = '2.5%'; 62 | handle.style.lineHeight = '2vw'; 63 | uiElement.appendChild(handle); 64 | 65 | const closeButton = document.createElement('div'); 66 | closeButton.className = 'close-button'; 67 | closeButton.textContent = '✕'; 68 | closeButton.style.position = 'absolute'; 69 | closeButton.style.top = '0'; 70 | closeButton.style.right = '0'; 71 | closeButton.style.width = '12.5%'; 72 | closeButton.style.height = '2.5vw'; 73 | closeButton.style.backgroundColor = 'red'; 74 | closeButton.style.color = 'white'; 75 | closeButton.style.borderRadius = '0 1vw 0 0'; 76 | closeButton.style.display = 'flex'; 77 | closeButton.style.justifyContent = 'center'; 78 | closeButton.style.alignItems = 'center'; 79 | closeButton.style.cursor = 'pointer'; 80 | handle.appendChild(closeButton); 81 | 82 | const minimizeButton = document.createElement('div'); 83 | minimizeButton.className = 'minimize-button'; 84 | minimizeButton.textContent = '─'; 85 | minimizeButton.style.color = 'white'; 86 | minimizeButton.style.position = 'absolute'; 87 | minimizeButton.style.top = '0'; 88 | minimizeButton.style.right = '12.5%'; 89 | minimizeButton.style.width = '12.5%'; 90 | minimizeButton.style.height = '2.5vw'; 91 | minimizeButton.style.backgroundColor = 'gray'; 92 | minimizeButton.style.borderRadius = '0 0 0 0'; 93 | minimizeButton.style.display = 'flex'; 94 | minimizeButton.style.justifyContent = 'center'; 95 | minimizeButton.style.alignItems = 'center'; 96 | minimizeButton.style.cursor = 'pointer'; 97 | handle.appendChild(minimizeButton); 98 | 99 | const header = document.createElement('h2'); 100 | header.textContent = 'QUIZ ID'; 101 | header.style.display = 'block'; 102 | header.style.margin = '1vw'; 103 | header.style.textAlign = 'center'; 104 | header.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 105 | header.style.fontSize = '2vw'; 106 | header.style.color = 'white'; 107 | header.style.textShadow = ` 108 | -1px -1px 0 rgb(47, 47, 47), 109 | 1px -1px 0 rgb(47, 47, 47), 110 | -1px 1px 0 rgb(47, 47, 47), 111 | 1px 1px 0 rgb(47, 47, 47) 112 | `; 113 | 114 | uiElement.appendChild(header); 115 | 116 | const inputContainer = document.createElement('div'); 117 | inputContainer.style.display = 'flex'; 118 | inputContainer.style.justifyContent = 'center'; 119 | 120 | const inputBox = document.createElement('input'); 121 | inputBox.type = 'text'; 122 | inputBox.style.color = 'black'; 123 | inputBox.placeholder = 'Quiz Id here...'; 124 | inputBox.style.width = '27.8vw'; 125 | inputBox.style.height = '1.5vw'; 126 | inputBox.style.margin = '0vw'; 127 | inputBox.style.padding = '0vw'; 128 | inputBox.style.padding = '0'; 129 | inputBox.style.border = '.1vw solid black'; 130 | inputBox.style.borderRadius = '1vw'; 131 | inputBox.style.outline = 'none'; 132 | inputBox.style.textAlign = 'center'; 133 | inputBox.style.fontSize = '1.15vw'; 134 | 135 | 136 | inputContainer.appendChild(inputBox); 137 | uiElement.appendChild(inputContainer); 138 | 139 | const header2 = document.createElement('h2'); 140 | header2.textContent = 'POINTS PER QUESTION'; 141 | header2.style.display = 'block'; 142 | header2.style.margin = '1vw'; 143 | header2.style.textAlign = 'center'; 144 | header2.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 145 | header2.style.fontSize = '2vw'; 146 | header2.style.color = 'white'; 147 | header2.style.textShadow = ` 148 | -1px -1px 0 rgb(47, 47, 47), 149 | 1px -1px 0 rgb(47, 47, 47), 150 | -1px 1px 0 rgb(47, 47, 47), 151 | 1px 1px 0 rgb(47, 47, 47) 152 | `; 153 | 154 | uiElement.appendChild(header2); 155 | 156 | const sliderContainer = document.createElement('div'); 157 | sliderContainer.style.width = '80%'; 158 | sliderContainer.style.margin = '1vw auto'; 159 | sliderContainer.style.display = 'flex'; 160 | sliderContainer.style.alignItems = 'center'; 161 | sliderContainer.style.justifyContent = 'center'; 162 | 163 | const pointsLabel = document.createElement('span'); 164 | pointsLabel.textContent = 'Points per Question: 950'; 165 | pointsLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 166 | pointsLabel.style.fontSize = '1.5vw'; 167 | pointsLabel.style.margin = '1vw'; 168 | pointsLabel.style.marginLeft = '1vw'; 169 | pointsLabel.style.marginRight = '1vw'; 170 | pointsLabel.style.color = 'white'; 171 | sliderContainer.appendChild(pointsLabel); 172 | 173 | const pointsSlider = document.createElement('input'); 174 | pointsSlider.type = 'range'; 175 | pointsSlider.min = '500'; 176 | pointsSlider.max = '1000'; 177 | pointsSlider.value = '950'; 178 | pointsSlider.style.width = '70%'; 179 | pointsSlider.style.marginLeft = '1vw'; 180 | pointsSlider.style.marginRight = '1vw'; 181 | 182 | 183 | pointsSlider.style.border = 'none'; 184 | pointsSlider.style.outline = 'none'; 185 | pointsSlider.style.cursor = 'ew-resize'; 186 | pointsSlider.className = 'custom-slider'; 187 | 188 | 189 | sliderContainer.appendChild(pointsSlider); 190 | 191 | 192 | uiElement.appendChild(sliderContainer); 193 | 194 | pointsSlider.addEventListener('input', () => { 195 | const points = +pointsSlider.value; 196 | PPT = points; 197 | pointsLabel.textContent = 'Points per Question: ' + points; 198 | }); 199 | 200 | const header3 = document.createElement('h2'); 201 | header3.textContent = 'ANSWERING'; 202 | header3.style.display = 'block'; 203 | header3.style.margin = '1vw'; 204 | header3.style.textAlign = 'center'; 205 | header3.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 206 | header3.style.fontSize = '2vw'; 207 | header3.style.color = 'white'; 208 | header3.style.textShadow = ` 209 | -1px -1px 0 rgb(47, 47, 47), 210 | 1px -1px 0 rgb(47, 47, 47), 211 | -1px 1px 0 rgb(47, 47, 47), 212 | 1px 1px 0 rgb(47, 47, 47) 213 | `; 214 | 215 | uiElement.appendChild(header3); 216 | 217 | const autoAnswerSwitchContainer = document.createElement('div'); 218 | autoAnswerSwitchContainer.className = 'switch-container'; 219 | autoAnswerSwitchContainer.style.display = 'flex'; 220 | autoAnswerSwitchContainer.style.alignItems = 'center'; 221 | autoAnswerSwitchContainer.style.justifyContent = 'center'; 222 | uiElement.appendChild(autoAnswerSwitchContainer); 223 | 224 | const autoAnswerLabel = document.createElement('span'); 225 | autoAnswerLabel.textContent = 'Auto Answer'; 226 | autoAnswerLabel.className = 'switch-label'; 227 | autoAnswerLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 228 | autoAnswerLabel.style.fontSize = '1.5vw'; 229 | autoAnswerLabel.style.color = 'white'; 230 | autoAnswerLabel.style.margin = '2.5vw' 231 | autoAnswerSwitchContainer.appendChild(autoAnswerLabel); 232 | 233 | const autoAnswerSwitch = document.createElement('label'); 234 | autoAnswerSwitch.className = 'switch'; 235 | autoAnswerSwitchContainer.appendChild(autoAnswerSwitch); 236 | 237 | const autoAnswerInput = document.createElement('input'); 238 | autoAnswerInput.type = 'checkbox'; 239 | autoAnswerInput.addEventListener('change', function() { 240 | autoAnswer = this.checked; 241 | info.ILSetQuestion = info.questionNum 242 | }); 243 | autoAnswerSwitch.appendChild(autoAnswerInput); 244 | 245 | const autoAnswerSlider = document.createElement('span'); 246 | autoAnswerSlider.className = 'slider'; 247 | autoAnswerSwitch.appendChild(autoAnswerSlider); 248 | 249 | const showAnswersSwitchContainer = document.createElement('div'); 250 | showAnswersSwitchContainer.className = 'switch-container'; 251 | showAnswersSwitchContainer.style.display = 'flex'; 252 | showAnswersSwitchContainer.style.alignItems = 'center'; 253 | showAnswersSwitchContainer.style.justifyContent = 'center'; 254 | uiElement.appendChild(showAnswersSwitchContainer); 255 | 256 | const showAnswersLabel = document.createElement('span'); 257 | showAnswersLabel.textContent = 'Show Answers'; 258 | showAnswersLabel.className = 'switch-label'; 259 | showAnswersLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 260 | showAnswersLabel.style.fontSize = '1.5vw'; 261 | showAnswersLabel.style.color = 'white'; 262 | showAnswersLabel.style.margin = '2.5vw' 263 | showAnswersSwitchContainer.appendChild(showAnswersLabel); 264 | 265 | const showAnswersSwitch = document.createElement('label'); 266 | showAnswersSwitch.className = 'switch'; 267 | showAnswersSwitchContainer.appendChild(showAnswersSwitch); 268 | 269 | const showAnswersInput = document.createElement('input'); 270 | showAnswersInput.type = 'checkbox'; 271 | showAnswersInput.addEventListener('change', function() { 272 | showAnswers = this.checked; 273 | }); 274 | showAnswersSwitch.appendChild(showAnswersInput); 275 | 276 | const showAnswersSlider = document.createElement('span'); 277 | showAnswersSlider.className = 'slider'; 278 | showAnswersSwitch.appendChild(showAnswersSlider); 279 | 280 | 281 | const style = document.createElement('style'); 282 | style.textContent = ` 283 | .custom-slider { 284 | background: white 285 | border: none; 286 | outline: none; 287 | cursor: ew-resize; 288 | appearance: none; /* Remove default appearance */ 289 | height: 0; /* Set the height to match the thumb height */ 290 | } 291 | 292 | .custom-slider::-webkit-slider-thumb { 293 | appearance: none; /* Remove default appearance */ 294 | width: 1.75vw; /* Set width of the slider handle */ 295 | height: 1.75vw; /* Set height of the slider handle */ 296 | background-color: rgb(47, 47, 47); /* Set handle color to dark gray */ 297 | border-radius: 50%; /* Create a circle for the handle */ 298 | cursor: ew-resize; /* Horizontal resize cursor */ 299 | margin-top: -0.5vw; /* Adjust margin-top to vertically center the thumb */ 300 | } 301 | 302 | .custom-slider::-webkit-slider-runnable-track { 303 | width: 100%; /* Set track width to 100% */ 304 | height: 0.75vw; /* Set track height to match the thumb height */ 305 | background-color: white; /* Set track color to white */ 306 | cursor: ew-resize; /* Horizontal resize cursor */ 307 | border-radius: 1vw; /* Set rounded corners for the track */ 308 | background: linear-gradient(to right, red, yellow, limegreen); /* Gradient from red to yellow to green */ 309 | } 310 | 311 | 312 | 313 | :root { 314 | --switch-width: 5.9vw; 315 | --switch-height: 3.3vw; 316 | --slider-size: 2.5vw; 317 | --slider-thumb-size: 1.3vw; 318 | } 319 | 320 | .switch { 321 | position: relative; 322 | display: inline-block; 323 | width: var(--switch-width); 324 | height: var(--switch-height); 325 | margin: 2.5vw; 326 | } 327 | 328 | .switch input { 329 | opacity: 0; 330 | width: 0; 331 | height: 0; 332 | } 333 | 334 | .slider { 335 | position: absolute; 336 | cursor: pointer; 337 | top: 0; 338 | left: 0; 339 | right: 0; 340 | bottom: 0; 341 | background-color: red; 342 | transition: 0.8s; 343 | border-radius: .5vw 344 | } 345 | 346 | .slider:before { 347 | position: absolute; 348 | content: ""; 349 | height: var(--slider-size); 350 | width: var(--slider-size); 351 | left: calc(var(--slider-thumb-size) / 3); 352 | bottom: calc(var(--slider-thumb-size) / 3); 353 | background-color: rgb(43, 43, 43); 354 | transition: 0.8s; 355 | border-radius: .5vw 356 | } 357 | 358 | input:checked + .slider { 359 | background-color: green; 360 | } 361 | 362 | input:focus + .slider { 363 | box-shadow: 0 0 1px green; 364 | } 365 | 366 | input:checked + .slider:before { 367 | transform: translateX(calc(var(--slider-size))); 368 | } 369 | 370 | `; 371 | document.head.appendChild(style); 372 | 373 | const header4 = document.createElement('h2'); 374 | header4.textContent = 'INFO'; 375 | header4.style.display = 'block'; 376 | header4.style.margin = '1vw'; 377 | header4.style.textAlign = 'center'; 378 | header4.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 379 | header4.style.fontSize = '2vw'; 380 | header4.style.color = 'white'; 381 | header4.style.textShadow = ` 382 | -1px -1px 0 rgb(47, 47, 47), 383 | 1px -1px 0 rgb(47, 47, 47), 384 | -1px 1px 0 rgb(47, 47, 47), 385 | 1px 1px 0 rgb(47, 47, 47) 386 | `; 387 | 388 | uiElement.appendChild(header4) 389 | 390 | const questionsLabel = document.createElement('span'); 391 | questionsLabel.textContent = 'Question 0 / 0'; 392 | questionsLabel.style.display = 'block'; 393 | questionsLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 394 | questionsLabel.style.fontSize = '1.5vw'; 395 | questionsLabel.style.textAlign = 'center'; 396 | questionsLabel.style.margin = '1vw'; 397 | questionsLabel.style.marginLeft = '1vw'; 398 | questionsLabel.style.marginRight = '1vw'; 399 | questionsLabel.style.color = 'white'; 400 | uiElement.appendChild(questionsLabel); 401 | 402 | const inputLagLabel = document.createElement('span'); 403 | inputLagLabel.textContent = 'Input lag : 125 ms'; 404 | inputLagLabel.style.display = 'block'; 405 | inputLagLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 406 | inputLagLabel.style.fontSize = '1.5vw'; 407 | inputLagLabel.style.textAlign = 'center'; 408 | inputLagLabel.style.margin = '1vw'; 409 | inputLagLabel.style.marginLeft = '1vw'; 410 | inputLagLabel.style.marginRight = '1vw'; 411 | inputLagLabel.style.color = 'white'; 412 | uiElement.appendChild(inputLagLabel); 413 | 414 | const versionLabel = document.createElement('h1'); 415 | versionLabel.textContent = 'KaHack! V'+Version; 416 | versionLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 417 | versionLabel.style.fontSize = '2.5vw'; 418 | versionLabel.style.display = 'block'; 419 | versionLabel.style.textAlign = 'center'; 420 | versionLabel.style.marginTop = '3.5vw'; 421 | versionLabel.style.marginLeft = '1vw'; 422 | versionLabel.style.marginRight = '1vw'; 423 | versionLabel.style.color = 'white'; 424 | uiElement.appendChild(versionLabel); 425 | 426 | const githubContainer = document.createElement('div'); 427 | githubContainer.style.textAlign = 'center'; 428 | githubContainer.style.marginTop = '1vw'; 429 | 430 | const githubLabel = document.createElement('span'); 431 | githubLabel.textContent = 'GitHub: '; 432 | githubLabel.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 433 | githubLabel.style.fontSize = '1.5vw'; 434 | githubLabel.style.margin = '0 1vw'; 435 | githubLabel.style.color = 'white'; 436 | githubContainer.appendChild(githubLabel); 437 | 438 | const githubUrl = document.createElement('a'); 439 | githubUrl.textContent = 'jokeri2222'; 440 | githubUrl.href = 'https://github.com/jokeri2222'; 441 | githubUrl.target = '_blank'; 442 | githubUrl.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 443 | githubUrl.style.fontSize = '1.5vw'; 444 | githubUrl.style.margin = '0 1vw'; 445 | githubUrl.style.color = 'white'; 446 | githubContainer.appendChild(githubUrl); 447 | 448 | const githubUrl2 = document.createElement('a'); 449 | githubUrl2.textContent = 'Epic0001'; 450 | githubUrl2.href = 'https://github.com/Epic0001'; 451 | githubUrl2.target = '_blank'; 452 | githubUrl2.style.fontFamily = '"Montserrat", "Noto Sans Arabic", "Helvetica Neue", Helvetica, Arial, sans-serif;'; 453 | githubUrl2.style.fontSize = '1.5vw'; 454 | githubUrl2.style.margin = '0 1vw'; 455 | githubUrl2.style.color = 'white'; 456 | githubContainer.appendChild(githubUrl2); 457 | 458 | uiElement.appendChild(githubContainer); 459 | 460 | closeButton.addEventListener('click', () => { 461 | document.body.removeChild(uiElement); 462 | autoAnswer = false; 463 | showAnswers = false; 464 | }); 465 | 466 | let isMinimized = false; 467 | 468 | minimizeButton.addEventListener('click', () => { 469 | isMinimized = !isMinimized; 470 | 471 | if (isMinimized) { 472 | header.style.display = 'none'; 473 | header2.style.display = 'none'; 474 | header3.style.display = 'none'; 475 | header4.style.display = 'none'; 476 | inputContainer.style.display = 'none'; 477 | questionsLabel.style.display = 'none'; 478 | versionLabel.style.display = 'none'; 479 | inputLagLabel.style.display='none'; 480 | githubContainer.style.display = 'none'; 481 | 482 | sliderContainer.style.display = 'none'; 483 | autoAnswerSwitchContainer.style.display = 'none'; 484 | showAnswersSwitchContainer.style.display = 'none'; 485 | 486 | uiElement.style.height = '2.5vw'; 487 | handle.style.height = '100%'; 488 | closeButton.style.height = '100%'; 489 | minimizeButton.style.height = '100%'; 490 | } else { 491 | header.style.display = 'block'; 492 | header2.style.display = 'block'; 493 | header3.style.display = 'block'; 494 | header4.style.display = 'block'; 495 | inputContainer.style.display = 'flex'; 496 | questionsLabel.style.display = 'block'; 497 | versionLabel.style.display = 'block'; 498 | inputLagLabel.style.display='block'; 499 | githubContainer.style.display = 'block'; 500 | 501 | handle.style.height = '2.5vw'; 502 | uiElement.style.height = 'auto'; 503 | closeButton.style.height = '2.5vw'; 504 | minimizeButton.style.height = '2.5vw'; 505 | 506 | sliderContainer.style.display = 'flex'; 507 | autoAnswerSwitchContainer.style.display = 'flex'; 508 | showAnswersSwitchContainer.style.display = 'flex'; 509 | } 510 | }); 511 | 512 | function parseQuestions(questionsJson){ 513 | let questions = [] 514 | questionsJson.forEach(function (question){ 515 | let q = {type:question.type, time:question.time} 516 | if (['quiz', 'multiple_select_quiz'].includes(question.type)){ 517 | var i=0 518 | q.answers = [] 519 | q.incorrectAnswers = [] 520 | question.choices.forEach(function(choise){ 521 | if (choise.correct) { 522 | q.answers.push(i) 523 | } 524 | else{ 525 | q.incorrectAnswers.push(i) 526 | } 527 | i++ 528 | }) 529 | } 530 | if (question.type == 'open_ended') 531 | { 532 | q.answers = [] 533 | question.choices.forEach(function(choise){ 534 | q.answers.push(choise.answer) 535 | }) 536 | } 537 | questions.push(q) 538 | }) 539 | return questions 540 | } 541 | 542 | function handleInputChange() { 543 | const quizID = inputBox.value; 544 | const url = 'https://kahoot.it/rest/kahoots/' + quizID; 545 | 546 | if (quizID != "") { 547 | fetch(url) 548 | .then(response => { 549 | if (!response.ok) { 550 | throw new Error(''); 551 | } 552 | return response.json(); 553 | }) 554 | .then(data => { 555 | inputBox.style.backgroundColor = 'green' 556 | 557 | questions=parseQuestions(data.questions) 558 | info.numQuestions=questions.length 559 | }) 560 | .catch(error => { 561 | inputBox.style.backgroundColor = 'red'; 562 | 563 | info.numQuestions = 0 564 | }); 565 | } else { 566 | inputBox.style.backgroundColor = 'white'; 567 | info.numQuestions = 0 568 | 569 | } 570 | } 571 | 572 | inputBox.addEventListener('input', handleInputChange); 573 | 574 | document.body.appendChild(uiElement); 575 | 576 | let isDragging = false; 577 | let offsetX, offsetY; 578 | 579 | handle.addEventListener('mousedown', (e) => { 580 | isDragging = true; 581 | offsetX = e.clientX - uiElement.getBoundingClientRect().left; 582 | offsetY = e.clientY - uiElement.getBoundingClientRect().top; 583 | }); 584 | 585 | document.addEventListener('mousemove', (e) => { 586 | if (isDragging) { 587 | const x = e.clientX - offsetX; 588 | const y = e.clientY - offsetY; 589 | 590 | uiElement.style.left = x + 'px'; 591 | uiElement.style.top = y + 'px'; 592 | } 593 | }); 594 | 595 | document.addEventListener('mouseup', () => { 596 | isDragging = false; 597 | }); 598 | 599 | 600 | function onQuestionStart(){ 601 | console.log(inputLag) 602 | var question = questions[info.questionNum] 603 | if (showAnswers){ 604 | highlightAnswers(question) 605 | } 606 | if (autoAnswer){ 607 | answer(question, (question.time - question.time / (500/(PPT-500))) - inputLag) 608 | } 609 | } 610 | 611 | function highlightAnswers(question){ 612 | question.answers.forEach(function (answer) { 613 | setTimeout(function() { 614 | FindByAttributeValue("data-functional-selector", 'answer-'+answer, "button").style.backgroundColor = 'rgb(0, 255, 0)' 615 | }, 0) 616 | }) 617 | question.incorrectAnswers.forEach(function (answer) { 618 | setTimeout(function() { 619 | FindByAttributeValue("data-functional-selector", 'answer-'+answer, "button").style.backgroundColor = 'rgb(255, 0, 0)' 620 | }, 0) 621 | }) 622 | } 623 | 624 | function answer(question, time) { 625 | Answered_PPT = PPT 626 | 627 | var delay = 0 628 | if (question.type == 'multiple_select_quiz') delay = 60 629 | setTimeout(function() { 630 | if (question.type == 'quiz') { 631 | const key=(+question.answers[0]+1).toString(); 632 | const event = new KeyboardEvent('keydown', { key }); 633 | window.dispatchEvent(event); 634 | } 635 | if (question.type == 'multiple_select_quiz') { 636 | question.answers.forEach(function (answer) { 637 | setTimeout(function() { 638 | const key=(+answer+1).toString(); 639 | const event = new KeyboardEvent('keydown', { key }); 640 | window.dispatchEvent(event); 641 | }, 0) 642 | }) 643 | setTimeout(function() { 644 | FindByAttributeValue("data-functional-selector", 'multi-select-submit-button', "button").click() 645 | }, 0) 646 | } 647 | }, time - delay) 648 | } 649 | 650 | let isHidden = false; 651 | document.addEventListener('keydown', (event)=> { 652 | if (event.key == "h" && event.altKey) 653 | { 654 | isHidden = !isHidden 655 | } 656 | 657 | if (event.key == "x" && event.altKey){ 658 | document.body.removeChild(uiElement); 659 | autoAnswer = false; 660 | showAnswers = false; 661 | } 662 | 663 | if (isHidden) 664 | { 665 | uiElement.style.display = 'none' 666 | } 667 | else 668 | { 669 | uiElement.style.display = 'block' 670 | } 671 | }) 672 | 673 | setInterval(function () { 674 | var textElement = FindByAttributeValue("data-functional-selector", "question-index-counter", "div") 675 | if (textElement){ 676 | 677 | info.questionNum = +textElement.textContent - 1 678 | } 679 | if (FindByAttributeValue("data-functional-selector", 'answer-0', "button") && info.lastAnsweredQuestion != info.questionNum) 680 | { 681 | info.lastAnsweredQuestion = info.questionNun 682 | onQuestionStart() 683 | } 684 | if (autoAnswer){ 685 | if (info.ILSetQuestion != info.questionNum){ 686 | var ppt = Answered_PPT 687 | if (ppt > 987) ppt = 1000 688 | var incrementElement = FindByAttributeValue("data-functional-selector", "score-increment", "span") 689 | if (incrementElement){ 690 | info.ILSetQuestion = info.questionNum 691 | var increment = +incrementElement.textContent.split(" ")[1] 692 | if (increment != 0){ 693 | inputLag += (ppt-increment)*15 694 | if (inputLag < 0) { 695 | inputLag -= (ppt-increment)*15 696 | inputLag += (ppt-increment/2)*15 697 | } 698 | inputLag = Math.round(inputLag) 699 | } 700 | } 701 | } 702 | } 703 | questionsLabel.textContent = 'Question '+(info.questionNum+1)+' / '+info.numQuestions; 704 | inputLagLabel.textContent = 'Input lag : '+inputLag+' ms'; 705 | }, 1) 706 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 jokeri2222 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # KaHack! 3 | 4 | 5 | ## Description 6 | This is a Kahoot hack AKA a cheat made for Chrome browser and Tampermonkey. Made in vanilla js and works on most browsers. 7 | 8 | ## Instructions 9 | 1. Open the KaHack!.user.js 10 | 2. Click raw to install this script to Tampermonkey or copy-paste it on the console. Ctrl+Shift+i opens the developer tab and there you can find the console. Paste the code the code there and press enter to run it. 11 | 3. Type in the quiz ID. You should see it on the host's screen. If the quiz ID box is still red after typing in the right quiz ID that means the Kahoot is private and this cannot be used with it. 12 | ![image](https://github.com/jokeri2222/KaHack/assets/110989057/bcb3e365-b51e-42fd-9b44-bab8bcfeeda4) 13 | 14 | 4. Have happy cheating :). Also here is another tip don't put the points slider over 987 it will cause the points to be 1000 automatically because that's how Kahoot calculates the points. Try to make the points as non-suspicious as possible. 15 | 16 | ## Features 17 | The latest version includes Auto Answer, Show Answers, and Answer Speed. Only quiz and multi-select answers are supported. Type answers and everything else are not supported yet. By pressing Alt+h on your keyboard it will hide the menu and by pressing Alt+x it will terminate the menu. You can drag the menu from the top bar and minimize and close if you want. Closing the cheat will end the script and will not auto-answer or show the answers. You can use this as a panic button. Or just do Alt+x. 18 | 19 | ![image](https://github.com/jokeri2222/KaHack/assets/110989057/5229a862-ca1e-41c7-af01-61a6ae30f8da) 20 | 21 | 22 | ## Credits 23 | Huge thanks to [Epic0001](https://github.com/Epic0001) for bug testing and general bug fixing. Without his help, this project would be way outdated and not fully working piece of cheatware. 24 | 25 | ## Donations 26 | The cheat is free to use but if you respect me and my work and you want to support me in making these hacks and updating them. Here is a way to donate to me and it really helps me. Thank you! 27 | 28 | 29 | 30 | 31 | [![image](https://github.com/jokeri2222/KaHack/assets/110989057/fb87a570-186d-4f37-9065-6eb1907e33ae)](https://www.paypal.com/donate/?hosted_button_id=DUXNZVDCDAQ8S) 32 | --------------------------------------------------------------------------------