您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Remove all bots from a kahoot game.
当前为
// ==UserScript== // @name Kahoot AntiBot // @namespace http://tampermonkey.net/ // @version 2.5.7 // @description Remove all bots from a kahoot game. // @author theusaf // @match *://play.kahoot.it/* // @grant none // @run-at document-start // ==/UserScript== if(window.fireLoaded){ throw "[ANTIBOT] - page is loaded"; } //window.stop(); //stop loading and save data from the page. if(window.localStorage.extraCheck){ console.log("[ANTIBOT] - Detected PIN Checker"); } document.write(""); window.url = window.location.href; window.page = new XMLHttpRequest(); window.page.open("GET",window.url); window.page.send(); window.page.onload = ()=>{ let scriptURL = window.page.response.match(/<\/script><script\ .*?vendors.*?><\/script>/mg)[0].substr(9).split("src=\"")[1].split("\"")[0]; let script2 = window.page.response.match(/<\/script><script src=\"\/v2\/assets\/js\/main.*?(?=\")/mg)[0].substr(22); let originalPage = window.page.response.replace(/<\/script><script\ .*?vendors.*?><\/script>/mg,"</script>"); originalPage = originalPage.replace(/<\/script><script src=\"\/v2\/assets\/js\/main.*?(?=\")/mg,"</script><script src=\"data:text/javascript,"); let script = new XMLHttpRequest(); script.open("GET","https://play.kahoot.it/"+scriptURL); script.send(); script.onload = ()=>{ let patchedScript =script.response.replace(".onMessage=function(e,n){",".onMessage=function(e,n){window.globalMessageListener(t,n);"); const code = /*window.setupAntibot = */ ()=>{ const percent = 0.6; var waterMark = document.createElement("p"); waterMark.innerText = "v2.5.7 @theusaf"; waterMark.style = "position: fixed; bottom: 100px; right:100px; font-size: 1em"; document.body.append(waterMark); window.isUsingNamerator = false; window.cachedUsernames = []; window.confirmedPlayers = []; window.cachedData = {}; window.loggedPlayers = {}; var messageId = 0; var clientId = null; var pin = null; function similarity(s1, s2) { if(!s2){ return 0; } if(s1){ if(!isNaN(s2) && !isNaN(s1) && s1.length == s2.length){ return 1; } } if(window.isUsingNamerator){ let caps = s2.length - s2.replace(/[A-Z]/g, '').length; if(caps !== 2){ /*has less than 2 or more than 2 capitals*/ return -1; } if (s2.substr(0,1).replace(/[A-Z]/g,'').length === 1){/*first char is not a capital*/ return -1; } if (s2.substr(1,2).replace(/[A-Z]/g,'').length != 2){/*next few char have capitals*/ return -1; } if(s2.substr(s2.length -2,2).replace(/[A-Z]/g,'').length !== 2){ /*last few char have acapital*/ return -1; } if(s2.replace(/[a-z]/ig,'').length > 0){ /*hasnon-letter chars*/ return -1; } } if(!s1){ return; } s1 = s1.toLowerCase(); s2 = s2.toLowerCase(); var longer = s1; var shorter = s2; if (s1.length < s2.length) { longer = s2; shorter = s1; } var longerLength = longer.length; if (longerLength == 0) { return 1.0; } return (longerLength - editDistance(longer, shorter)) /parseFloat(longerLength); } function editDistance(s1, s2) { s1 = s1.toLowerCase(); s2 = s2.toLowerCase(); var costs = new Array(); for (var i = 0; i <= s1.length; i++) { var lastValue = i; for (var j = 0; j <= s2.length; j++) { if (i == 0){ costs[j] = j; } else { if (j > 0) { var newValue = costs[j - 1]; if (s1.charAt(i - 1) != s2.charAt(j - 1)){ newValue = Math.min(Math.min(newValue,lastValue),costs[j]) + 1; } costs[j - 1] = lastValue; lastValue = newValue; } } } if (i > 0){ costs[s2.length] = lastValue; } } return costs[s2.length]; } function setup(){ var launch_button =document.querySelectorAll("[data-functional-selector=\"launch-button\"]")[0]; if(launch_button){ console.warn("[ANTIBOT] - launch button found!"); }else{ setTimeout(setup,1000); } } setup(); function createKickPacket(id){ messageId++; return [{ channel: "/service/player", clientId: clientId, id: String(Number(messageId)), data: { cid: String(id), content: JSON.stringify({ kickCode: 1, quizType: "quiz" }), gameid: pin, host: "play.kahoot.it", id: 10, type: "message" }, ext: {} }]; } function determineEvil(player,socket){ // Disabled in V 2.5.5 /*if(window.loggedPlayers[player.cid] === true){ let packet = createKickPacket(player.cid); socket.send(JSON.stringify(packet)); window.loggedPlayers[player.cid] = false; throw "[ANTIBOT] - Evil intentions discovered"; }*/ if(window.cachedUsernames.length == 0){ if(similarity(null,player.name) == -1){ var packet = createKickPacket(player.cid); socket.send(JSON.stringify(packet)); console.warn(`[ANTIBOT] - Bot ${player.name} has been banished`); throw "[ANTIBOT] - Bot banned. Dont add"; } window.cachedUsernames.push({name: player.name, id:player.cid, time: 10, banned: false}); window.loggedPlayers[player.cid] = true; }else{ var removed = false; for(var i in window.cachedUsernames){ if(window.confirmedPlayers.includes(window.cachedUsernames[i].name)){ continue; } if(similarity(window.cachedUsernames[i].name,player.name) == -1){ removed = true; var packet1 = createKickPacket(player.cid); socket.send(JSON.stringify(packet1)); console.warn(`[ANTIBOT] - Bot ${player.name} has been banished`); throw "[ANTIBOT] - Bot banned. Dont add"; } if(similarity(window.cachedUsernames[i].name,player.name) >= percent){ removed = true; let packet1 = createKickPacket(player.cid); socket.send(JSON.stringify(packet1)); if(!window.cachedUsernames[i].banned){ var packet2 =createKickPacket(window.cachedUsernames[i].id); window.cachedUsernames[i].banned = true; window.cachedUsernames[i].time = 10; socket.send(JSON.stringify(packet2)); } console.warn(`[ANTIBOT] - Bots ${player.name} and ${window.cachedUsernames[i].name} have been banished`); throw "[ANTIBOT] - Bot banned. Dont add"; } } if(!removed){ window.cachedUsernames.push({name: player.name,id: player.cid, time: 10, banned: false}); window.loggedPlayers[player.cid] = true; } } } function specialBotDetector(type,data,socket){ switch (type) { case 'joined': if(!window.cachedData[data.cid] && !isNaN(data.cid) && Object.keys(data).length <= 5){ //if the id has not been cached yet or is an invalid id, and they are not a bot :p window.cachedData[data.cid] = { tries: 0 }; }else{ /*if(window.loggedPlayers[data.cid] === false){ break; }*/ var packet = createKickPacket(data.cid); socket.send(JSON.stringify(packet)); console.warn(`[ANTIBOT] - Bot ${data.name} has been banished, clearly a bot from kahootsmash or something`); throw "[ANTIBOT] - Bot banned. Dont add"; } break; } } var timer = setInterval(function(){ for(let i in window.cachedUsernames){ if(window.cachedUsernames[i].time <= 0 && !window.cachedUsernames[i].banned && !window.confirmedPlayers.includes(window.cachedUsernames[i].name)){ window.confirmedPlayers.push(window.cachedUsernames[i].name); continue; } if(window.cachedUsernames[i].time <= -20){ window.cachedUsernames.splice(i,1); continue; } window.cachedUsernames[i].time--; } },1000); const TFATimer = setInterval(()=>{ for(let i in window.cachedData){ window.cachedData[i].tries = 0; } },10000); window.globalMessageListener = function(e,t){ window.e = e; /*console.log(e); from testing: e[.webSocket] is the websocket*/ var data = JSON.parse(t.data)[0]; /*console.log(data);*/ messageId = data.id ? data.id : messageId; /*if the message is the first message, which contains important clientid data*/ if(data.id == 1){ clientId = data.clientId; } try{ pin = pin ? pin : Number(document.querySelector("[data-functional-selector=\"game-pin\"]").innerHTML); if(Number(document.querySelector("[data-functional-selector=\"game-pin\"]").innerHTML) != pin){ pin = Number(document.querySelector("[data-functional-selector=\"game-pin\"]").innerHTML); } }catch(err){} /*if the message contains the pin*/ /*if(data.id == 3){ pin = data.data.gameid; }*/ /*if the message is a player join message*/ if(data.data ? data.data.type == "joined" : false){ console.warn("[ANTIBOT] - determining evil..."); determineEvil(data.data,e.webSocket); specialBotDetector(data.data.type,data.data,e.webSocket); } /*if the message is a player leave message*/ if(data.data ? data.data.type == "left" : false){ //Disabled in V2.5.5 /*if(window.loggedPlayers[data.data.cid] === false){ //if the antibot detected the evildoer //As of V 2.5.2, this has been abandoned since it doesn't actually work :p window.loggedPlayers[data.data.cid] = true; throw "[ANTIBOT] - Preventing removal of real player."; } window.loggedPlayers[data.data.cid] = false;*/ } if(data.data ? data.data.id == 50 : false){ window.cachedData[data.data.cid].tries++; if(window.cachedData[data.data.cid].tries > 3){ const kicker = createKickPacket(data.data.cid); e.webSocket.send(JSON.stringify(kicker)); const name = window.cachedUsernames.filter(o=>{return o.id == data.data.cid}).length ? window.cachedUsernames.filter(o=>{return o.id == data.data.cid})[0].name : "bot"; console.warn(`[ANTIBOT] - Bot ${name} banished. Seen spamming 2FA`); } } }; }; let mainScript = new XMLHttpRequest(); mainScript.open("GET","https://play.kahoot.it/"+script2); mainScript.send(); mainScript.onload = ()=>{ let sc = mainScript.response; sc = sc.replace("r.namerator","(()=>{console.log(r.namerator);window.isUsingNamerator = r.namerator;return r.namerator})()"); let changed = originalPage.split("</body>"); changed = `${changed[0]}<script>${patchedScript}</script><script>${sc}</script><script>try{(${window.localStorage.extraCheck})();}catch(err){}window.setupAntibot = ${code.toString()};window.fireLoaded = true;window.setupAntibot();</script></body>${changed[1]}`; console.log("[ANTIBOT] - loaded"); document.open(); document.write(changed); document.close(); //document.documentElement.innerHTML = changed; }; }; };