mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 10:51:17 +00:00
add dmzj,copymanga,jmccomic
This commit is contained in:
595
javascript/manga/src/zh/copymanga.js
Normal file
595
javascript/manga/src/zh/copymanga.js
Normal file
@@ -0,0 +1,595 @@
|
||||
const mangayomiSources = [{
|
||||
"name": "拷贝漫画",
|
||||
"lang": "zh",
|
||||
"baseUrl": "https://www.mangacopy.com",
|
||||
"apiUrl": "https://api.mangacopy.com",
|
||||
"iconUrl": "https://hi77-overseas.mangafuna.xyz/static/free.ico",
|
||||
"typeSource": "single",
|
||||
"isManga": true,
|
||||
"isNsfw": false,
|
||||
"version": "0.0.1",
|
||||
"dateFormat": "",
|
||||
"dateFormatLocale": "",
|
||||
"pkgPath": "manga/src/zh/copymanga.js"
|
||||
}];
|
||||
|
||||
class DefaultExtension extends MProvider {
|
||||
stringUTF8(text) {
|
||||
var bytes = [];
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
bytes.push(text.charCodeAt(i));
|
||||
}
|
||||
var charCodes = [];
|
||||
var i = 0;
|
||||
while (i < bytes.length) {
|
||||
var byte1 = bytes[i];
|
||||
var charCode;
|
||||
|
||||
if (byte1 < 0x80) {
|
||||
charCode = byte1;
|
||||
i += 1;
|
||||
} else if (byte1 < 0xE0) {
|
||||
var byte2 = bytes[i + 1];
|
||||
charCode = ((byte1 & 0x1F) << 6) | (byte2 & 0x3F);
|
||||
i += 2;
|
||||
} else if (byte1 < 0xF0) {
|
||||
var byte2 = bytes[i + 1];
|
||||
var byte3 = bytes[i + 2];
|
||||
charCode = ((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);
|
||||
i += 3;
|
||||
} else {
|
||||
var byte2 = bytes[i + 1];
|
||||
var byte3 = bytes[i + 2];
|
||||
var byte4 = bytes[i + 3];
|
||||
charCode = ((byte1 & 0x07) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F);
|
||||
i += 4;
|
||||
}
|
||||
|
||||
charCodes.push(charCode);
|
||||
}
|
||||
return String.fromCharCode.apply(null, charCodes);
|
||||
}
|
||||
|
||||
base64encode(str) {
|
||||
const base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var out, i, len;
|
||||
var c1, c2, c3;
|
||||
len = str.length;
|
||||
i = 0;
|
||||
out = "";
|
||||
while (i < len) {
|
||||
c1 = str.charCodeAt(i++) & 0xff;
|
||||
if (i == len) {
|
||||
out += base64EncodeChars.charAt(c1 >> 2);
|
||||
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
|
||||
out += "==";
|
||||
break;
|
||||
}
|
||||
c2 = str.charCodeAt(i++);
|
||||
if (i == len) {
|
||||
out += base64EncodeChars.charAt(c1 >> 2);
|
||||
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
|
||||
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
|
||||
out += "=";
|
||||
break;
|
||||
}
|
||||
c3 = str.charCodeAt(i++);
|
||||
out += base64EncodeChars.charAt(c1 >> 2);
|
||||
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
|
||||
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
|
||||
out += base64EncodeChars.charAt(c3 & 0x3F);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
decode(result) {
|
||||
var iv = result.substring(0, 16);
|
||||
result = result.replace(iv, "");
|
||||
const bytes = [];
|
||||
for (var i = 0; i < result.length; i = i + 2) {
|
||||
bytes.push(parseInt(result.substr(i, 2), 16));
|
||||
}
|
||||
var charString = String.fromCharCode.apply(null, bytes);
|
||||
const data = this.base64encode(charString);
|
||||
const text = cryptoHandler(data, iv, "xxxmanga.woo.key", false);
|
||||
return text;
|
||||
}
|
||||
|
||||
getHeaders(url) {
|
||||
return {
|
||||
Referer: this.source.baseUrl
|
||||
};
|
||||
}
|
||||
|
||||
async getManga(url) {
|
||||
const res = await new Client().get(this.source.apiUrl + url);
|
||||
const datas = JSON.parse(res.body);
|
||||
const manga = [];
|
||||
for (const data of datas["results"]["list"]) {
|
||||
manga.push({
|
||||
name: this.stringUTF8(data["name"]),
|
||||
imageUrl: data["cover"],
|
||||
link: data["path_word"]
|
||||
});
|
||||
}
|
||||
return {
|
||||
list: manga,
|
||||
hasNextPage: true
|
||||
};
|
||||
}
|
||||
|
||||
async getPopular(page) {
|
||||
return await this.getManga(`/api/v3/comics?free_type=1&limit=16&offset=${(page-1)*16}&ordering=-popular&_update=true`);
|
||||
}
|
||||
|
||||
async getLatestUpdates(page) {
|
||||
return await this.getManga(`/api/v3/comics?free_type=1&limit=16&offset=${(page-1)*16}&ordering=-datetime_updated&_update=true`);
|
||||
}
|
||||
|
||||
async search(query, page, filters) {
|
||||
if (query != "") {
|
||||
const res = await new Client().get(this.source.apiUrl + `/api/v3/search/comic?platform=1&q=${query}&limit=16&offset=${(page -1)*16}&q_type=&_update=true`, {
|
||||
"webp": '1',
|
||||
"region": '1',
|
||||
"platform": '1',
|
||||
"version": '2022.10.20',
|
||||
"accept": 'application/json',
|
||||
'content-encoding': 'gzip, compress, br'
|
||||
});
|
||||
const datas = JSON.parse(res.body)["results"]["list"];
|
||||
const manga = [];
|
||||
for (const data of datas) {
|
||||
manga.push({
|
||||
name: this.stringUTF8(data["name"]),
|
||||
imageUrl: data["cover"],
|
||||
link: data["path_word"]
|
||||
});
|
||||
}
|
||||
return {
|
||||
list: manga,
|
||||
hasNextPage: true
|
||||
};
|
||||
}
|
||||
var type, region, sort;
|
||||
for (const filter of filters) {
|
||||
if (filter["type"] == "type") {
|
||||
type = filter["values"][filter["state"]]["value"];
|
||||
}
|
||||
if (filter["type"] == "region") {
|
||||
region = filter["values"][filter["state"]]["value"];
|
||||
}
|
||||
if (filter["type"] == "sort") {
|
||||
sort = filter["values"][filter["state"]]["value"];
|
||||
}
|
||||
}
|
||||
return await this.getManga(`/api/v3/comics?free_type=1&limit=16&offset=${(page-1)*16}&theme=${type}&top=${region}&ordering=${sort}&_update=true`);
|
||||
}
|
||||
|
||||
async getDetail(url) {
|
||||
const res = await new Client().get(this.source.apiUrl + `/api/v3/comic2/${url}`);
|
||||
const data = JSON.parse(res.body)["results"]["comic"];
|
||||
const title = this.stringUTF8(data["name"]);
|
||||
const cover = data["cover"];
|
||||
const desc = this.stringUTF8(data["brief"]);
|
||||
const author_ = [];
|
||||
for (const a of data["author"]) {
|
||||
author_.push(this.stringUTF8(a["name"]));
|
||||
}
|
||||
const author = author_.join(",");
|
||||
const status = data["status"]["value"];
|
||||
const genres = data["theme"].map(e => this.stringUTF8(e["name"]));
|
||||
const chapters = [];
|
||||
const res_ = await new Client().get(this.source.baseUrl + `/comicdetail/${url}/chapters`, {
|
||||
"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"
|
||||
});
|
||||
const ch_text = JSON.parse(res_.body)["results"];
|
||||
const chapter_datas = JSON.parse(this.decode(ch_text));
|
||||
for (const ch of chapter_datas["groups"]["default"]["chapters"]) {
|
||||
chapters.push({
|
||||
name: ch["name"],
|
||||
url: url + "|" + ch["id"]
|
||||
});
|
||||
}
|
||||
return {
|
||||
name: title,
|
||||
imageUrl: cover,
|
||||
description: desc,
|
||||
author: author,
|
||||
status: status,
|
||||
genre: genres,
|
||||
episodes: chapters,
|
||||
link: this.source.baseUrl + "/comic/" + url
|
||||
}
|
||||
}
|
||||
|
||||
async getPageList(url) {
|
||||
const urls = url.split("|");
|
||||
const res = await new Client().get(this.source.baseUrl + `/comic/${urls[0]}/chapter/${urls[1]}`, {
|
||||
"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"
|
||||
});
|
||||
const img_text = res.body.match(/contentKey="(.*)"/)[1];
|
||||
const results = JSON.parse(this.decode(img_text));
|
||||
return results.map(e => e["url"]);
|
||||
}
|
||||
|
||||
getFilterList() {
|
||||
return [{
|
||||
type: "type",
|
||||
name: "分类",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "全部",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "愛情",
|
||||
value: "aiqing"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "歡樂向",
|
||||
value: "huanlexiang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "冒险",
|
||||
value: "maoxian"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "奇幻",
|
||||
value: "qihuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "百合",
|
||||
value: "baihe"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "校园",
|
||||
value: "xiaoyuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "科幻",
|
||||
value: "kehuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "東方",
|
||||
value: "dongfang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "生活",
|
||||
value: "shenghuo"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "轻小说",
|
||||
value: "qingxiaoshuo"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "格鬥",
|
||||
value: "gedou"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "耽美",
|
||||
value: "danmei"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "悬疑",
|
||||
value: "xuanyi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "神鬼",
|
||||
value: "shengui"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "其他",
|
||||
value: "qita"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "职场",
|
||||
value: "zhichang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "萌系",
|
||||
value: "mengxi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "治愈",
|
||||
value: "zhiyu"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "長條",
|
||||
value: "changtiao"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "四格",
|
||||
value: "sige"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "舰娘",
|
||||
value: "jianniang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "节操",
|
||||
value: "jiecao"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "TL",
|
||||
value: "teenslove"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "竞技",
|
||||
value: "jingji"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "搞笑",
|
||||
value: "gaoxiao"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "伪娘",
|
||||
value: "weiniang"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "热血",
|
||||
value: "rexue"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "後宮",
|
||||
value: "hougong"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "美食",
|
||||
value: "meishi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "性转换",
|
||||
value: "xingzhuanhuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "侦探",
|
||||
value: "zhentan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "励志",
|
||||
value: "lizhi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "AA",
|
||||
value: "aa"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "彩色",
|
||||
value: "COLOR"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "音乐舞蹈",
|
||||
value: "yinyuewudao"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "异世界",
|
||||
value: "yishijie"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "战争",
|
||||
value: "zhanzheng"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "历史",
|
||||
value: "lishi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "机战",
|
||||
value: "jizhan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "惊悚",
|
||||
value: "jingsong"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "C99",
|
||||
value: "comiket99"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "恐怖",
|
||||
value: "恐怖"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "都市",
|
||||
value: "dushi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "C97",
|
||||
value: "comiket97"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "穿越",
|
||||
value: "chuanyue"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "C96",
|
||||
value: "comiket96"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "重生",
|
||||
value: "chongsheng"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "魔幻",
|
||||
value: "mohuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "宅系",
|
||||
value: "zhaixi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "武侠",
|
||||
value: "wuxia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "C98",
|
||||
value: "C98"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "生存",
|
||||
value: "shengcun"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "C95",
|
||||
value: "comiket95"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "FATE",
|
||||
value: "fate"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "無修正",
|
||||
value: "Uncensored"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "转生",
|
||||
value: "zhuansheng"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "LoveLive",
|
||||
value: "loveLive"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "男同",
|
||||
value: "nantong"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "仙侠",
|
||||
value: "xianxia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "玄幻",
|
||||
value: "xuanhuan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "真人",
|
||||
value: "zhenren"
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "region",
|
||||
name: "地区",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "全部",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "日本",
|
||||
value: "japan"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "韩国",
|
||||
value: "korea"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "欧美",
|
||||
value: "west"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "完结",
|
||||
value: "finish"
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "sort",
|
||||
name: "排序",
|
||||
type_name: "SelectFilter",
|
||||
values: [{
|
||||
type_name: "SelectOption",
|
||||
name: "更新时间⬇️",
|
||||
value: "-datetime_updated"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "更新时间⬆️",
|
||||
value: "datetime_updated"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "热度⬇️",
|
||||
value: "-popular"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "热度⬆️",
|
||||
value: "popular"
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
getSourcePreferences() {
|
||||
throw new Error("getSourcePreferences not implemented");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user