Greasy Fork

[KissAnime] Captcha Solver

Saves initial responses to KissAnime captcha and auto-selects images if it knows the answer.

目前为 2018-07-06 提交的版本。查看 最新版本

// ==UserScript==
// @name         [KissAnime] Captcha Solver
// @namespace    https://greasyfork.org/en/users/193865-westleym
// @author       WestleyM
// @version      2018.07.06
// @icon         http://kissanime.ru/Content/images/favicon.ico
// @description  Saves initial responses to KissAnime captcha and auto-selects images if it knows the answer.
// @grant        none
// @include      http://kissanime.ru/Special/AreYouHuman2*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// ==/UserScript==


//Global variables
var words = [];
var undefinedWords = [];
var imageSrc = [];
var clickImage = [];
var count = 0;
var formVerify = document.getElementById("formVerify");
var impExpFlag = 0;
var wordImagePairs = {}

if (formVerify === null) {
  var link = document.getElementsByTagName("a");
  link = link[0];
  if (localStorage.getItem("lastDescriptions") != null) {
		wordsObj = JSON.parse(localStorage.getItem("lastDescriptions"));
  	localStorage.removeItem(wordsObj.firstWord);
		localStorage.removeItem(wordsObj.secondWord);
  	localStorage.removeItem("lastDescriptions");
  	console.log("Deleted the last two entries");
  }
  console.log("Redirecting page. . . .");
  link.click();
}


