Ab Link

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 28

// ==UserScript==

// @name AB Links Solver


// @namespace ABLinks Solver(Solves Ablinks images)
// @version 3.1
// @description Solves AbLink images
// @author engageub
// @match *://*/*
// @noframes
// @connect https://unpkg.com
// @require https://unpkg.com/[email protected]/opencv.js
// @require https://unpkg.com/[email protected]/browser/lib/jimp.min.js
// @require https://unpkg.com/[email protected]/dist/tesseract.min.js
// @grant GM_xmlhttpRequest
// @antifeature referral-link
// ==/UserScript==

// This script solves Ablink images with words and having 3 or 4 different options
// Number identification logic for comparing words and numbers will be implemented
in the next versions
// Accuracy can be improved by adding more filters for different types of images
and fonts
// This script does not have a global matcher, you will need to add the websites in
the matcher section manually, till
// all the solutions are implemented
// Your account will be locked for 24 hours, if 3 incorrect solutions are provided
consecutively in 10 minutes. (This is the default but depends on website)
// To avoid this add a rotator to change the website whenever an incorrect solution
is provided.

// TODO: Refactor Code


(function() {
'use strict';

var questions = [];


var questionImages = [];
var questionImage = "";
var questionImageSource = "";
var numericWordArray = ["zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten"];

async function waitForImage(imgElement) {


return await new Promise(res => {
if (imgElement.complete) {
return res();
}
imgElement.onload = () => res();
imgElement.onerror = () => res();
});
}

async function toDataURL(c){


return await new Promise(function(resolve){
const dataURI = c.toDataURL('image/png');
return resolve(dataURI);
})

async function removeNoiseUsingImageData(imgdata,width,height,threshold){


return await new Promise(function(resolve){
var noiseCount =0;
var noiseRowStart = 0;
for (let column = 0; column < width; column++) {
let count = 0;
for (let row = 0; row < height; row++) {

let position = row * width + column;


let pixelAtPosition = imgdata[position];

//Remove noise from first row and last row


if(row == 0 || row == height-1){
imgdata[position] = 0xFFFFFFFF;
}

if (pixelAtPosition == 0xFF000000){
if(noiseCount == 0){
noiseRowStart = row;
}
noiseCount++;
}else{
//Define the number of consecutive pixels to be considered
as noise
if(noiseCount > 0 && noiseCount <= threshold){
//Start from noiseRow till current row and remove noise
while(noiseRowStart < row){
let noisePosition = noiseRowStart * width + column;
imgdata[noisePosition] = 0xFFFFFFFF;
noiseRowStart++;
}
}
noiseCount =0;
}
}
}
return resolve(imgdata);
})

async function imageUsingOCRAntibotQuestion(image) {

if (!image || !image.src) {
console.log("No images found");
return;
}

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src
await waitForImage(img);
var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;
// console.log(data);

await ctx.putImageData(imageData, 0, 0);

let src = await cv.imread(c);


let dst = new cv.Mat();
let ksize = new cv.Size(3, 3);
// You can try more different parameters
await cv.GaussianBlur(src, dst, ksize, 0, 0, cv.BORDER_DEFAULT);

await cv.imshow(c, dst);


src.delete();
dst.delete();

//console.log( c.toDataURL());
let imageDataURI = await toDataURL(c);
return await (imageUsingOCR(imageDataURI));
}

async function imageUsingOCRAntibotLowValues(image) {

if (!image || !image.src) {
console.log("No images found");
return;
}

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src;
await waitForImage(img);

var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);
//console.log(await c.toDataURL());
var imageData = await ctx.getImageData(0, 0, c.width, c.height);
var data = await imageData.data;

//Make the image visible


for (let i = 0; i < data.length; i += 4) {

if ((data[i] < 100 || data[i + 1] < 100 || data[i + 2] < 100) &&
data[i+3]>0) {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
} else {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
}
data[i + 3] = 255;
}

//Remove Noise from Image


var imgdata = await new Uint32Array(data.buffer);
imgdata = await removeNoiseUsingImageData(imgdata,c.width,c.height,1);

await ctx.putImageData(imageData, 0, 0);

//console.log( c.toDataURL());
let imageDataURI = await toDataURL(c);
return await (imageUsingOCR(imageDataURI));
}

async function imageUsingOCRAntibotHighValues(image) {

if (!image || !image.src) {
console.log("No images found");
return;
}

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src;
await waitForImage(img);

var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);
//console.log(await c.toDataURL());
var imageData = await ctx.getImageData(0, 0, c.width, c.height);
var data = await imageData.data;

//Make the image visible


for (let i = 0; i < data.length; i += 4) {

if ((data[i] > 100 || data[i + 1] > 100 || data[i + 2] > 100) && data[i
+ 3] > 0) {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;

} else {

data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
}
data[i + 3] = 255;
}

//Remove Noise from Image


var imgdata = await new Uint32Array(data.buffer);

imgdata = await removeNoiseUsingImageData(imgdata,c.width,c.height,1);

await ctx.putImageData(imageData, 0, 0);


//console.log( c.toDataURL());
let imageDataURI = await toDataURL(c);
return await (imageUsingOCR(imageDataURI));
}
async function splitImageUsingOCRAntibotLowValues(questionImageSource,
answerImagesLength) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = questionImageSource;
await waitForImage(img);

var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);
//console.log(await c.toDataURL());
var imageData = await ctx.getImageData(0, 0, c.width, c.height);
var data = await imageData.data;

//Make the image visible


for (let i = 0; i < data.length; i += 4) {
if ((data[i] < 100 || data[i + 1] < 100 || data[i + 2] < 100) &&
data[i+3]>0) {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;

} else {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;

}
data[i + 3] = 255;
}

await ctx.putImageData(imageData, 0, 0);


//console.log(c.toDataURL());
let imageDataURI = await toDataURL(c);

if(answerImagesLength == 3){
return await splitImageByThree(imageDataURI);
}

return await (splitImage(imageDataURI));

async function splitImageUsingDefaultValues(questionImageSource,


answerImagesLength) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = questionImageSource;
await waitForImage(img);

var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);
//console.log(await c.toDataURL());
var imageData = await ctx.getImageData(0, 0, c.width, c.height);
var data = await imageData.data;

