您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Manga downloader for piccoma.com
// ==UserScript== // @name PiccomaDownloader // @namespace https://github.com/Timesient/manga-download-scripts // @version 0.6 // @license GPL-3.0 // @author Timesient // @description Manga downloader for piccoma.com // @icon https://piccoma.com/static/web/img/common/favicon.ico // @homepageURL https://greasyforks.org/scripts/451876-piccomadownloader // @supportURL https://github.com/Timesient/manga-download-scripts/issues // @match https://piccoma.com/web/viewer/*/* // @require https://unpkg.com/[email protected]/dist/axios.min.js // @require https://unpkg.com/[email protected]/dist/jszip.min.js // @require https://unpkg.com/[email protected]/dist/FileSaver.min.js // @require https://update.greasyforks.org/scripts/451810/1398192/ImageDownloaderLib.js // @grant GM_info // @grant GM_xmlhttpRequest // @grant unsafeWindow // ==/UserScript== (async function(axios, JSZip, saveAs, ImageDownloader) { 'use strict'; // wait for the data and method generate by other scripts await new Promise(resolve => { const timer = setInterval(() => { if (unsafeWindow._pdata_ && unsafeWindow.dd && unsafeWindow.get_seed && unsafeWindow.unscrambleImg) { clearInterval(timer); resolve(); } }, 500); }); // generate title and data of images const title = unsafeWindow._pdata_.title; const imageData = unsafeWindow._pdata_.img.filter(img => img.path !== '').map(config => { const url = new URL('https:' + config.path); const sum = url.pathname.split('/')[4]; const expire = url.search.match(/\d{10}/)[0]; config.url = 'https:' + config.path; config.seed = unsafeWindow.dd(unsafeWindow.get_seed(sum, expire)); delete config.path; return config; }); // setup ImageDownloader ImageDownloader.init({ maxImageAmount: imageData.length, getImagePromises, title }); // collect promises of image function getImagePromises(startNum, endNum) { return imageData .slice(startNum - 1, endNum) .map(data => getDecryptedImage(data) .then(ImageDownloader.fulfillHandler) .catch(ImageDownloader.rejectHandler) ); } // get promise of decrypted image function getDecryptedImage(data) { return new Promise(async resolve => { const imageArrayBuffer = await new Promise(resolve => { GM_xmlhttpRequest({ method: 'GET', url: data.url, responseType: 'arraybuffer', onload: res => resolve(res.response) }); }); const image = document.createElement('img'); image.src = 'data:image/jpg;base64,' + window.btoa(new Uint8Array(imageArrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), '')); image.onload = function () { const result = unsafeWindow.unscrambleImg(image, 50, data.seed); result[0].toBlob(resolve); } }); } })(axios, JSZip, saveAs, ImageDownloader);