您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
从to-corona-ex下载并解密图片,打包成 ZIP 格式下载
// ==UserScript== // @name to-corona-ex 漫画下载 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 从to-corona-ex下载并解密图片,打包成 ZIP 格式下载 // @author 丸玖 // @license MIT // @icon https://avatar.dmzj.com/70/86/7086ff9daebc44bb0555f462ba03c517.png // @match https://to-corona-ex.com/episodes/* // ==/UserScript== (function() { 'use strict'; const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js'; script.onload = init; document.body.appendChild(script); async function init() { const fetchPageData = async () => { const res = await fetch(window.location.href); const text = await res.text(); const pages = JSON.parse((text.match(/"pages":\s*(\[[^\]]+\])/)||[])[1] || '[]'); const title = (text.match(/"episode_title":\s*"([^"]+)"/)||[])[1] || '默认章节'; return { pages, title }; }; const decodeImage = (url, hash, i) => new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = 'Anonymous'; img.src = url; img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const [o, a, ...l] = Array.from(atob(hash)).map(c => c.charCodeAt(0)); const w = Math.floor(img.width / o), x = Math.floor(img.height / a); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); l.forEach((v, i) => { const c = v % o, u = Math.floor(v / o); const p = i % o, s = Math.floor(i / o); ctx.drawImage(img, c * w, u * x, w, x, p * w, s * x, w, x); }); resolve({ filename: `${String(i+1).padStart(2, '0')}.png`, dataUrl: canvas.toDataURL('image/png') }); }; img.onerror = () => reject(new Error(`加载图像失败: ${url}`)); }); const createZip = (images, title) => { const zip = new JSZip(); images.forEach(image => zip.file(image.filename, image.dataUrl.split(',')[1], { base64: true })); zip.generateAsync({ type: 'blob' }).then(content => { const link = document.createElement('a'); link.href = URL.createObjectURL(content); link.download = `${title}.zip`; link.click(); }).catch(console.error); }; // 创建下载按钮 const btn = document.createElement('button'); btn.textContent = '下载'; btn.style = 'position: fixed; top: 20px; right: 20px; padding: 10px 20px; font-size: 16px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; z-index: 1000;'; btn.onclick = async () => { btn.disabled = true; btn.textContent = '下载中...'; // 获取数据并处理图片 const { pages, title } = await fetchPageData(); const images = await Promise.all(pages.map(({ page_image_url, drm_hash }, i) => decodeImage(page_image_url, drm_hash, i))); // 创建 ZIP 文件 createZip(images, title); // 恢复按钮 btn.disabled = false; btn.textContent = '下载'; }; document.body.appendChild(btn); } })();