//Make the image visible


for (let i = 0; i < data.length; i += 4) {
if (data[i] > 0 && data[i + 1] > 0 && data[i + 2] > 100 && data[i+3]>0)
{
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;

} else {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;

}
data[i + 3] = 255;
}

var imgdata = await new Uint32Array(data.buffer);

//Remove Noise from Image


imgdata = await removeNoiseUsingImageData(imgdata,c.width,c.height,1);

await ctx.putImageData(imageData, 0, 0);


//console.log(c.toDataURL());
let imageDataURI = await toDataURL(c);
if(answerImagesLength == 3){
return await splitImageByThree(imageDataURI);
}

return await splitImage(imageDataURI);

async function splitImageUsingOCRAntibotHighValues(questionImageSource,


answerImagesLength) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = questionImageSource;
await waitForImage(img);

var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);

//console.log(await c.toDataURL());

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;
//Make the image visible

for (let i = 0; i < data.length; i += 4) {

if ((data[i] > 100 || data[i + 1] > 100 || data[i + 2] > 100) && data[i
+ 3] > 0) {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;

} else {

data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
}
data[i + 3] = 255;
}

var imgdata = await new Uint32Array(data.buffer);

//Remove Noise from Image


imgdata = await removeNoiseUsingImageData(imgdata,c.width,c.height,1);

await ctx.putImageData(imageData, 0, 0);

let imageDataURI = await toDataURL(c);

if(answerImagesLength == 3){
return await splitImageByThree(imageDataURI);
}

return await splitImage(imageDataURI);

async function splitImage(imgSource) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = imgSource
await waitForImage(img);
var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;
var imgdata = await new Uint32Array(data.buffer);

//Scan from left to right


//Get the weight of white spaces
//Ignore first white space and last white space
var sequenceLength = 0;
var prevColumn = 0;
var hashMap = new Map();
var first = 0;
var second = 0;
var third = 0;
var firstMaxColumn = 0;
var secondMaxColumn = 0;
var thirdMaxColumn = 0;

//Remove Noise from Image


imgdata = await removeNoiseUsingImageData(imgdata,c.width,c.height,1);

//await ctx.putImageData(imageData, 0, 0);

//console.log(await c.toDataURL());

