Vous êtes sur la page 1sur 9

// ==UserScript==

// @name [KissAnime] Captcha Solver


// @namespace https://greasyfork.org/en/users/193865-westleym
// @author WestleyM
// @version 2018.10.15
// @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==

function main() {
//Variable declarations
var currentVersion = "2018.10.15";
var installText = "Thank you for installing [KissAnime] Captcha Solver!";
var updateText = "Line 106-related issues should not be possible any more. To
see how it works now you can read the few lines starting from 108\nFixed
duplication of KCS-\nThe best way to reach me is on Reddit @WarriorSolution\nPlease
report any bugs or issues!";
var $ = window.jQuery;
var formVerify = document.getElementById("formVerify");
var words = [], undefinedWords = [], unknownWords = [], knownWords = [],
imageSrc = [], clickImage = [], imageData = [], imageElements = [],
multiImageFlag = [];
var matchFound = 0, count = 0, impExpFlag = 0, askedForHelp = 0, PHObjFlag = 0;
var wordImagePairs = {}, wordsObj = {}, imageObj = {}, clickedImgs = {},
placeholderObjOne = {}, placeholderObjTwo = {};
var dataURL = "";
var impExpButton, inputSubmit, exportButton,
firstDiv, PElements, thirdPElement, alertBoxDiv,
alertBoxText, importExport, inputJSON, lineSeparator,
exportDirections, exportBox; //Variables used for created HTML elements

if (formVerify === null) {


var link = document.getElementsByTagName("a");
link = link[0];
if (localStorage.getItem("KCS-lastDescriptions") != null) {
wordsObj = JSON.parse(localStorage.getItem("KCS-lastDescriptions"));
localStorage.removeItem(wordsObj.firstWord);
localStorage.removeItem(wordsObj.secondWord);
localStorage.removeItem("KCS-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 for initial install or update of the script
if (localStorage.getItem("KCS-version") === null &&
localStorage.getItem("version") === null) { messagePusher("install"); }
if (localStorage.getItem("KCS-version") != currentVersion &&
localStorage.getItem("KCS-version") != null) { messagePusher("update"); }
if (localStorage.getItem("KCS-version") === null &&
localStorage.getItem("version") != null) { messagePusher("update"); }
//Image onclick events
imageElements = $("#formVerify").find("img").toArray();
imageElements.forEach(function(currentImage, imageIndex)
{ currentImage.onclick = function() { onClickEvents("image", currentImage,
imageIndex); } });

//Create custom HTML


customHTML();

//Import/Export onclick function calls


impExpButton.onclick = function() { onClickEvents("impExpButton") };
inputSubmit.onclick = function() { onClickEvents("inputSubmit") };
exportButton.onclick = function() { onClickEvents("exportButton") };

//Avoid conflicts, start main processes


this.$ = this.jQuery = jQuery.noConflict(true);
$(document).ready(function() {
wordGrabber();
unknownWordGrabber();
knownWordGrabber();
imageGrabber();
clickImages();

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]);
}
});
}

//Functions
function askForHelp(word) { //Asks you to select an answer when the script
doesn't know.
alertBoxText.innerText = "Please select image: " + word;
localStorage.setItem("KCS-helpWord", word);
}

function unknownWordGrabber() { //Finds the words that the script doesn't know
the answer to
words.forEach(function(word) {
if(!localStorage.getItem("KCS-" + word)) { //If the solution isn't
found in the local storage, it will be added to the "unknownWords" array
unknownWords.push(word);
}
});
}

function knownWordGrabber() { //Finds the words that the script knows the
answer to
words.forEach(function(word) {
if(localStorage.getItem("KCS-" + word)) { //If solution is found in the
local storage, it will be added to the "knownWords" array
knownWords.push(word);
}
});
}

