- // ==UserScript==
- // @name quizizz hax - lldvee
- // @namespace Violentmonkey Scripts
- // @match *://*.quizizz.com/*
- // @grant none
- // @version 1.7
- // @author lldvee#5852 / w h e e z er
- // @run-at document-start
- // @description final ver. bye bye world
- // ==/UserScript==
-
- // cringe decryption stuff
-
- let OffsetAdder = {
- add(e, t, a, n, i) {
- function _i(e) {
- let res =
- !!isNumber(e) &&
- !(e >= 55296 && e <= 56319) &&
- !(e >= 56320 && e <= 57343);
- return res;
- }
-
- function fi(e, t, a, n) {
- return n(e, a % 2 === 0 ? t : -t);
- }
-
- switch (i) {
- case 2:
- return _i(e) ? fi(e, t, a, n) : e;
- case 1:
- default:
- return fi(e, t, a, n);
- }
- }
- };
-
- let defaults = {
- stringModifier: function (e, t, a) {
- return e;
- },
- keySumExtractor: function (e, t) {
- return e.charCodeAt(0);
- },
- offsetAdder: function (e, t, a, n) {
- return n(e, t);
- },
- miscDataForLogging: "",
- obfsVersionExtractor: function (e) {
- if (typeof e == "string" && e[e.length - 1]) {
- let t = parseInt(e[e.length - 1], 10);
- if (!isNaN(t)) {
- return t;
- }
- }
- return null;
- }
- };
-
- let firstStage = {
- offsetAdder: OffsetAdder.add,
- stringModifier: function () {
- var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "",
- t =
- (arguments.length > 1 && arguments[1],
- arguments.length > 2 && arguments[2],
- arguments.length > 3 && arguments[3],
- e.charCodeAt(e.length - 2) - 33);
- return e.slice(t, -2);
- },
- obfsVersionExtractor: function extractVersion(e) {
- if (typeof e == "string" && e[e.length - 1]) {
- let t = parseInt(e[e.length - 1], 10);
- if (!isNaN(t)) {
- return t;
- }
- }
- return null;
- },
- keySumExtractor: function (e, t) {
- return e.charCodeAt(0) + e.charCodeAt(e.length - 1);
- },
- miscDataForLogging: ""
- };
-
- function sliceEncrypted() {
- let e =
- arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
- let t =
- (arguments.length > 1 && arguments[1],
- arguments.length > 2 && arguments[2],
- e.charCodeAt(e.length - 2) - 33);
- let a = e.slice(0, e.charCodeAt(e.length - 2) - 33);
- return xi(a, "quizziz.com");
- }
-
- function ki(e, t) {
- let si = 0;
- let oi = 65535;
- var a = e + t;
- return a > oi ? si + (a - oi) - 1 : a < si ? oi - (si - a) + 1 : a;
- }
-
- function xi(encryptedData, gifunc, a) {
- a = a || defaults;
- let n = a.obfsVersionExtractor(encryptedData);
- let i = "";
- let r = typeof gifunc == "function" ? gifunc(encryptedData, a, n) : gifunc;
- let o = -a.keySumExtractor(r);
- let s = a.stringModifier(encryptedData, r, o, n);
-
- for (var c = 0; c < s.length; c++) {
- let l = s.charCodeAt(c);
- let d = a.offsetAdder(l, o, c, ki, n);
- i += String.fromCharCode(d);
- }
- return i;
- }
-
- function decrypt(encrypted) {
- return xi(encrypted, sliceEncrypted, firstStage);
- }
-
- // Helpers
- function getTag(value) {
- if (value == null) {
- return value === undefined ? "[object Undefined]" : "[object Null]";
- }
- return toString.call(value);
- }
-
- function isObjectLike(value) {
- return typeof value === "object" && value !== null;
- }
-
- function isNumber(value) {
- return (
- typeof value === "number" ||
- (isObjectLike(value) && getTag(value) == "[object Number]")
- );
- }
-
- // end
-
- function AnswerParser() {
- function cleanText(input) {
- return input.replace(/<\/?[^>]+(>|$)/g, "");
- }
-
- function parseMCQ(q) {
- let ansIdx = decrypt(q.structure.answer)
- let optAns = q.structure.options[ansIdx]
- let ans = optAns.type == 'image' ? optAns.media[0].url : cleanText(optAns.text)
- return {
- question: cleanText(q.structure.query.text),
- answers: ans
- }
- }
-
- function parseBLANK(q) {
- let ans = []
- for (let opt of q.structure.options) {
- ans.push(opt.text)
- }
- return {
- question: cleanText(q.structure.query.text),
- answers: ans
- }
- }
-
- function parseMSQ(q) {
- let ans = []
- let ansIdxs = JSON.parse(decrypt(q.structure.answer))
-
- for (let ansIdx of ansIdxs) {
- ans.push(cleanText(q.structure.options[ansIdx].text))
-
- }
-
- return {
- question: cleanText(q.structure.query.text),
- answers: ans
- }
- }
-
- function parseOther(q) {
- return {
- question: "Not supported",
- answers: "Not supported"
- }
- }
-
- this.parse = function (data) {
- let parsedAnswers = []
- for (let key in data.questions) {
- let currQuestion = data.questions[key]
- if (currQuestion.type == "BLANK") {
- parsedAnswers.push(parseBLANK(currQuestion))
- } else if (currQuestion.type == "MCQ") {
- parsedAnswers.push(parseMCQ(currQuestion))
- } else if (currQuestion.type == "MSQ") {
- parsedAnswers.push(parseMSQ(currQuestion))
- } else {
- parsedAnswers.push(parseOther(currQuestion))
- }
- }
- return parsedAnswers
- }
- }
-
- function printAnswers(ansdata) {
- for (data of ansdata) {
- let m = false;
- let f = data.answers;
- if (Array.isArray(data.answers)) {
- if (data.answers.length > 1) {
- m = true
- f = data.answers.map((v) => `[ ${v} ]`).join(" OR ")
- }
- else {
- f = data.answers[0]
- }
- }
- console.log(
- `Question: ${data.question}
- ${m ? "Multiple" : ""} Answers: ${f}`)
- }
- }
-
- function getQuizInfo() {
- let ctx = JSON.parse(localStorage.getItem("previousContext"))
- let roomHash = decrypt(ctx.game.roomHash.slice(9))
- let type = ctx.game.gameMode
- return {
- roomHash,
- type
- }
- }
-
- function printServerNotice(json) {
- if (json.serverNotice) {
- console.log("quizizz hax: ", json.serverNotice.trim())
- }
- }
-
- async function getQuizData(quizInfo) {
- const reqUrl = `https://vfgrm205b8.execute-api.us-east-1.amazonaws.com/bazinga/v3proxy?rh=${quizInfo.roomHash}&type=${quizInfo.type}`
- let response = await fetch(reqUrl)
- if (response.status == 200) {
- return response.json()
- }
- let json = await response.json()
- console.error(`quizizz haxx: Error retrieving answers: [${json.error}]`)
- null.l0l()
- }
-
- async function start() {
- console.log('quizizzz haxx - retrieving answers')
- let ansParser = new AnswerParser()
- let quizInfo = getQuizInfo()
- let quizData = await getQuizData(quizInfo)
- let parsedAnswers = ansParser.parse(quizData)
- console.clear()
- printServerNotice(quizData)
- printAnswers(parsedAnswers)
- console.log("quizizz haxx v3 - by asgar & llvdee#5852");
- }
-
- function _hook(f, p, r, m) {
- console.log('hooking ', f)
- m = m ? m : globalThis
- let old = p ? m['__proto__'][f] : m[f]
- if (p) {
- m['__proto__'][f] = r(old)
- } else {
- m[f] = r(old)
- }
- }
-
- // function hookFetchAfter(f) {
- // _hook('fetch', false, function(old) {
- // return function() {
- // return new Promise((resolve, reject) => {
- // let origCall = old.apply(this, arguments)
- // origCall
- // .then(res => f({arguments, response: res.clone()}))
- // .then(newRes => resolve(newRes))
- // .catch(err => reject(err))
- // })
- // }
- // })
- // }
-
- // _hook('setItem', true, function (old) {
- // return function() {
- // let orig = old.apply(this, arguments)
- // let e = new CustomEvent("storageUpdated", {detail: {key: arguments[0], value: arguments[1]}})
- // window.dispatchEvent(e)
- // return orig
- // }
- // }, localStorage)
-
- _hook('pushState', false, function(old) {
- return function() {
- let orig = old.apply(this, arguments)
- let e = new Event("updateUrl")
- window.dispatchEvent(e)
- return orig
- }
- }, history)
-
- window.addEventListener('updateUrl', function(e) {
- if (window.location.href.includes('join/game')) {
- start()
- }
- });
-
- // if you're going to rebrand the script as yours atleast improve it you fucks
-
- console.clear()
- console.log("quizizz haxx v3 - by asgar & lldvee#5852");