// ==UserScript==
// @name For Imhentai
// @namespace http://tampermonkey.net/
// @version 2.5
// @description 不翻墙下,更快加载 imhentai.xxx 的图片,并提供打包下载
// @author 水母
// @match https://imhentai.xxx/gallery/*
// @match https://*.imhentai.xxx/*
// @icon https://imhentai.xxx/images/logo.png
// @require https://cdn.jsdelivr.net/npm/jszip@3.6.0/dist/jszip.min.js#sha512-uVSVjE7zYsGz4ag0HEzfugJ78oHCI1KhdkivjQro8ABL/PRiEO4ROwvrolYAcZnky0Fl/baWKYilQfWvESliRA==
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_download
// @grant GM_openInTab
// @license MIT
// @downloadURL none
// ==/UserScript==
(function () {
"use strict";
// 全局数据
let IS_INIT = false;
/**
* 启动
*/
let IS_RUN = false;
let IS_DOWNLOADING = false;
// 页码序列 [cover.jpg, 1.jpg, ..., 30.jpg] : cover不计入页数; eg.总页数定为 30; 数组 [0] 定为 cover
/**
* 当前页码
*/
let CURRENT_PAGE = 0;
/**
* 最大浏览的页码,只增
*/
let MAX_BROWSE_PAGE = 0;
/**
* 已加载的页码
*/
let PAGE_LOADED = 0;
/**
* @desc 标识当前在哪个页面
*/
let CURRENT_URL;
/**
* @desc 页面枚举
*/
const CURRENT_URL_TYPE = {
/**
* @desc 标识在 https://imhentai.xxx/gallery/? 页面
*/
gallery: "gallery",
/**
* @desc 标识在 https://imhentai.xxx/view/? 页面
*/
view: "view",
/**
* @desc 标识在 https://?.imhentai.xxx/?/?/cover.jpg 页面
*/
imgPage: "imgPage",
/**
* @desc 标识在 测试 gallery 页面
*/
testGallery: "testGallery",
/**
* @desc 标识在 测试 imgPage 页面
*/
testImgPage: "testImgPage",
/**
* @desc 标识为无法识别页面
*/
unknow: "unknow",
};
/**
* 用户定义的下载页码区间
*/
let UserCustemRange = {
min: 0,
max: 0,
page_loaded: 0,
};
// enum
const CanEleID = {
/**
* 主体
*/
app: "can-app",
runBtn: "can-run",
previousBtn: "can-pre",
nextBtn: "can-next",
downloadBtn: "can-down",
scaleUpBtn: "can-sUp",
scaleResetBtn: "can-sReset",
scaleDownBtn: "can-sDown",
/**
* 页码
*/
pageLabel: "can-page",
/**
* 页码跳转
*/
changePageInput: "can-input",
/**
* 图片显示
*/
showImg: "can-img",
/**
* 图片显示外包
*/
showImgDiv: "can-img-div",
/**
* 转 base64
*/
canvas: "can-cvs",
};
const BtnText = {
runBtn: "启动🥰",
previousBtn: "⫷",
nextBtn: "⫸",
downloadBtn: "下载🥵",
scaleUpBtn: "⇲",
scaleResetBtn: "↺◲",
scaleDownBtn: "⇱",
};
/**
* FileReader 加载完毕计算器,由异步方法调用
*/
const CounterForFileReader = {
/**
* 异步锁
*/
is_lock: false,
count: 0,
/**
* 如果更新成功,返回 true
* @returns {boolean}
*/
update() {
if (this.is_lock) return false;
else {
this.is_lock = true;
this.count++;
this.is_lock = false;
return true;
}
},
};
// 避免没必要下载属性,被 JSON.stringify()
const keyImageBase64 = Symbol("imageBase64");
const keyImageScale = Symbol("imageScale");
/**
*
* @param {string} imgName
* @param {string} imgUrl
* @param {string} imgType
* @param {number} width
* @param {number} height
* @param {number} scale 仅用于页面浏览
* @param {string} imageBase64
*/
function ImgInfo(
imgName,
imgUrl = "",
imgType = "",
width = 0,
height = 0,
scale = 1.0,
imageBase64 = ""
) {
this.imgName = imgName;
this.imgUrl = imgUrl;
this.imgType = imgType;
this.width = width;
this.height = height;
this[keyImageScale] = scale;
this[keyImageBase64] = imageBase64;
}
/**
* 本子数据
* @param {string} name_en
* @param {string} name_sub
* @param {number} page
* @param {string} origin_url 原预览页面
* @param {string} root_url 图片的根地址
* @param {ImgInfo[]} imgInfoList
*/
function BzData(
name_en = "Null",
name_sub = "Null",
page = 0,
origin_url = "",
root_url = "",
imgInfoList = []
) {
this.name_en = name_en;
this.name_sub = name_sub;
this.page = page;
this.origin_url = origin_url;
this.root_url = root_url;
this.imgInfoList = imgInfoList;
}
/**
* BzData 迭代器
* @param {BzData} bzData
*/
function* BzDataIterator(bzData) {
let index = 0;
while (index < bzData.imgInfoList.length) {
let imgInfo = bzData.imgInfoList[index];
yield [index++, bzData.root_url, imgInfo];
}
}
/**
* 保存跳转下载的存储数据
*/
let downloadTabData = {
dataKey: "",
oriBzData: null,
};
//