function wordGrabber() { //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, wordElements;

pElements.forEach(function(pElement) { //Grabs the p element that contains


2 span elements in it.
if ($(pElement).find("span").toArray().length === 2) {
wordElements = $(pElement).find("span").toArray();
}
});
words = [wordElements[0].innerText, wordElements[1].innerText];

//Saves the descriptions to local Storage


var lastDescriptions = { "firstWord":wordElements[0].innerText,
"secondWord":wordElements[1].innerText };
var DescJSON = JSON.stringify(lastDescriptions);
localStorage.setItem("KCS-lastDescriptions", DescJSON);
}

function imageGrabber() {
imageElements.forEach(function(image, index) {
var objKey = "image" + index.toString();
var imageData = convertToDataUrl(image);
imageData = minimiseDataUrl(minimiseDataUrl(minimiseDataUrl(imageData,
5), 4), 3);
imageObj[objKey] = imageData;
});
}

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 clickImages() {
knownWords.forEach(function(word) {
var i = 0;
for (var key in imageObj) {
if (localStorage.getItem("KCS-" + word) == imageObj[key]) {
$("[indexValue='" + i + "']").click();
break;
} else if (i === Object.keys(imageObj).length-1) {
var multiImageDesc = localStorage.getItem("KCS-" + word);
var foundFlag = 0;
try {
JSON.parse(multiImageDesc);
for (var j = 0; j < Object.keys(multiImageDesc).length; j+
+) {
if (multiImageDesc[j] === imageObj[key]) {
console.log("Description with multiple images found
and clicked: " + word);
$("[indexValue='" + i + "']").click();
foundFlag = 1;
}
}
}
catch(err) {}
if (foundFlag === 0) {
console.log("Description with multiple images found.
Solution unknown: " + word);
multiImageFlag.push(word);
unknownWords.push(word);
knownWords.splice(knownWords.indexOf(word), 1);
}
}
i++;
}
});
}

function convertSolutions() {
var tempVarKey = "";
var tempVarDesc = "";
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.key(i) != "KCS-helpWord" && localStorage.key(i) !=
"KCS-lastDescriptions" && localStorage.key(i) != "KCS-version") {
tempVarKey = localStorage.key(i);
tempVarKey = tempVarKey.replace(/KCS-/g, "");
tempVarDesc = localStorage.getItem(localStorage.key(i));
localStorage.removeItem(localStorage.key(i));
localStorage.setItem("KCS-" + tempVarKey, tempVarDesc);
}
}
}

function removeBrokenSolutions() {
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.getItem(localStorage.key(i))[0] === "[" ||
localStorage.getItem(localStorage.key(i)) === undefined ||
localStorage.getItem(localStorage.key(i)) === "undefined") {
localStorage.removeItem(localStorage.key(i));
}
}
}

function messagePusher(type) {
switch(type) {
case "install":
console.log(installText);
localStorage.removeItem("version");
localStorage.removeItem("lastDescriptions");
localStorage.removeItem("helpWord");
localStorage.setItem("KCS-version", currentVersion);
break;
case "update":
//alert("(You will only see this message once per update)\n\n" +
updateText);
localStorage.removeItem("version");
localStorage.removeItem("lastDescriptions");
localStorage.removeItem("helpWord");
localStorage.setItem("KCS-version", currentVersion);
convertSolutions();
removeBrokenSolutions();
break;
}
}