if (formVerify != null) {  //User is on the regular captcha page
  //Alerts based on new updates
	var currentVersion = "2018.07.06"
	var versionAlert = "(You will only see this message once)\n\nImporting/Exporting solutions has been added in this version.\nIf you would like to help out your fellow users, I would be grateful if you could send me\nyour solutions using the new 'export' option.  I will verify it and compile a master list to publish.\n\n You can reach me through GreasyFork @WestleyM"
	if (localStorage.getItem("version") != currentVersion) {
		alert(versionAlert);
	  localStorage.setItem("version", currentVersion);
	}
  
  
	var imageElements = $("#formVerify").find("img").toArray();  //All images under the "formVerify" form
	var imageNumber = imageElements.length;  //How many images are in the captcha
	var words = Words();
  
	//Image onclick events
	imageElements.forEach(function(currentImage, imageIndex) {
	  currentImage.onclick = function() {
	    if (!localStorage.getItem("helpword")){ //Saves the solution to local storage
		  	localStorage.setItem(localStorage.getItem("helpWord"),ProcessImages()[imageIndex])
		    localStorage.removeItem("helpword");
		  }
	    
	    if (count === 1) {  //Changes text in the alert box
	      alertBoxText.innerText = "Selections complete.  Loading next page. . . .";
	    }
	    
		  if (unknownwords[1] !== undefined && count < 1){ //If there is a word that is not known it will ask for help.  This specific if statement will only activate after you've made your first selection and if the second is unknown.
		    askForHelp(unknownwords[1]);
		    count++;
		  }
	  }
	});
	
	//Message box creation
	var firstDiv = $("#formVerify").find("div").toArray()[0];
	firstDiv.style.cssText = "width:100%;";  //The box holding the information at the top was not wide enough originally
	var thirdPElement = $(firstDiv).find("p").toArray()[2];
	thirdPElement.style.cssText = "opacity:0; height:0px; width:100%;"  //Hides where it lists both selection choices.  This is to insure users select the images in the correct order.
	
	var alertBoxDiv = document.createElement("div");  //Creation of div element which will contain the below text element
	alertBoxDiv.style.cssText = "background:#518203; color:white; height:30px; width:100%; line-height:30px; text-align:center;"
	
	var alertBoxText = document.createElement("h3");  //Creation of text element which will say the descriptions of images the script doesn't know the answer to
	alertBoxText.innerText = "Checking data. . . .";
	alertBoxText.style.cssText = "background:#518203; color:white; height:100%; width:100%; text-align:center; font-size: 20px;"
	
	alertBoxDiv.insertAdjacentElement("afterbegin", alertBoxText);  //Inserting "alertBoxText" into "alertBoxDiv" at the top
	thirdPElement.insertAdjacentElement("afterend", alertBoxDiv);  //Placing "alertBoxDiv" at the end of "mainBlock"
  
  
  //Import/Export area
  var documentBody = document.body;
  
  var importExport = document.createElement("div");
  importExport.style.cssText = "display:block; background: #111111; color:white; width:970px; padding:2px; text-align:center; margin-bottom:30px; margin-left:auto; margin-right:auto; border:1px solid #2f2f2f;"
  
  var impExpButton = document.createElement("p");
  impExpButton.style.cssText = "background:#518203; color:white; height:15px; width:960px; margin-top:5px; margin-bottom:5px; text-align:center; font-size: 15px; padding:5px; cursor:pointer;"
  impExpButton.innerText = "[+] Solution List Importing/Exporting"
  impExpButton.id = "impExpButton"
  
  var inputJSON = document.createElement("input");
  inputJSON.type = "text"
  inputJSON.name = "JSON input"
  inputJSON.id = "inputJSON"
  inputJSON.placeholder = "Paste solution here (will not overwrite existing solutions)"
  inputJSON.style.cssText = "display:none; width:50%; margin-left:auto; margin-right:auto; margin-bottom:5px;"
  
  var inputSubmit = document.createElement("div");
  inputSubmit.style.cssText = "display:none; background:#518203; color:white; height:20px; width:50%; margin-left:auto; margin-right:auto; margin-bottom:5px; border:1px solid #5a5a5a; cursor:pointer;"
  inputSubmit.innerText = "Submit"
  inputSubmit.id = "inputSubmit"
  
  var lineSeparator = document.createElement("div");
  lineSeparator.style.cssText = "display:none; background:#5f5f5f; height:3px; width:100%; margin-left:auto; margin-right:auto; margin-bottom:5px;"
  lineSeparator.id = "lineSeparator"
  
  var exportButton = document.createElement("div");
  exportButton.style.cssText = "display:none; background:#518203; color:white; height:20px; width:50%; margin-left:auto; margin-right:auto; margin-bottom:5px; border:1px solid #5a5a5a; cursor:pointer;"
  exportButton.innerText = "Export list"
  exportButton.id = "exportButton"
  
  var exportDirections = document.createElement("div");
  exportDirections.style.cssText = "display:none; background:#518203; color:white; height:20px; width:50%; margin-left:auto; margin-right:auto; margin-bottom:5px; border:1px solid #5a5a5a;"
  exportDirections.innerText = "Copy the below data: (triple click to select all)"
  exportDirections.id = "exportDirections"
  
  var exportBox = document.createElement("p");
  exportBox.style.cssText = "display:none; #111111; color:white; width:75%; margin-left:auto; margin-right:auto; margin-top:0px; margin-bottom:5px; text-align:center; font-size:10px; border:1px solid #2f2f2f; word-wrap: break-word; overflow:auto; max-height:500px;"
  exportBox.innerText = "test text"
  exportBox.id = "exportBox"
  
  importExport.insertAdjacentElement("afterbegin", impExpButton);
  importExport.insertAdjacentElement("beforeend", inputSubmit);
  inputSubmit.insertAdjacentElement("afterend", lineSeparator);
  lineSeparator.insertAdjacentElement("afterend", exportButton);
  exportButton.insertAdjacentElement("afterend", exportDirections);
  exportDirections.insertAdjacentElement("afterend", exportBox);
  impExpButton.insertAdjacentElement("afterend", inputJSON);
  documentBody.insertAdjacentElement("beforeend", importExport);
  
  
  //Import/Export onclick events
  impExpButton.onclick = function() {
    if (impExpFlag === 0) {
      impExpButton.innerText = "[-] Solution List Importing/Exporting";
    	inputJSON.style.display = "block";
      inputSubmit.style.display = "block";
      lineSeparator.style.display = "block";
      exportButton.style.display = "block";
      impExpFlag = 1;
    } else {
      impExpButton.innerText = "[+] Solution List Importing/Exporting"
      inputJSON.style.display = "none";
      inputSubmit.style.display = "none";
      lineSeparator.style.display = "none";
      exportButton.style.display = "none";
      exportDirections.style.display = "none";
      exportBox.style.display = "none";
      impExpFlag = 0;
    }
  }
  
  inputSubmit.onclick = function() {
    var inputData = inputJSON.value;
    
    try {
    	var newCaptchaData = JSON.parse(inputData);
    	Object.keys(newCaptchaData).forEach(function(current) {
    	  if (localStorage.getItem(current) === null) {
    	  	localStorage.setItem(current, newCaptchaData[current]);
    	  }
    	});
    	inputSubmit.innerText = "Submitted successfully!";
      console.log("Solution list has been updated.");
    }
    catch(err) {
      inputSubmit.innerText = "There was an issue.  Check the console.";
      console.log("Issue with list upload: " + err);
  	}
  }
  
  exportButton.onclick = function() {
    //Grab data from local storage and convert to JSON string
    for (var i = 0; i < localStorage.length; i++) {
      if (localStorage.key(i) != "helpWord" && localStorage.key(i) != "lastDescriptions" && localStorage.key(i) != "version") {
      	wordImagePairs[localStorage.key(i)] = localStorage.getItem(localStorage.key(i));
      }
		}
    var wordImagePairsJSON = JSON.stringify(wordImagePairs);
    exportBox.innerText = wordImagePairsJSON;
    
    exportDirections.style.display = "block";
    exportBox.style.display = "block";
  }
  
	
	
	//Avoid conflicts
	this.$ = this.jQuery = jQuery.noConflict(true);
	$(document).ready(function()
	{
	 	unknownwords = UnknownWords();
	  knownwords = KnownWords();
	  console.log("Unknown words: " + unknownwords);
	  console.log("Known words: " + knownwords);
	  if(unknownwords[0] !== undefined){  //Ask for help with the first unknown word
	  	askForHelp(unknownwords[0]);
	  }
	  knownwords.forEach(function(word){
	    matchfound = 0;
	    console.log("processing known word:" + word)
	    ProcessImages().forEach(function(image,counter){  //Grabs known value from local storage and clicks the corresponding image
	      console.log("counter: " + counter);
	      if(localStorage.getItem(word) == image){
	        console.log("found match for word " + word);
	        matchfound = 1;
	        $("[indexValue='"+counter+"']").click();
	      }else if(counter === imageNumber-1 && matchfound === 0){
	        location.reload();
	      }
	    })
	  })
	});
	
	//Functions
	function askForHelp(word){  //Asks you to select an answer when the script doesn't know.
	  alertBoxText.innerText = "Please select image: " + word;
	  localStorage.setItem("helpWord",word);
	}
	
	function UnknownWords(){  //Finds the words that the script doesn't know the answer to
	  var unknownwords = [];
	  words.forEach(function(word){
	     if(!localStorage.getItem(word)){  //If the solution isn't found in the local storage, it will be added to the "unknownwords" array
	       	unknownwords.push(word);
	     }
	  });
	  return unknownwords;
	}
	
	function KnownWords(){  //Finds the words that the script knows the answer to
	  var knownWords = [];
	  words.forEach(function(word){
	     if(localStorage.getItem(word)){  //If solution is found in the local storage, it will be added to the "Knownwords" array
	       	knownWords.push(word);
	     }
	  });
	  return knownWords;
	}
	
	function SaveWord(word, dataurl){
	  if(!localStorage.getItem(word)){
	   	localStorage.removeItem(word);
	    localStorage.setItem(word, dataurl);
	  } else {
	  	localStorage.setItem(word,dataurl);
	  }
	}
	
	function Words(){ //Grabs span elements that are children of the "formVerify" form.  This will include the two sections saying what to select.  Ex: "cat, glasses, 0"
		var pElements = $("#formVerify").find("p").toArray();
	  var finalPElement = pElements[pElements.length-1];
	  var words = $(finalPElement).find("span").toArray();
	  var firstDesc = words[0].innerText;
	  var secondDesc = words[1].innerText;
    
    //Saves the descriptions to local Storage
    lastDescriptions = { "firstWord":firstDesc, "secondWord":secondDesc };
		var DescJSON = JSON.stringify(lastDescriptions);
		localStorage.setItem("lastDescriptions", DescJSON);
    
	  return [firstDesc, secondDesc];
	}
	
	function Images(){
	  return $("[indexValue]").toArray();
	}
	
	function ConvertToDataUrl(img) {
	  var canvas = document.createElement("canvas");
	  canvas.width = img.width;
	  canvas.height = img.height;
	  var ctx = canvas.getContext("2d");
	  ctx.drawImage(img, 0, 0);
	  var dataURL = canvas.toDataURL("image/png");
	  return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
	}
	
	function MinimiseDataUrl(dataUrl,jump) {
	  var a = "";
	  for(var i = 0; i < dataUrl.length; i=i+jump)
	      a += dataUrl.charAt(i);
	  return a;
	}
	
	function ProcessImages()
	{
	  var imagedata = [];
	  Images().forEach(function(image, counter)
	  {
	    dataurl = ConvertToDataUrl(image)
	    imagedata.push(MinimiseDataUrl(MinimiseDataUrl(MinimiseDataUrl(dataurl, 5), 4),3));
	  })
	  return imagedata
	}
}