Kahoot AntiBot

Remove all bots from the player join screen. Simply start a kahoot game and watch as all bots get killed. Does not work on leaderboards currently.

目前为 2018-11-24 提交的版本。查看 最新版本

// ==UserScript==
// @name         Kahoot AntiBot
// @namespace    http://tampermonkey.net/
// @version      1.4.1.1
// @description  Remove all bots from the player join screen. Simply start a kahoot game and watch as all bots get killed. Does not work on leaderboards currently.
// @author       theusaf
// @match        *://play.kahoot.it/*
// @grant        none
// ==/UserScript==

window.similarity = function (s1, s2) {
  if(!isNaN(s2) && !isNaN(s1)){
    return 1;
  }
  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);
}

window.editDistance = function (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];
}

window.test_leaderboard = function (mu,observer){
  if(document.getElementsByTagName("iframe")[1].contentDocument.querySelectorAll("[data-functional-selector=\"highscores\"]").length > 0){
    if(document.getElementsByTagName("iframe")[1].contentDocument.querySelectorAll("[data-functional-selector=\"highscores\"]")[0].querySelectorAll("[data-functional-selector=\"player-name\"]").length == 0){
        return;
    }
  }else{
    return;
  }
  let players = document.getElementsByTagName("iframe")[1].contentDocument.querySelectorAll("[data-functional-selector=\"highscores\"]")[0].querySelectorAll("[data-functional-selector=\"player-name\"]");
  for(let i in players){
    let beaned = false;
    if(cachedLeaderboard.length == 0){
      cachedLeaderboard.push({element:players[i],text:players[i].innerText,clicked:false});
      continue;
    }
    for(let k in cachedLeaderboard){
      if(cachedLeaderboard[k].text == players[i].innerText){
        continue;
      }
      if(similarity(cachedLeaderboard[k].text,players[i].innerText) >= 0.60){
        if(confirmedPlayers.includes(players[i].innerText)){
          break;
        }
        players[i].click();
        beaned = true;
        if(!cachedLeaderboard[k].clicked){
          if(confirmedPlayers.includes(cachedUsernames[k].text)){
            break;
          }
          cachedLeaderboard[k].element.click();
          cachedLeaderboard[k].clicked = true;
        }
        break;
      }
    }
    if(cachedLeaderboard.filter(function(item){return item.text == players[i].innerText}).length === 0 && !beaned){
        cachedLeaderboard.push({element:players[i],text:players[i].innerText,clicked:false});
    }
  }
}

window.setup1 = function (){
  setInterval(test_leaderboard,1000);
  var launch_button = document.querySelectorAll("[data-functional-selector=\"launch-button\"]")[0];
  if(launch_button){
    console.warn("launch button found!");
    launch_button.addEventListener("click",setup2);
  }else{
    setTimeout(setup1,1000);
  }
}

window.setup2 = function (){
  var start_button = document.querySelectorAll("[data-functional-selector=\"start-button\"]")[0];
  if(start_button){
    console.warn("start button found!");
    setup3();
  }else{
    setTimeout(setup2,1000);
  }
}

window.setup3 = function (){
  let playerList = document.getElementsByClassName("player-list")[0];
  let conf = {
    childList: true,
    subtree: true
  };
  let observer = new MutationObserver(kill_bots);
  observer.observe(playerList,conf);
}

window.onload = setup1;

window.cachedUsernames = [];
window.cachedLeaderboard = [];

window.timer = setInterval(function(){
  for(let i in cachedUsernames){
    if(cachedUsernames[i].time <= 0 && !cachedUsernames[i].clicked){
      confirmedPlayers.push(cachedUsernames[i].text);
      continue;
    }
    cachedUsernames[i].time--;
  }
},1000);
window.confirmedPlayers = []; //confirmed players.

window.kill_bots = function (e,observer){
  console.warn("determining evil now. be warned.");
  if(document.getElementsByClassName("player-list").length == 0){
    observer.disconnect();
    return;
  }
  let players = document.querySelectorAll("[data-functional-selector=\"player\"]");
  for(let i in players){
    let beaned = false;
    if(cachedUsernames.length == 0){
      cachedUsernames.push({element:players[i],text:players[i].innerText,clicked:false,time:10});
      continue;
    }
    for(let k in cachedUsernames){
      if(cachedUsernames[k].element == players[i]){
        continue;
      }
      if(similarity(cachedUsernames[k].text,players[i].innerText) >= 0.60){
        if(confirmedPlayers.includes(players[i].innerText)){
          break;
        }
        players[i].click();
        beaned = true;
        if(!cachedUsernames[k].clicked){
          if(confirmedPlayers.includes(cachedUsernames[k].text)){
            break;
          }
          cachedUsernames[k].element.click();
          cachedUsernames[k].clicked = true;
        }
        break;
      }
    }
    if(cachedUsernames.filter(function(item){return item.text == players[i].innerText}).length === 0 && !beaned){
        cachedUsernames.push({element:players[i],text:players[i].innerText,clicked:false,time:10});
    }
  }
};