NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name KissManga Adblock
// @namespace https://openuserjs.org/scripts/shadofx
// @description Sometimes KissManga goes out of its way to screw with ad block. Install this and disable your normal adblock to avoid ads
// @copyright 2018, shadofx (https://openuserjs.org/users/shadofx)
// @license MIT
// @match http://kissmanga.com/*
// @match https://kissmanga.com/*
// @match https://kisscartoon.ac/*
// @match https://kissanime.ac/*
// @match http://kissanime.ru/*
// @match https://kissanime.ru/*
// @match https://kimcartoon.ac/*
// @match https://readcomiconline.to/*
// @match http://kimcartoon.me/*
// @match https://kimcartoon.me/*
// @updateURL https://openuserjs.org/meta/shadofx/KissManga_Adblock.meta.js
// @grant GM_xmlhttpRequest
// @version 5.17
// @run-at document-start
// @require http://code.jquery.com/jquery-1.7.2.min.js
// @require https://unpkg.com/tesseract.js@2.0.0/dist/tesseract.min.js
// ==/UserScript==
// ==OpenUserJS==
// @author shadofx
// ==/OpenUserJS==
var $ = jQuery;
let oldDocEvLi = EventTarget.prototype.addEventListener;
let oldWOpen = window.open;
let oldWAlert = window.alert;
function addEventListener(type,lis){
try{
if(type=='mousedown'||type=='mousemove'){return;}
if(type=='click'&&lis.name=='m0'){return;}
oldDocEvLi.call(this,type,lis)//prevent javascript popups (mostly for Edge)
}catch(e){console.log(e)}
}
function SwapAEL(){//sabotage addEventListener and window.open and window.alert
EventTarget.prototype.addEventListener = addEventListener
window.open = wopen
window.alert = walert
let k = document.title;
Object.defineProperty(document,'title',{
set:function(x){console.log(x)},
get:function(){return k}
});//also prevent page title changes
}
function wopen(URL, name, specs, replace){
if(URL.includes(window.location.origin)){
oldWOpen(URL,name,specs,replace)//only open javascript navs to same origin
}
}
function walert(text){
console.log(text)
}
// If it's the challenge page then wait for it to finish beofore sabotage (sometimes challenge page gets stuck)
if($('head title').text()=="Please wait 5 seconds..."){setInterval(SwapAEL,5000)}else{SwapAEL()}
//RemoveAds removes the offending nodes
function RemoveAds(){
if($('iframe[src*=captcha]').length==0)//don't block when there's google recaptcha
{
$("a:contains('Hide')").click();//click on hide button
$(".divCloseBut").remove();
$(".glx-ctrls-button").parent().parent().parent().remove()
$('.divCloseBut').remove();
$('[src*="propellerads"]').remove();
$('[id^="p_"]').remove();
$('[src*="mgid.com"]').remove();
$('div[id^="MarketGidComposite"]').remove();
$('a[target^="_blank"]>img').remove();//remove any image inside a link which opens in a new tab
$('div[style*="width: 2048px"][style*="z-index: 2147483647"]').remove();//remove the massive click-interceptor that spans the entire page
$('div[style*="z-index: 2000"]').remove();//remove the click-interceptor that blocks disqus
$('iframe').not('#disqus_thread>iframe[src*="comments"]').not('[id^="dsq-app"]:not([src*="disqusads.com"])').not('#ifrmVast').remove();//remove iframes except for the disqus/video ones
$('iframe[src*="ads-iframe"]').remove();//disqus ads
$('#divImage,#btnShowComments').show();//from https://greasyfork.org/en/scripts/372860-fu-kissmanga
$('div.bebi-icon-hover').remove();
$('body>div[style*="absolute"]:not(.tooltip)').remove()//remove click-interceptor that blocks disqus (added 3/29/2019),with exception for tooltips, thanks FooBar@openuserjs.org
$('#footer').remove()//footer gets in the way for some reason
$('#__vliadb83-bg').remove()
$('#__vliadb83').remove()
}
$('a[href*="bebi.com"]').remove();
$("b:contains('[Hide]')").parent().click();//click on hide button
}
//repeatedly run RemoveAds while DOM loads
var loadproc = setInterval(RemoveAds, 50);
//When DOM is loaded...
window.addEventListener("DOMContentLoaded", () => {
//..stop spamming RemoveAds...
clearInterval(loadproc);
//..because we can add more targeted handlers to spam RemoveAds more efficiently:
document.addEventListener("readystatechange", RemoveAds);//Run when page is entirely loaded
new MutationObserver(RemoveAds).observe($('body')[0],{childList: true}); //Run whenever body is changed
document.addEventListener("visibilitychange", RemoveAds);//Run when you switch tabs
loadproc = setInterval(RemoveAds, 1000);//Run every second just in case
});
var covering,tries;
window.addEventListener("load",()=>{
setTimeout(()=>{
if($('#challenge-form').length != 0)
{//hcaptcha exists
covering = $('<div />').appendTo('body').css('position','absolute').css('top','0').css('bottom','0').css('width','100%').css('height','100%').css('background','#333').css('z-index','999999999')
covering.click(()=>{covering.hide()})
tries = 9;//9 tries should be enough, doing it too much gets your ip temporarily blocked
BypassHCaptcha();
}
},500)});
function BypassHCaptcha(){
if(tries<0){covering.remove();return;}tries--;
covering.text("Attempting to autosolve Hcaptcha.Click to Remove.Remaining attempts: "+tries);
let sk = $('iframe[src*=sitekey]').first().attr('src').split('&').filter(c=>c.startsWith('sitekey'))[0].substring(8)
GM_xmlhttpRequest({
method:'POST',headers:{'Content-type':'application/x-www-form-urlencoded'},
url:'https://hcaptcha.com/getcaptcha',
data:'sitekey='+sk+'&host=kissmanga.com&hl=en-US',
onabort:BypassHCaptcha,onerror:BypassHCaptcha,ontimeout:BypassHCaptcha,
onload :(x)=>{
let r1 =JSON.parse(x.responseText);
let ans = {
answers:r1.tasklist.reduce((m,o)=>{m[o.task_key]='true';return m;},{}),//select all images.
c:'null',n:null,job_mode:r1.request_type,serverdomain:'kissmanga.com',sitekey:sk
}
GM_xmlhttpRequest({
method:'POST',headers:{'Content-type':'application/json'},
url:'https://hcaptcha.com/checkcaptcha/'+r1.key,
data:JSON.stringify(ans),
onabort:BypassHCaptcha,onerror:BypassHCaptcha,ontimeout:BypassHCaptcha,
onload :(x)=>{
let r2 = JSON.parse(x.responseText);
if(r2.pass==true&&r2.error!='invalid'&&r2.generated_pass_UUID)
{
$('textarea[name="h-captcha-response"]').val(r2.generated_pass_UUID)
$('textarea[name="g-captcha-response"]').val(r2.generated_pass_UUID)
$('#challenge-form').submit()
}
else{setTimeout(BypassHCaptcha,10)}
}
})
}
})
}
//Custom Captcha Assist using canvas based image diffing and Tesseract OCR
if(window.location.pathname == "/Special/AreYouHuman2"){
const whitelistedColors = [
'234,1,0,255',//red
'255,139,0,255',//orange
'0,117,1,255',//green
'0,1,254,255',//blue
'114,0,118,255'//purple
]
let worker = new Tesseract.createWorker({});
function ImageIsLoaded(img){
if(!img.complete){return false}
if(img.naturalWidth === 0){return false}
return true
}
async function GetAccessor(img){
if(!ImageIsLoaded(img)){await new Promise(resolve => img.addEventListener('load', resolve));}
let canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
let context = canvas.getContext('2d')
return {
context: context,
getPixel:(x,y)=>context.getImageData(x, y, 1, 1).data,
width: img.width,
height:img.height,
data:()=>context.getImageData(0,0,img.width,img.height)
}
}
function GetDraw(width,height){
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let context = canvas.getContext('2d')
let idat = context.createImageData(1,1)
let imgdat = idat.data
return {
canvas: canvas,
drawPixel:(x,y,r,g,b,a)=>
{
imgdat[0]= r;
imgdat[1]= g;
imgdat[2]= b;
imgdat[3]= a;
context.putImageData( idat, x, y );
},
getPixel:(x,y)=>context.getImageData(x, y, 1, 1).data,
width: width,
height:height,
data:()=>context.getImageData(0,0,width,height),
setData:(data)=>context.putImageData(data,0,0)
}
}
function AddColor(colgroup,color){
let item = color.join(',')
Increment(colgroup,item)
}
function Increment(group,item){
if(group[item])
{group[item] = group[item] +1}
else
{group[item] = 1}
}
function AddColorFromData(colgroup,data,offset){
Increment(colgroup,data[offset]+','+data[offset+1]+','+data[offset+2]+','+data[offset+3])
}
function Diff(first,firstIndex,second,secondIndex){
return Math.abs(first[firstIndex]-second[secondIndex])+Math.abs(first[firstIndex+1]-second[secondIndex+1])+Math.abs(first[firstIndex+2]-second[secondIndex+2])
}
function DiffStrCol(first,second){
let firstSplit = first.split(',').map(c=>parseInt(c))
let secondSplit = second.split(',').map(c=>parseInt(c))
return Diff(firstSplit,0,secondSplit,0)
}
function SetRef(dest,destIndex,src,srcIndex){
dest[destIndex] = src[srcIndex]
dest[destIndex+1] = src[srcIndex+1]
dest[destIndex+2] = src[srcIndex+2]
dest[destIndex+3] = src[srcIndex+3]
}
function SetColor(dest,destIndex,r,g,b,a){
dest[destIndex] = r
dest[destIndex+1] = g
dest[destIndex+2] = b
dest[destIndex+3] = a
}
function GenDiffMap(differenceColors,maindata,otherdata,width,height){
let sortedDifferenceColors = Object.keys(differenceColors).sort((a,b)=> differenceColors[b]-differenceColors[a]).filter(color=>{
for(let item in whitelistedColors)
{
if(DiffStrCol(whitelistedColors[item],color)<10)
{return true;}
}
return false;
})
let colmax = sortedDifferenceColors[0].split(',')
console.log(colmax)
let difference = GetDraw(width,height)
let differenceinfo = difference.data()
let differencedata = differenceinfo.data
for (let i = 0; i < maindata.length; i += 4) {
if(Diff(maindata,i,colmax,0)>50)
{SetColor(differencedata,i,0,0,0,0)}
else
{
if(Diff(maindata,i,otherdata,i)>100)
{SetRef(differencedata,i,maindata,i)}
else
{SetColor(differencedata,i,255,0,255,255)}
}
}
difference.setData(differenceinfo)
return difference.canvas
}
async function GenDiffMapPair(firstimg,secondimg){
let first = await GetAccessor(firstimg)
let second = await GetAccessor(secondimg)
let firstDifferenceColors = {}
let secondDifferenceColors = {}
let firstdata = first.data().data
let seconddata = second.data().data
for (let i = 0; i < firstdata.length; i += 4) {
if(Diff(firstdata,i,seconddata,i)>100)
{
AddColorFromData(firstDifferenceColors,firstdata,i)
AddColorFromData(secondDifferenceColors,seconddata,i)
}
}
let firstdiffmap = GenDiffMap(firstDifferenceColors,firstdata,seconddata,first.width,first.height);
let seconddiffmap = GenDiffMap(secondDifferenceColors,seconddata,firstdata,second.width,second.height);
return [{img: firstimg, diffmap:firstdiffmap},{img: secondimg, diffmap:seconddiffmap}]
}
window.addEventListener("load",()=>{//auto returns from error page
let dest = document.evaluate('//a[text()="HERE"]').iterateNext().href
if(dest){window.location = dest}
})
window.addEventListener("DOMContentLoaded", async () => {
await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
let spans = $('span[style="font-weight: bold; color: #d5f406"]');
let terms = spans.toArray().map(d=>'cap-'+d.innerText.split(', ').slice(0,2).sort().join('_'));
let numbers = spans.toArray().map(d=>d.innerText.split(', ')[2]);
console.log(numbers)
let images = $('img[indexvalue]');
let promises = new Array();
for(let i = 0;i<images.length;i+=2){promises.push(GenDiffMapPair(images[i],images[i+1]))}
let numProcessedImages = 0;
let numUsage = {}
for(let i in promises)
{
let result = await promises[i]
for(let item in result)
{
let data = await (worker.recognize(result[item].diffmap));
numbers.forEach(n=>{
if(data.data.text.includes(n)){
Increment(numUsage,n)
result[item].img.setAttribute('result',n)
return;
}
});
if(!result[item].img.getAttribute('result')) {result[item].img.style.cssText = "opacity:0.3"}
numProcessedImages++;
if(numProcessedImages == images.length)//done with all image recog
{
let remainder = new Array()
for(let item in numUsage)
{
let matching = $('img[indexvalue][result="'+item+'"]')
if(numUsage[item]===1)
{
matching.click()
spans.filter((_,d)=>d.innerText.includes(item)).css('color','#aaaaaa')
await new Promise(resolve => setTimeout(resolve, 500));
}
else
{
matching.each((_,d)=>{
if(d.style.cssText != "opacity:0.3")
{remainder.push(d)}
})
}
}
}
}
}
})
}