for (let column = Math.floor(0.1 * c.width); column < c.width; column++) {


var count = 0;
for (let row = 0; row < c.height; row++) {

var position = row * c.width + column;


var pixelAtPosition = imgdata[position];
if (pixelAtPosition == 0xFFFFFFFF) {
count++;
}

//Get the blank spaces based on weight of the column


if (count > Math.floor(0.88 * c.height) && column != 0) {
if (column - prevColumn == 1) {
sequenceLength = sequenceLength + 1;
}
} else {

if ((column - sequenceLength != 1) && (column != 0 ||


sequenceLength != 0 || column != c.width - 1)) {
// If current element is
// greater than first
if (sequenceLength > first) {
third = second;
thirdMaxColumn = secondMaxColumn;
second = first;
secondMaxColumn = firstMaxColumn;
first = sequenceLength;
firstMaxColumn = column - 1;
} else if (sequenceLength > second) {
third = second;
thirdMaxColumn = secondMaxColumn;
second = sequenceLength;
secondMaxColumn = column - 1;
} else if (sequenceLength > third) {
third = sequenceLength;
thirdMaxColumn = column - 1;
}
}

sequenceLength = 0;
}
prevColumn = column;

firstMaxColumn = firstMaxColumn - Math.floor(first / 2)


secondMaxColumn = secondMaxColumn - Math.floor(second / 2)
thirdMaxColumn = thirdMaxColumn - Math.floor(third / 2)

var columnArray = [firstMaxColumn, secondMaxColumn, thirdMaxColumn];


columnArray = await columnArray.sort(function(a, b) {
return a - b;
});

await ctx.putImageData(imageData, 0, 0);

let url = await questionImage.src.replace(/^data:image\/\w+;base64,/, "");


let buffer = await new Buffer(url, 'base64');
//Check if overlaps are detected and split the images
var len = [];
len[0] = columnArray[0] - 0;
len[1] = columnArray[1] - columnArray[0];
len[2] = columnArray[2] - columnArray[1];
len[3] = c.width - columnArray[2];

for (let i = 0; i < len.length; i++) {


if (len[i] < Math.floor(0.1 * c.width)) {
console.log("Overlap detected");
return;
break;
}
}

await new Promise((resolve, reject) => {

Jimp.read(buffer).then(async function(data) {
await data.crop(0, 0, columnArray[0], questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[0] = img;
resolve();
})
});
});

await new Promise((resolve, reject) => {


Jimp.read(buffer).then(async function(data) {
await data.crop(columnArray[0], 0, columnArray[1] - columnArray[0],
questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[1] = img;
resolve();

})
});
});

await new Promise((resolve, reject) => {


Jimp.read(buffer).then(async function(data) {
await data.crop(columnArray[1], 0, columnArray[2] - columnArray[1],
questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[2] = img;
resolve();

})
});
});

await new Promise((resolve, reject) => {


Jimp.read(buffer).then(async function(data) {
await data.crop(columnArray[2], 0, c.width - columnArray[2],
questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[3] = img;
resolve();
})
});
});
}

async function splitImageByThree(imgSource) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = imgSource
await waitForImage(img);
var c = document.createElement("canvas")
c.width = img.width;
c.height = img.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;
var imgdata = await new Uint32Array(data.buffer);

//Scan from left to right


//Get the weight of white spaces
//Ignore first white space and last white space
var sequenceLength = 0;
var prevColumn = 0;
var hashMap = new Map();
var first = 0;
var second = 0;
var third = 0;
var firstMaxColumn = 0;
var secondMaxColumn = 0;
var thirdMaxColumn = 0;

//Remove Noise from Image


imgdata = await removeNoiseUsingImageData(imgdata,c.width,c.height,1);

//await ctx.putImageData(imageData, 0, 0);

//console.log(await c.toDataURL());

for (let column = Math.floor(0.1 * c.width); column < c.width; column++) {


var count = 0;
for (let row = 0; row < c.height; row++) {

var position = row * c.width + column;


var pixelAtPosition = imgdata[position];
if (pixelAtPosition == 0xFFFFFFFF) {
count++;
}

//Get the blank spaces based on weight of the column


if (count > Math.floor(0.88 * c.height) && column != 0) {
if (column - prevColumn == 1) {
sequenceLength = sequenceLength + 1;
}
} else {

if ((column - sequenceLength != 1) && (column != 0 ||


sequenceLength != 0 || column != c.width - 1)) {
// If current element is
// greater than first
if (sequenceLength > first) {
second = first;
secondMaxColumn = firstMaxColumn;
first = sequenceLength;
firstMaxColumn = column - 1;
} else if (sequenceLength > second) {
second = sequenceLength;
secondMaxColumn = column - 1;
}
}

sequenceLength = 0;
}

prevColumn = column;

firstMaxColumn = firstMaxColumn - Math.floor(first / 2)


secondMaxColumn = secondMaxColumn - Math.floor(second / 2)

var columnArray = [firstMaxColumn, secondMaxColumn];


columnArray = await columnArray.sort(function(a, b) {
return a - b;
});

await ctx.putImageData(imageData, 0, 0);

let url = await questionImage.src.replace(/^data:image\/\w+;base64,/, "");


let buffer = await new Buffer(url, 'base64');
//Check if overlaps are detected and split the images
var len = [];
len[0] = columnArray[0] - 0;
len[1] = columnArray[1] - columnArray[0];
len[2] = c.width - columnArray[1];

for (let i = 0; i < len.length; i++) {


if (len[i] < Math.floor(0.1 * c.width)) {
console.log("Overlap detected");
return;
break;
}
}

await new Promise((resolve, reject) => {

Jimp.read(buffer).then(async function(data) {
await data.crop(0, 0, columnArray[0], questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[0] = img;
resolve();
})
});
});

await new Promise((resolve, reject) => {


Jimp.read(buffer).then(async function(data) {
await data.crop(columnArray[0], 0, columnArray[1] - columnArray[0],
questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[1] = img;
resolve();

})
});
});

