From 83d77dae2e76180ff5b54c16af183f3733a6ee88 Mon Sep 17 00:00:00 2001 From: ftbom Date: Sat, 5 Apr 2025 09:52:22 +0800 Subject: [PATCH] re-add manhuagui --- javascript/icon/zh.manhuagui.png | Bin 0 -> 3689 bytes javascript/manga/src/zh/manhuagui.js | 595 +++++++++++++++++++++++++++ 2 files changed, 595 insertions(+) create mode 100644 javascript/icon/zh.manhuagui.png create mode 100644 javascript/manga/src/zh/manhuagui.js diff --git a/javascript/icon/zh.manhuagui.png b/javascript/icon/zh.manhuagui.png new file mode 100644 index 0000000000000000000000000000000000000000..8ac7cf084038fc85e36f9b00bc4f857285d6e1b4 GIT binary patch literal 3689 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 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"], + } + }]; + } +}