mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 19:01:15 +00:00
re-add manhuagui
This commit is contained in:
595
javascript/manga/src/zh/manhuagui.js
Normal file
595
javascript/manga/src/zh/manhuagui.js
Normal file
@@ -0,0 +1,595 @@
|
||||
const mangayomiSources = [{
|
||||
"name": "漫画柜",
|
||||
"lang": "zh",
|
||||
"baseUrl": "https://www.manhuagui.com",
|
||||
"apiUrl": "",
|
||||
"iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/zh.manhuagui.png",
|
||||
"typeSource": "single",
|
||||
"itemType": 0,
|
||||
"isNsfw": false,
|
||||
"version": "0.0.25",
|
||||
"dateFormat": "",
|
||||
"dateFormatLocale": "",
|
||||
"pkgPath": "manga/src/zh/manhuagui.js"
|
||||
}];
|
||||
|
||||
LZString = function() {
|
||||
function o(o, r) {
|
||||
if (!t[o]) {
|
||||
t[o] = {};
|
||||
for (var n = 0; n < o.length; n++) t[o][o.charAt(n)] = n
|
||||
}
|
||||
return t[o][r]
|
||||
}
|
||||
var r = String.fromCharCode,
|
||||
n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||
e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",
|
||||
t = {},
|
||||
i = {
|
||||
decompressFromBase64: function(r) {
|
||||
return null == r ? "" : "" == r ? null : i._decompress(r.length, 32, function(e) {
|
||||
return o(n, r.charAt(e))
|
||||
})
|
||||
},
|
||||
_decompress: function(o, n, e) {
|
||||
var t, i, s, p, u, c, a, l, f = [],
|
||||
h = 4,
|
||||
d = 4,
|
||||
m = 3,
|
||||
v = "",
|
||||
w = [],
|
||||
A = {
|
||||
val: e(0),
|
||||
position: n,
|
||||
index: 1
|
||||
};
|
||||
for (i = 0; 3 > i; i += 1) f[i] = i;
|
||||
for (p = 0, c = Math.pow(2, 2), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
|
||||
switch (t = p) {
|
||||
case 0:
|
||||
for (p = 0, c = Math.pow(2, 8), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
|
||||
l = r(p);
|
||||
break;
|
||||
case 1:
|
||||
for (p = 0, c = Math.pow(2, 16), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
|
||||
l = r(p);
|
||||
break;
|
||||
case 2:
|
||||
return ""
|
||||
}
|
||||
for (f[3] = l, s = l, w.push(l);;) {
|
||||
if (A.index > o) return "";
|
||||
for (p = 0, c = Math.pow(2, m), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
|
||||
switch (l = p) {
|
||||
case 0:
|
||||
for (p = 0, c = Math.pow(2, 8), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
|
||||
f[d++] = r(p), l = d - 1, h--;
|
||||
break;
|
||||
case 1:
|
||||
for (p = 0, c = Math.pow(2, 16), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
|
||||
f[d++] = r(p), l = d - 1, h--;
|
||||
break;
|
||||
case 2:
|
||||
return w.join("")
|
||||
}
|
||||
if (0 == h && (h = Math.pow(2, m), m++), f[l]) v = f[l];
|
||||
else {
|
||||
if (l !== d) return null;
|
||||
v = s + s.charAt(0)
|
||||
}
|
||||
w.push(v), f[d++] = s + v.charAt(0), h--, s = v, 0 == h && (h = Math.pow(2, m), m++)
|
||||
}
|
||||
}
|
||||
};
|
||||
return i
|
||||
}();
|
||||
|
||||
function decode(text) {
|
||||
function packed(functionStr, a, c, data) {
|
||||
function e(c) {
|
||||
return String(c < a ? '' : e(Math.floor(c / a))) + String((c % a > 35) ? String.fromCharCode(c % a + 29) : tr(c % a, 36));
|
||||
}
|
||||
|
||||
function tr(value, num) {
|
||||
var tmp = itr(value, num);
|
||||
return tmp == '' ? '0' : tmp;
|
||||
}
|
||||
|
||||
function itr(value, num) {
|
||||
const d = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
return value <= 0 ? '' : itr(Math.floor(value / num), num) + d[value % num];
|
||||
}
|
||||
|
||||
c = c - 1;
|
||||
const d = {};
|
||||
while (c + 1) {
|
||||
d[e(c)] = data[c] == '' ? e(c) : data[c];
|
||||
c -= 1;
|
||||
}
|
||||
const pieces = functionStr.split(/\b(\w+)\b/);
|
||||
const js = pieces.map(function(x) {
|
||||
return d[x] !== undefined ? d[x] : x;
|
||||
}).join('').replace(/\\'/g, '\'');
|
||||
return JSON.parse(js.match(/^.*\((\{.*\})\).*$/)[1]);
|
||||
}
|
||||
const m = text.match(/^.*\}\(\'(.*)\',(\d*),(\d*),\'([\w|\+|\/|=]*)\'.*$/);
|
||||
return packed(m[1], parseInt(m[2]), parseInt(m[3]), LZString.decompressFromBase64(m[4]).split('|'));
|
||||
}
|
||||
|
||||
class DefaultExtension extends MProvider {
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
|
||||
};
|
||||
|
||||
getHeaders(url) {
|
||||
return {
|
||||
Referer: this.source.baseUrl
|
||||
}
|
||||
}
|
||||
|
||||
async getItems(url, p) {
|
||||
const res = await new Client().get(this.source.baseUrl + url, this.headers);
|
||||
const doc = new Document(res.body);
|
||||
const mangas = [];
|
||||
const elements = doc.select(p);
|
||||
for (const element of elements) {
|
||||
const title = element.selectFirst("a").attr("title");
|
||||
const url = element.selectFirst("a").attr("href");
|
||||
var cover = element.selectFirst("img").attr("src");
|
||||
if (cover == "") {
|
||||
cover = element.selectFirst("img").attr("data-src");
|
||||
}
|
||||
cover = "https:" + cover;
|
||||
mangas.push({
|
||||
name: title,
|
||||
imageUrl: cover,
|
||||
link: url
|
||||
});
|
||||
}
|
||||
return {
|
||||
list: mangas,
|
||||
hasNextPage: true
|
||||
};
|
||||
}
|
||||
|
||||
async getPopular(page) {
|
||||
return await this.getItems(`/list/view_p${page}.html`, "ul#contList li");
|
||||
}
|
||||
|
||||
async getLatestUpdates(page) {
|
||||
return await this.getItems(`/list/index_p${page}.html`, "ul#contList li");
|
||||
}
|
||||
|
||||
async search(query, page, filters) {
|
||||
if (query == "") {
|
||||
var sort, locations, categories, status, reader;
|
||||
for (const filter of filters) {
|
||||
if (filter["type"] == "sort") {
|
||||
sort = filter["values"][filter["state"]]["value"];
|
||||
} else if (filter["type"] == "locations") {
|
||||
locations = filter["values"][filter["state"]]["value"];
|
||||
} else if (filter["type"] == "categories") {
|
||||
categories = filter["values"][filter["state"]]["value"];
|
||||
} else if (filter["type"] == "status") {
|
||||
status = filter["values"][filter["state"]]["value"];
|
||||
} else if (filter["type"] == "reader") {
|
||||
reader = filter["values"][filter["state"]]["value"];
|
||||
}
|
||||
}
|
||||
const params = [locations, categories, reader, status];
|
||||
return await this.getItems(`/list${"/"+params.filter(item => item != "").join("_")}/${sort}_p${page}.html`, "ul#contList li");
|
||||
} else {
|
||||
return await this.getItems(`/s/${query}_p${page}.html`, "div.book-result li");
|
||||
}
|
||||
}
|
||||
|
||||
async getDetail(url) {
|
||||
const res = await new Client().get(this.source.baseUrl + url, this.headers);
|
||||
const doc = new Document(res.body);
|
||||
const title = doc.selectFirst("div.book-title h1").text;
|
||||
const cover = "https:" + doc.selectFirst("p.hcover img").attr("src");
|
||||
const desc = doc.selectFirst("div#intro-all").text;
|
||||
const info = doc.select("ul.detail-list li")[1].select("span");
|
||||
const authors = info[1].text.replace("漫画作者:", "");
|
||||
const genres = info[0].select("a").map(e => e.text);
|
||||
const status_str = doc.selectFirst("li.status span").text;
|
||||
var status;
|
||||
if (status_str == "已完结") {
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
const eps = [];
|
||||
var chapter_html;
|
||||
if (res.body.search("请点击此处继续阅读!") == -1) {
|
||||
chapter_html = doc;
|
||||
} else {
|
||||
const text = LZString.decompressFromBase64(doc.selectFirst("input#__VIEWSTATE").attr("value"));
|
||||
chapter_html = new Document(text);
|
||||
}
|
||||
const ch_title = chapter_html.select("h4 span");
|
||||
const chapters = chapter_html.select("div.chapter-list")
|
||||
var index = 0;
|
||||
for (const chs of ch_title) {
|
||||
const t = chs.text;
|
||||
for (const ch of chapters[index].select("ul")) {
|
||||
const ep_ = [];
|
||||
for (const c of ch.select("a.status0")) {
|
||||
ep_.push({
|
||||
name: `|${t}|` + c.attr("title"),
|
||||
url: c.attr("href")
|
||||
});
|
||||
}
|
||||
ep_.reverse();
|
||||
for (const e of ep_) {
|
||||
eps.push(e);
|
||||
}
|
||||
}
|
||||
index = index + 1;
|
||||
}
|
||||
eps.reverse();
|
||||
return {
|
||||
name: title,
|
||||
imageUrl: cover,
|
||||
description: desc,
|
||||
genre: genres,
|
||||
author: authors,
|
||||
status: status,
|
||||
episodes: eps
|
||||
};
|
||||
}
|
||||
|
||||
async getPageList(url) {
|
||||
const preference = new SharedPreferences();
|
||||
const image_host = preference.get("imghost");
|
||||
const res = await new Client().get(this.source.baseUrl + url, this.headers);
|
||||
const datas = decode(res.body);
|
||||
const imgs = [];
|
||||
for (const data of datas["files"]) {
|
||||
imgs.push(`https://${image_host}.hamreus.com` + datas["path"] + data + `?e=${datas["sl"]["e"]}&m=${datas["sl"]["m"]}`);
|
||||
}
|
||||
return imgs;
|
||||
}
|
||||
|
||||
getFilterList() {
|
||||
return [{
|
||||
type: "sort",
|
||||
name: "排序",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "最新发布",
|
||||
value: "index"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "最新更新",
|
||||
value: "update"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "人气最旺",
|
||||
value: "view"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "评分最高",
|
||||
value: "rate"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "locations",
|
||||
name: "地区",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "全部",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "日本",
|
||||
value: "japan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "港台",
|
||||
value: "hongkong"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "其他",
|
||||
value: "other"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "欧美",
|
||||
value: "europe"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "内地",
|
||||
value: "china"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "韩国",
|
||||
value: "korea"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "categories",
|
||||
name: "剧情",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "全部",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "热血",
|
||||
value: "rexue"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "冒险",
|
||||
value: "maoxian"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "魔幻",
|
||||
value: "mohuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "神鬼",
|
||||
value: "shengui"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "搞笑",
|
||||
value: "gaoxiao"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "萌系",
|
||||
value: "mengxi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "爱情",
|
||||
value: "aiqing"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "科幻",
|
||||
value: "kehuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "魔法",
|
||||
value: "mofa"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "格斗",
|
||||
value: "gedou"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "武侠",
|
||||
value: "wuxia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "机战",
|
||||
value: "jizhan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "战争",
|
||||
value: "zhanzheng"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "竞技",
|
||||
value: "jingji"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "体育",
|
||||
value: "tiyu"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "校园",
|
||||
value: "xiaoyuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "生活",
|
||||
value: "shenghuo"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "励志",
|
||||
value: "lizhi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "历史",
|
||||
value: "lishi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "伪娘",
|
||||
value: "weiniang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "宅男",
|
||||
value: "zhainan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "腐女",
|
||||
value: "funv"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "耽美",
|
||||
value: "danmei"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "百合",
|
||||
value: "baihe"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "后宫",
|
||||
value: "hougong"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "治愈",
|
||||
value: "zhiyu"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "美食",
|
||||
value: "meishi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "推理",
|
||||
value: "tuili"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "悬疑",
|
||||
value: "xuanyi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "恐怖",
|
||||
value: "kongbu"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "四格",
|
||||
value: "sige"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "职场",
|
||||
value: "zhichang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "侦探",
|
||||
value: "zhentan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "社会",
|
||||
value: "shehui"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "音乐",
|
||||
value: "yinyue"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "舞蹈",
|
||||
value: "wudao"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "杂志",
|
||||
value: "zazhi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "黑道",
|
||||
value: "heidao"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "reader",
|
||||
name: "受众",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "全部",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "少女",
|
||||
value: "shaonv"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "少年",
|
||||
value: "shaonian"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "青年",
|
||||
value: "qingnian"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "儿童",
|
||||
value: "ertong"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "通用",
|
||||
value: "tongyong"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "status",
|
||||
name: "状态",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "全部",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "连载中",
|
||||
value: "lianzai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "已完结",
|
||||
value: "wanjie"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
getSourcePreferences() {
|
||||
return [{
|
||||
"key": "imghost",
|
||||
"listPreference": {
|
||||
"title": "图片服务器",
|
||||
"summary": "",
|
||||
"valueIndex": 0,
|
||||
"entries": ["通用", "欧洲", "美国"],
|
||||
"entryValues": ["i", "eu", "us"],
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user