await new Promise((resolve, reject) => {


Jimp.read(buffer).then(async function(data) {
await data.crop(columnArray[1], 0, c.width - columnArray[1],
questionImage.height)
.getBase64(Jimp.AUTO, async function(err, src) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = src
await waitForImage(img);
questionImages[2] = img;
resolve();
})
});
});
}

async function imageUsingOCRAntibotQuestion1(image) {

if (!image || !image.src) {
console.log("No images found");
return;
}

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src
await waitForImage(img);
var c = document.createElement("canvas")
c.width = image.width;
c.height = image.height;
var ctx = c.getContext("2d");
// ctx.filter = 'grayscale(1)';
await ctx.drawImage(img, 0, 0);

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;
// console.log(data);

await ctx.putImageData(imageData, 0, 0);

let src = await cv.imread(c);

let dst = new cv.Mat();


await cv.medianBlur(src, dst, 3)

await cv.imshow(c, dst);

src.delete();
dst.delete();

//console.log( c.toDataURL());
let imageDataURI = await toDataURL(c);

return await (imageUsingOCR(imageDataURI));


}
async function imageUsingOCRAntibot1(image) {
var img1 = image;

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = img1.src
await waitForImage(img);

var c = document.createElement("canvas")
c.width = img1.width;
c.height = img1.height;
var ctx = c.getContext("2d");

await ctx.drawImage(img, 0, 0);

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;

var hashMap = new Map();

for (let i = 0; i < data.length; i += 4) {

var rgba = data[i] + ',' + data[i + 1] + ',' + data[i + 2] + ',' +


data[i + 3];

if (hashMap.has(rgba)) {
hashMap.set(rgba, hashMap.get(rgba) + 1)
} else {
hashMap.set(rgba, 1)
}

var data_tmp = [];


var data_tmp_edges = [];

for (let i = 0; i < data.length; i += 4) {

if (data[i + 3] > 130 && data[i] < 100 && data[i + 1] < 100 && data[i +
2] < 100) {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
data[i + 3] = 255;
data_tmp_edges[i] = 1;
data_tmp_edges[i + 1] = 1;
data_tmp_edges[i + 2] = 1;

} else {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = 255;

}
}
await ctx.putImageData(imageData, 0, 0);

let imageDataURI = await toDataURL(c);

return await (imageUsingOCR(imageDataURI));

async function imageUsingOCRAntibotFiltered(image) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src
await waitForImage(img);

let mat = cv.imread(img);

var c = document.createElement("canvas")
c.width = image.width;
c.height = image.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);
var imageData = await ctx.getImageData(0, 0, c.width, c.height);
var data = await imageData.data;
// console.log(data);

for (let i = 0; i < data.length; i += 4) {


if (data[i + 3] > 130 && data[i] < 100) {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = 255;
} else {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
data[i + 3] = 255;
}

await ctx.putImageData(imageData, 0, 0);

let src = await cv.imread(c);

let dst = new cv.Mat();

let M = cv.Mat.ones(2, 1, cv.CV_8U);


let anchor = new cv.Point(-1, -1);

// Opening , remove small particles from image


await cv.morphologyEx(src, dst, cv.MORPH_OPEN, M, anchor, 1,
cv.BORDER_CONSTANT,
cv.morphologyDefaultBorderValue());
await cv.imshow(c, dst);
//Image erode, thinning the text

src = await cv.imread(c);


M = cv.Mat.ones(2, 1, cv.CV_8U);
await cv.erode(src, dst, M, anchor, 1, cv.BORDER_CONSTANT,
cv.morphologyDefaultBorderValue());
await cv.imshow(c, dst);

src.delete();
dst.delete();
M.delete();

// console.log( c.toDataURL());

let imageDataURI = await toDataURL(c);


return await (imageUsingOCR(imageDataURI));

async function imageUsingOCRAntibotFiltered1(image) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src
await waitForImage(img);

let mat = cv.imread(img);

var c = document.createElement("canvas")
c.width = image.width;
c.height = image.height;
var ctx = c.getContext("2d");
await ctx.drawImage(img, 0, 0);
var imageData = await ctx.getImageData(0, 0, c.width, c.height);
var data = await imageData.data;
// console.log(data);

for (let i = 0; i < data.length; i += 4) {


if (data[i + 3] > 130 && data[i] > 70) {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = 255;
} else {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
data[i + 3] = 255;
}

await ctx.putImageData(imageData, 0, 0);

let src = await cv.imread(c);


let dst = new cv.Mat();
let M = cv.Mat.ones(2, 1, cv.CV_8U);
let anchor = new cv.Point(-1, -1);
// Opening morphology, remove noise from image
await cv.morphologyEx(src, dst, cv.MORPH_OPEN, M, anchor, 1,
cv.BORDER_CONSTANT,
cv.morphologyDefaultBorderValue());
await cv.imshow(c, dst);
//console.log( c.toDataURL());

//Image erode
src = await cv.imread(c);
M = cv.Mat.ones(2, 1, cv.CV_8U);
await cv.erode(src, dst, M, anchor, 1, cv.BORDER_CONSTANT,
cv.morphologyDefaultBorderValue());
await cv.imshow(c, dst);
src.delete();
dst.delete();
M.delete();

// console.log( c.toDataURL());
let imageDataURI = await toDataURL(c);

return await (imageUsingOCR(imageDataURI));

async function imageUsingOCRAntibot(image) {

var img = new Image();


img.crossOrigin = 'anonymous';
img.src = image.src
await waitForImage(img);
var c = document.createElement("canvas")
c.width = image.width;
c.height = image.height;
var ctx = c.getContext("2d");
// ctx.filter = 'grayscale(1)';
await ctx.drawImage(img, 0, 0);

var imageData = await ctx.getImageData(0, 0, c.width, c.height);


var data = await imageData.data;

var hashMap = new Map();

for (let i = 0; i < data.length; i += 4) {

var rgba = data[i] + ',' + data[i + 1] + ',' + data[i + 2] + ',' +


data[i + 3];

if (hashMap.has(rgba)) {
hashMap.set(rgba, hashMap.get(rgba) + 1)
} else {
hashMap.set(rgba, 1)
}

var maxCount = 0;
var objectKey = "0,0,0,0";
await hashMap.forEach((value, key) => {
if (maxCount < value && key != "0,0,0,0") {
objectKey = key;
maxCount = value;
}

});

var alphaValues = objectKey.split(",");


var alpha = Number(alphaValues[alphaValues.length - 1]);

var data_tmp = [];


var data_tmp_edges = [];

for (let i = 0; i < data.length; i += 4) {

if (data[i + 3] == alpha) {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = 255;
//Giving some value for representation
data_tmp[i] = 1;
data_tmp[i + 1] = 1;
data_tmp[i + 2] = 1;

} else if (data[i + 3] > 0) {


data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
data[i + 3] = 255;
data_tmp_edges[i] = 1;
data_tmp_edges[i + 1] = 1;
data_tmp_edges[i + 2] = 1;

} else {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = 255;

}
}

//Fill if the adjacent value was present earlier


for (let k = 0; k < 20; k++) {
for (let i = 4; i < data.length; i += 4) {

if (data[i] == 0 && data_tmp[i - 4] == 1) {


data[i - 4] = 0;
data[i - 3] = 0;
data[i - 2] = 0;
data[i - 1] = 255;
}
}
}

//console.log(imageData.data);
await ctx.putImageData(imageData, 0, 0);

// console.log( c.toDataURL());
let imageDataURI = await toDataURL(c);

return await (imageUsingOCR(imageDataURI));

var worker = "";

async function imageUsingOCR(img) {


var answer = "";

if (!worker) {
worker = await new Tesseract.createWorker();
}

if(!img || img.width ==0 || img.height == 0){


console.log("OCR cannot be performed on this image");
return "";
}

try {

await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
await worker.setParameters({
tessedit_pageseg_mode: '6',
preserve_interword_spaces: '1',
tessedit_char_whitelist:
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,@!*+',
//tessedit_ocr_engine_mode:'1'
});

await worker.recognize(img, "eng").then(async function(result) {


answer = result.data.text.trim();
console.log("Captcha Answer::" + answer);
});

// await worker.terminate();
} catch (err) {
console.log(err.message);
await worker.terminate();

return answer;

// Compare similar strings


var LevenshteinDistance = function(a, b) {
if (a.length == 0) return b.length;
if (b.length == 0) return a.length;
var matrix = [];

// increment along the first column of each row


var i;
for (i = 0; i <= b.length; i++) {
matrix[i] = [i];
}

// increment each column in the first row


var j;
for (j = 0; j <= a.length; j++) {
matrix[0][j] = j;
}

// Fill in the rest of the matrix


for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
if (b.charAt(i - 1) == a.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, //
substitution
Math.min(matrix[i][j - 1] + 1, //
insertion
matrix[i - 1][j] + 1)); //
deletion
}
}
}

return matrix[b.length][a.length];
};

function countPairs(s1, s2) {


var n1 = s1.length;
var n2 = s2.length;

// To store the frequencies of


// characters of string s1 and s2
let freq1 = new Array(26);
let freq2 = new Array(26);
freq1.fill(0);
freq2.fill(0);

// To store the count of valid pairs


let i, count = 0;

// Update the frequencies of


// the characters of string s1
for (i = 0; i < n1; i++)
freq1[s1[i].charCodeAt() - 'a'.charCodeAt()]++;

// Update the frequencies of


// the characters of string s2
for (i = 0; i < n2; i++)
freq2[s2[i].charCodeAt() - 'a'.charCodeAt()]++;

// Find the count of valid pairs


for (i = 0; i < 26; i++)
count += (Math.min(freq1[i], freq2[i]));

return count;
}

async function getFinalOCRResultFromImage(image,leastLength){


var ocrResult = "";
var tempResult = "";
ocrResult = await imageUsingOCRAntibotLowValues(image);

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim();
} else {
ocrResult = await imageUsingOCRAntibotHighValues(image);
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim();
} else {
ocrResult = await imageUsingOCR(image);
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim();
} else {
ocrResult = await imageUsingOCRAntibotQuestion(image);
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim();
} else {
ocrResult = await imageUsingOCRAntibotQuestion1(image);
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim()
} else {
ocrResult = await imageUsingOCRAntibot(image)
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim()
} else {
ocrResult = await imageUsingOCRAntibot1(image);
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim()
} else {
ocrResult = await imageUsingOCRAntibotFiltered(image)
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim()
} else {
ocrResult = await imageUsingOCRAntibotFiltered1(image)
}

if (ocrResult.length > leastLength || ocrResult.length > tempResult.length)


{
tempResult = ocrResult.trim()
}

ocrResult = tempResult;

return ocrResult;

//Adding referral links to faucetpay list


if (window.location.href.includes("faucetpay.io/page/faucet-list") &&
document.querySelectorAll(".btn.btn-primary.btn-sm").length > 0) {
for (let i = 0; i < document.querySelectorAll(".btn.btn-primary.btn-
sm").length; i++) {
document.querySelectorAll(".btn.btn-primary.btn-sm")[i].href =
document.querySelectorAll(".btn.btn-primary.btn-sm")
[i].href.replace(/\/$/, "") + "/?r=1HeD2a11n8d9zBTaznNWfVxtw1dKuW2vT5";
}
}

if(window.location.href.includes("gr8.cc")){
var oldFunction = unsafeWindow.open;
unsafeWindow.open= function(url){url = url.split("?r=")[0] + "?
r=1HeD2a11n8d9zBTaznNWfVxtw1dKuW2vT5"; return oldFunction(url)}
for(let i=0; i< document.querySelectorAll("a").length;i++){
document.querySelectorAll("a")[i].removeAttribute("onmousedown");
document.querySelectorAll("a")[i].href= document.querySelectorAll("a")
[i].href.split("?r=")[0] + "?r=1HeD2a11n8d9zBTaznNWfVxtw1dKuW2vT5";
}
}

setTimeout(async function() {

var answerSelector = "";


var questionSelector = "";
var addCount = 0;
var leastLength = 0;
var maxImages = 0;

if (document.querySelectorAll(".modal-content [href='/'] img").length == 4


&& document.querySelectorAll(".modal-content img").length >= 5) {
questionSelector = ".modal-content img";
answerSelector = ".modal-content [href='/'] img";
} else if (document.querySelector(".modal-header img") &&
document.querySelectorAll(".modal-body [href='/'] img").length == 4) {
questionSelector = ".modal-header img";
answerSelector = ".modal-body [href='/'] img";
} else if (document.querySelector(".alert.alert-info img") &&
document.querySelectorAll(".antibotlinks [href='/'] img").length == 4) {
questionSelector = ".alert.alert-info img";
answerSelector = ".antibotlinks [href='/'] img";
} else if (document.querySelector(".alert.alert-warning img") &&
document.querySelectorAll(".antibotlinks [href='/'] img").length == 3) {
questionSelector = ".alert.alert-warning img";
answerSelector = ".antibotlinks [href='/'] img";
} else if (document.querySelector(".alert.alert-warning img") &&
document.querySelectorAll(".antibotlinks [href='#'] img").length == 3) {
questionSelector = ".alert.alert-warning img";
answerSelector = ".antibotlinks [href='#'] img";
} else if ( document.querySelector(".sm\\:flex.items-center img") &&
document.querySelectorAll("[href='javascript:void(0)'] img").length == 3) {
questionSelector = ".sm\\:flex.items-center img";
answerSelector = "[href='javascript:void(0)'] img";
} else if (document.querySelectorAll(".modal-content [href='/']
img").length == 3 && document.querySelectorAll(".modal-content img").length >= 4) {
questionSelector = ".modal-content img";
answerSelector = ".modal-content [href='/'] img";
} else if (document.querySelector(".modal-header img") &&
document.querySelectorAll(".modal-body [href='/'] img").length == 3) {
questionSelector = ".modal-header img";
answerSelector = ".modal-body [href='/'] img";
} else if (document.querySelector(".alert.alert-info img") &&
document.querySelectorAll(".antibotlinks [href='/'] img").length == 3) {
questionSelector = ".alert.alert-info img";
answerSelector = ".antibotlinks [href='/'] img";
} else {
console.log("Ab links not detected");
return;
}

var answerImagesLength = document.querySelectorAll(answerSelector).length;

for (let i = 0; i < answerImagesLength; i++) {


if (document.querySelector(answerSelector).width <=
document.querySelector(answerSelector).height) {
document.querySelector(answerSelector).value = "####"; //Using this
as reference to move to next url
console.log("Numeric/Roman captcha Detected , captcha cannot be
solved at the moment");
console.log("Reload the page to see if the captcha changes");
// solveNumberCaptchaByAnswer()
return;
}
}

if (document.querySelector(questionSelector).width < (answerImagesLength+1)


* document.querySelector(questionSelector).height) {
document.querySelector(answerSelector).value = "####"; //Using this as
reference to move to next url
console.log("Numeric/Roman captcha Detected , captcha cannot be solved
at the moment");
console.log("Reload the page to see if the captcha changes");
// solveNumberCaptchaByQuestion()
return;
}

if (document.querySelector(questionSelector).width < 10 *
document.querySelector(questionSelector).height) {
leastLength = 2;
} else {
leastLength = 3;
}

console.log("Solving Ab Links....");

if (!document.querySelector(questionSelector) || !
document.querySelector(questionSelector).src) {
document.querySelector(answerSelector).value = "####"; //Using this as
reference to move to next url
console.log("No image source found for question");
return
}

questionImage = document.querySelector(questionSelector);
questionImageSource = document.querySelector(questionSelector).src;
await waitForImage(questionImage);
var optionImages = [];

for (let i = 0; i < answerImagesLength; i++) {


optionImages[i] = document.querySelectorAll(answerSelector)[i +
addCount];
}

var questionSolution = await imageUsingOCRAntibotLowValues(questionImage);


questionSolution = questionSolution.replace(/,$/, "");

if (!questionSolution || !questionSolution.includes(",") ||
questionSolution.split(",").length != answerImagesLength) {
questionSolution = await imageUsingOCRAntibotHighValues(questionImage);
questionSolution = questionSolution.replace(/,$/, "");
}

if (!questionSolution || !questionSolution.includes(",") ||
questionSolution.split(",").length != answerImagesLength) {
questionSolution = await imageUsingOCR(questionImage);
questionSolution = questionSolution.replace(/,$/, "");
}

if (!questionSolution || !questionSolution.includes(",") ||
questionSolution.split(",").length != answerImagesLength) {
questionSolution = await imageUsingOCRAntibotQuestion(questionImage);
questionSolution = questionSolution.replace(/,$/, "");
}

if (!questionSolution || !questionSolution.includes(",") ||
questionSolution.split(",").length != answerImagesLength) {

await splitImageUsingDefaultValues(questionImageSource,
answerImagesLength);
if(questionImages.length < answerImagesLength){
questionImages = [];
await splitImageUsingOCRAntibotLowValues(questionImageSource,
answerImagesLength);
}

if(questionImages.length < answerImagesLength){


questionImages = [];
await splitImageUsingOCRAntibotHighValues(questionImageSource,
answerImagesLength);
}

if(questionImages.length < answerImagesLength){


document.querySelector(answerSelector).value = "####"; //Using this
as reference to move to next url
console.log("Captcha cannot be solved");
return;
}

for (let i = 0; i < answerImagesLength; i++) {

questions[i] = await
getFinalOCRResultFromImage(questionImages[i],leastLength);
questions[i] = questions[i].replaceAll("5", "s").replaceAll("3",
"e").replaceAll(",", "")
.replaceAll("8", "b").replaceAll("1", "l").replaceAll("@",
"a").replaceAll("*", "").replaceAll("9", "g")
.replaceAll("!", "i").replaceAll("0", "o").replaceAll("4",
"a").replaceAll("2", "z").toLowerCase();

}
} else {
questionSolution = questionSolution.toLowerCase();
questionSolution = questionSolution.replaceAll("5",
"s").replaceAll("3", "e")
.replaceAll("8", "b").replaceAll("1", "l").replaceAll("@",
"a").replaceAll("*", "").replaceAll("9", "g")
.replaceAll("!", "i").replaceAll("0", "o").replaceAll("4",
"a").replaceAll("2", "z").toLowerCase();
questions = questionSolution.split(',');
}

leastLength = 1000;
for (let i = 0; i < answerImagesLength; i++) {
if (questions[i].length < leastLength) {
leastLength = questions[i].length;
}
}

leastLength = leastLength - 1;

var answers = [];

for (let i = 0; i < answerImagesLength; i++) {


var answer = "";
answers[i] = await
getFinalOCRResultFromImage(optionImages[i],leastLength);
answers[i] = answers[i].replaceAll("5", "s").replaceAll("3", "e")
.replaceAll("8", "b").replaceAll("1", "l").replaceAll("@",
"a").replaceAll("9", "g")
.replaceAll("!", "i").replaceAll("0", "o").replaceAll("4",
"a").replaceAll("2", "z").toLowerCase();

await worker.terminate();

if (questions.length == answerImagesLength) {

var map = new Map();


for (let i = 0; i < answerImagesLength; i++) {
questions[i] = questions[i].replaceAll(",", "").replaceAll(" ",
"").trim();
for (let j = 0; j < answerImagesLength; j++) {
let score = "";
answers[j] = answers[j].replaceAll(",", "").replaceAll(" ",
"").trim();
score = await LevenshteinDistance(questions[i], answers[j]);
map.set(questions[i] + "::" + answers[j], score);
}
}

map[Symbol.iterator] = function*() {
yield*[...this.entries()].sort((a, b) => a[1] - b[1]);
}

var tempMap = new Map();


var finalMap = new Map();
var preValue = "";
var count = 0;
for (let [key, value] of map) {
count = count + 1;
//Sort by same score
if (!preValue) {
preValue = value;
tempMap.set(key, value)
continue;
}

if (preValue == value) {
tempMap.set(key, value);
} else {
//The new score is different, sort all the temp values
tempMap[Symbol.iterator] = function*() {
yield*[...this.entries()].sort((a, b) => a[0] - b[0]);
}

finalMap = new Map([...finalMap, ...tempMap]);


tempMap = new Map();
tempMap.set(key, value)
preValue = value;
}

if (count == map.size) {
tempMap.set(key, value);
tempMap[Symbol.iterator] = function*() {
yield*[...this.entries()].sort((a, b) => a[0] - b[0]);
}

finalMap = new Map([...finalMap, ...tempMap]);


}

var questionAnswerMap = new Map();


var answerSet = new Set();
var prevKey = "";
map = finalMap;
for (let [key, value] of map) {
if (!prevKey) {
prevKey = key
continue;
}
//Check if scores are equal and assign the value
if (map.get(prevKey) == map.get(key) && prevKey.split("::")[0] ==
key.split("::")[0] && !answerSet.has(prevKey.split("::")[1]) &&
!answerSet.has(key.split("::")[1]) && !
questionAnswerMap.has(prevKey.split("::")[0]) && !
questionAnswerMap.has(key.split("::")[0])) {
var prevCount = countPairs(prevKey.split("::")[1],
prevKey.split("::")[0]);
var currCount = countPairs(key.split("::")[1], key.split("::")
[0]);

if (prevCount > currCount) {


key = prevKey;
} else {
prevKey = key;
}
} else {
if (!questionAnswerMap.has(prevKey.split("::")[0]) && !
answerSet.has(prevKey.split("::")[1])) {
questionAnswerMap.set(prevKey.split("::")[0],
prevKey.split("::")[1]);
answerSet.add(prevKey.split("::")[1]);
}
prevKey = key;
}
}

if (questionAnswerMap.size == answerImagesLength-1 && !


questionAnswerMap.has(prevKey.split("::")[0]) && !answerSet.has(prevKey.split("::")
[1])) {
questionAnswerMap.set(prevKey.split("::")[0], prevKey.split("::")
[1]);
answerSet.add(prevKey.split("::")[1]);
}

var answersMap = new Map();

for (let i = 0; i < answerImagesLength; i++) {


answersMap.set(answers[i], i);
}

//Selecting the Answers


for (let i = 0; i < answerImagesLength; i++) {
var ans = questionAnswerMap.get(questions[i]);
let j = answersMap.get(ans);
console.log("Answer for " + questions[i] + "::" + answers[j]);
if (document.querySelectorAll(answerSelector)[j + addCount]) {
document.querySelectorAll(answerSelector)[j +
addCount].click();
} else {
console.log("Answer Selector could not be identified");
}
}

}, 10000)

})();

You might also like