function customHTML() {
//Message box
firstDiv = $("#formVerify").find("div").toArray()[0];
firstDiv.style.cssText = "width:100%;"; //The box holding the information
at the top was not wide enough originally

PElements = $(firstDiv).find("p").toArray();
if (PElements.length === 2) {
PElements[0].style.cssText = "opacity:0; height:0px; width:100%; line-
height:0px; font-size:0px;";
}
if (PElements.length === 3) {
PElements[0].style.cssText = "display: none;";
PElements[1].style.cssText = "opacity:0; height:0px; width:100%; line-
height:0px; font-size:0px;";
}

thirdPElement = PElements[PElements.length-1];
thirdPElement.style.cssText = "opacity:0; height:0px; width:100%; line-
height:0px; font-size:0px;"; //Hides where it lists both selection choices. This
is to insure users select the images in the correct order.

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;";

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; margin-top:0px;";

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
importExport = document.createElement("div");
importExport.style.cssText = "display:block; background: #111111;
color:white; width:970px; padding:2px; text-align:center; margin-left:auto; margin-
right:auto; border:1px solid #2f2f2f;";
importExport.id = "importExport";

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";

inputJSON = document.createElement("input");
inputJSON.type = "text";
inputJSON.name = "JSON input";
inputJSON.id = "inputJSON";
inputJSON.placeholder = "Paste solution here";
inputJSON.style.cssText = "display:none; width:50%; margin-left:auto;
margin-right:auto; margin-bottom:5px;";

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";

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";

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";

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";

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 = "";
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);
document.getElementById("containerRoot").insertAdjacentElement("afterend",
importExport);
}

function onClickEvents(clickedItem, clickedImage, imageIndexValue) {


switch(clickedItem) {
case "impExpButton":
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;
}
break;
case "exportButton":
//Grab data from local storage and convert to JSON string
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.key(i) != "KCS-helpWord" &&
localStorage.key(i) != "KCS-lastDescriptions" && localStorage.key(i) != "KCS-
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";
break;
case "inputSubmit":
var inputData = inputJSON.value;
var currentTemp = "";
var oldListLength = localStorage.length.toString();
try {
var newCaptchaData = JSON.parse(inputData);
Object.keys(newCaptchaData).forEach(function(current) {
currentTemp = current.replace(/KCS-/g, ""); //Allows for
compatibility between old export lists and new ones.
localStorage.setItem("KCS-" + currentTemp,
newCaptchaData[current]);
});
inputSubmit.innerText = "Submitted successfully!
Old/new/changed solutions: " + oldListLength + "/" + localStorage.length.toString()
+ "/" + Object.keys(newCaptchaData).length;
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);
}
removeBrokenSolutions();
convertSolutions();
break;
case "image":
if ($(clickedImage).attr("class") === "imgCapSelect") {
clickedImgs[localStorage.getItem("KCS-helpWord")] =
imageIndexValue;
} else {
words.forEach(function(word) {
if (imageIndexValue === clickedImgs[word]) {
delete clickedImgs[word];
}
});
}
if (Object.keys(clickedImgs).length === words.length) {
for (var key in clickedImgs) {
if (key !== multiImageFlag[0] && key !== multiImageFlag[1])
{
localStorage.setItem("KCS-" + key, imageObj["image" +
clickedImgs[key].toString()]);
} else {
var currentSolution = localStorage.getItem(key);
try {
JSON.parse(currentSolution);

currentSolution[Object.keys(currentSolution).length] = imageObj["image" +
clickedImgs[key].toString()];
}
catch(err) {
if (PHObjFlag === 0) {
placeholderObjOne[0] = currentSolution;
placeholderObjOne[1] = imageObj["image" +
clickedImgs[key].toString()];
currentSolution = placeholderObjOne;
PHObjFlag = 1;
} else if (PHObjFlag === 1) {
placeholderObjTwo[0] = currentSolution;
placeholderObjTwo[1] = imageObj["image" +
clickedImgs[key].toString()];
currentSolution = placeholderObjTwo;
PHObjFlag = 2;
}
}
JSON.stringify(currentSolution);
localStorage.setItem("KCS-" + key, currentSolution);
}
}
alertBoxText.innerText = "Selections complete. Loading next
page. . . .";
}
if (Object.keys(clickedImgs).length < words.length) {
words.forEach(function(word, index) {
if (clickedImgs[word] === undefined && askedForHelp === 0)
{
askForHelp(word);
askedForHelp = 1;
}
});
askedForHelp = 0;
}
}
}
}

main();

Vous aimerez peut-être aussi