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"); }); }; })();