NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Hentai Cafe Tweaks
// @namespace ProxyFiend.HentaiCafeTweaks
// @prefix HCT
// @author ProxyFiend
// @homepage https://openuserjs.org/scripts/ProxyFiend/Hentai_Cafe_Tweaks
// @supportURL https://openuserjs.org/scripts/ProxyFiend/Hentai_Cafe_Tweaks/issues
// @copyright 2020, ProxyFiend (https://openuserjs.org//users/ProxyFiend)
// @license MIT
// @version 1.4
// @description Tweaks Hentai Cafe, making it easier to use, and easier to save doujin for offline enjoyment.
// @include https://hentai.cafe/*
// @updateURL https://openuserjs.org/meta/ProxyFiend/Hentai_Cafe_Tweaks.meta.js
// @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery-scrollTo/1.4.2/jquery.scrollTo.min.js
// @require https://openuserjs.org/src/libs/ProxyFiend/jQuery_Binary_Ajax.js
// @require https://openuserjs.org/src/libs/ProxyFiend/ProxyFiendLib.js
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js
// @require https://kit.fontawesome.com/86ff082c1b.js
// @resource configCSS
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_notification
// ==/UserScript==
/*
* DO NOT CHANGE ANYTHING BEYOND HERE, UNLESS YOU KNOW WHAT YOU'RE DOING.
*/
(() => {
'use strict';
var zip = new JSZip();
var timer;
var deferreds = [];
var completed = [];
var progress = 0;
var path = window.location.pathname.substring(1);
path = path.split("/")
initConfig();
if (typeof path[0] !== "undefined") {
switch (path[0]) {
case "manga":
MangaPageScript();
break;
case "hc.fyi":
if (!isNaN(path[1])) {
DownloadPageScript();
}
break;
}
}
function MangaPageScript() {
var key_flag = false;
var key_scrolltimer;
jQuery(".inner>a").attr("onclick", "").unbind("click");
// Unbind events
jQuery(document).unbind("keydown");
jQuery(document).unbind("keyup");
jQuery(document).keydown((e) => {
if (!jQuery("input").is(":focus")) {
if (e.keyCode == 37 || e.keyCode == 65) {
e.preventDefault();
if (!key_flag) {
key_flag = true;
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
prevPage();
}
}
if (e.keyCode == 39 || e.keyCode == 68) {
e.preventDefault();
if (!key_flag) {
key_flag = true;
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
nextPage();
}
}
if (e.keyCode == 40 || e.keyCode == 83) {
e.preventDefault();
GM_debug("Triggered scroll down.");
if (!key_flag) {
key_flag = true;
key_scrolltimer = setInterval(() => {
window.scrollBy({
top: 13,
left: 0,
behavior: "instant"
});
}, 20);
}
}
if (e.keyCode == 38 || e.keyCode == 87) {
e.preventDefault();
if (!key_flag) {
key_flag = true;
key_scrolltimer = setInterval(() => {
window.scrollBy({
top: -13,
left: 0,
behavior: "instant"
});
}, 20);
}
}
}
});
jQuery(document).keyup((e) => {
key_scrolltimer = window.clearInterval(key_scrolltimer);
key_flag = false;
});
jQuery(".inner>a").click((e) => {
e.preventDefault();
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
nextPage();
});
var scriptElement = document.createElement("script");
scriptElement.text = "function changePage(e,r,t){return e=parseInt(e),(!initialized||e!=current_page)&&(initialized=!0,e>pages.length-1?(location.href=\"#\",!1):(e<0&&(current_page=0,e=0),preload(e),current_page=e,next=parseInt(e+1),jQuery(\"html, body\").stop(!0,!0),r||jQuery(\".panel\")[0].scrollIntoView(),!0!==pages[e].loaded?(jQuery(\"#page .inner img.open\").css({opacity:\"0\"}),jQuery(\"#page .inner img.open\").attr(\"src\",pages[e].url)):(jQuery(\"#page .inner img.open\").css({opacity:\"1\"}),jQuery(\"#page .inner img.open\").attr(\"src\",pages[e].url)),resizePage(e),t||History.pushState(null,null,base_url+\"page\/\"+(current_page+1)),jQuery(document).prop(\"title\",gt_page+\" \"+(current_page+1)+\" :: \"+title),update_numberPanel(),jQuery(\"#pagelist .current\").removeClass(\"current\"),jQuery(\"#ads_top_banner.iframe iframe\").attr(\"src\",site_url+\"content\/ads\/ads_top.html\"),jQuery(\"#ads_bottom_banner.iframe iframe\").attr(\"src\",site_url+\"content\/ads\/ads_bottom.html\"),!1))}";
document.body.appendChild(scriptElement);
};
function DownloadPageScript() {
jQuery("div.entry-content>div.last>p").append(
jQuery("<a/>").addClass("x-btn x-btn-flat x-btn-rounded x-btn-large").attr("title", "Download").append(
jQuery("<i/>").addClass("x-icon x-icon-download").attr("data-x-icon", "")).append(
jQuery("<span/>").text("Download")).css("height", "53.9844px")
.click(() => {
if (progress === 0) {
downloadDoujin();
jQuery("a[title='Download'] span").animate({
opacity: 0
}).queue((next) => {
jQuery("a[title='Download'] span").text("Downloading");
next();
}).animate({
width: "115px"
}).animate({
opacity: 1
});
}
}));
jQuery("body").append(
jQuery("<div/>").addClass("progress-bar").css({
position: "fixed",
bottom: "-10px",
height: "10px",
width: "100%",
margin: "0px",
background: "#121212"
}).append(
jQuery("<div/>").addClass("progress").css({
width: "0%",
height: "100%",
margin: "0px",
background: "#1e73be"
})
)
);
function deferredAddZip(url, filename, zip) {
var deferred = jQuery.Deferred();
jQuery.ajax({
url: url,
type: "GET",
dataType: "binary",
processData: false,
success: (result) => {
completed.push(filename);
zip.file(filename, result, {
binary: true
});
GM_debug("Loaded page: " + filename);
deferred.resolve(result);
},
error: (result) => {
deferred.reject(result);
}
});
return deferred;
};
function downloadDoujin() {
progress = 1;
jQuery("div.progress-bar").animate({
bottom: "0px"
}, {
duration: 200,
easing: "linear"
});
jQuery.ajax({
url: jQuery("a.x-btn[title='Read']").attr("href").replace("<br />", ""),
dataType: "html",
success: (data) => {
var obj = jQuery("<div/>").append(jQuery.parseHTML(data, true));
jQuery.globalEval(obj.find("#content>script")[0].innerText.substr(0, obj.find("#content>script")[0].innerText.indexOf("var next_chapter")));
GM_debug("Loaded page data.");
pages.forEach((page) => {
deferreds.push(deferredAddZip(page.url.replace("cdn.", ""), page.filename, zip));
GM_debug("Added page: " + page.filename);
});
timer = setInterval(() => {
var total = 0;
var loaded = 0;
var percentage = 0;
total = pages.length;
loaded = completed.length;
percentage = ((loaded / total) * 100);
GM_debug("Total: " + total + "; Loaded: " + loaded + "; Percentage: " + percentage);
jQuery("div.progress-bar>div.progress").animate({
width: percentage + "%"
}, {
duration: 200
});
}, 250);
jQuery.when.apply(jQuery, deferreds).done(() => {
clearInterval(timer);
jQuery("div.progress-bar>div.progress").animate({
width: "100%"
}, {
duration: 200
});
zip.generateAsync({
type: "blob"
})
.then((blob) => {
saveAs(blob, jQuery("div.entry-content>div.last>h3").text() + "." + GM_config.get("format").toLowerCase());
jQuery("a[title='Download'] span").animate({
opacity: 0
}).queue((next) => {
jQuery("a[title='Download'] span").text("Completed");
next();
}).animate({
width: "95px"
}).animate({
opacity: 1
});
setTimeout(() => {
jQuery("div.progress-bar").animate({
bottom: "-10px"
}, {
duration: 200,
easing: "linear"
});
}, 2000);
GM_notification({
title: "Hentai Cafe Downloader",
text: jQuery("div.entry-content>div.last>h3").text() + " has finished downloading. Enjoy!",
timeout: 2000
});
});
});
}
});
};
};
function initConfig() {
jQuery("body").append(
jQuery("<div/>").addClass("modal")
);
GM_registerMenuCommand("Hentai Cafe Config", () => {
GM_config.open();
});
GM_config.init({
"id": "hct-config",
"title": "Hentai Cafe Tweaks",
"fields": {
"format": {
"label": "Format",
"type": "select",
"options": ["ZIP", "CBZ"],
"default": "ZIP"
}
},
"frame": jQuery("div.modal")[0],
"css": "#hct-config *{font-family:arial,tahoma,myriad pro,sans-serif}#hct-config{background:#fff}#hct-config input[type=radio]{margin-right:8px}#hct-config .indent40{margin-left:40%}#hct-config .field_label{font-size:12px;font-weight:700;margin-right:6px}#hct-config .radio_label{font-size:12px}#hct-config .block{display:block}#hct-config .saveclose_buttons{margin:16px 10px 10px;padding:2px 12px}#hct-config .reset,#hct-config .reset a,#hct-config_buttons_holder{color:#000;text-align:right}#hct-config .config_header{font-size:20pt;margin:0}#hct-config .config_desc,#hct-config .reset,#hct-config .section_desc{font-size:9pt}#hct-config .center{text-align:center}#hct-config .section_header_holder{margin-top:8px}#hct-config .config_var{margin:0 0 4px}#hct-config .section_header{background:#414141;border:1px solid #000;color:#fff;font-size:13pt;margin:0}#hct-config .section_desc{background:#efefef;border:1px solid #ccc;color:#575757;font-size:9pt;margin:0 0 6px}.blur{filter:blur(5px) grayscale(.5);overflow:hidden}#hct-config *{font-family:inherit}#hct-config{z-index:9999;display:none;position:fixed;left:0;top:0;width:100%;height:100%;overflow:hidden;font-family:Lato,sans-serif;font-style:normal;font-weight:700;letter-spacing:.085em;background:0 0}#hct-config_wrapper{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);min-width:30%;max-width:80%;max-height:80%;border:1px solid #999;background-color:#202020}#hct-config .config_header{background-color:#121212;font-size:inherit}#hct-config .config_var{margin:0 10px 4px}#hct-config input{margin:auto;width:100%}#hct-config select{color:#999;width:100%;appearance:none;-moz-appearance:none;-webkit-appearance:none;background-image:url(\"data:image\/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='caret-down' class='svg-inline--fa fa-caret-down fa-w-10' role='img' xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 320 512'%3E%3Cpath fill='rgb(153, 153, 153)' d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'%3E%3C\/path%3E%3C\/svg%3E\");background-origin:content-box;background-repeat:no-repeat;background-position:right -.1rem center;background-size:12px}#hct-config #hct-config_buttons_holder{position:absolute;top:0;right:0;line-height:0}#hct-config .saveclose_buttons{border:none;background:0 0;color:#999;padding:0;margin:6px 4px;line-height:0}.animate-button{animation:.5s ease-in-out alternate saveAnim}@keyframes saveAnim{0%{transform:scale(1)}50%{transform:scale(1.2)}100%{transform:scale(1)}}#hct-config .reset_holder{display:none}.fa,.fas{font-family:\"Font Awesome 5 Free\"!important}",
"events": {
"open": () => {
GM_config.frame.setAttribute("style", "");
jQuery(".site").addClass("blur");
jQuery("#hct-config_saveBtn").html(jQuery("<i/>").addClass("fas fa-save"));
jQuery("#hct-config_closeBtn").html(jQuery("<i/>").addClass("fas fa-times-circle"))
jQuery(".config_var>input").attr("size", "")
},
"close": () => {
jQuery(".site").removeClass("blur");
},
"save": () => {
jQuery("#hct-config_saveBtn").addClass("animate-button")
}
}
})
jQuery("body").on("webkitAnimationEnd oanimationend msAnimationEnd animationend", () => {
jQuery("#hct-config_saveBtn").removeClass("animate-button");
});
};
})();