279 lines
15 KiB
JavaScript
279 lines
15 KiB
JavaScript
import { Crypto, load, _ } from './lib/cat.js';
|
||
|
||
/**
|
||
* 发布页:https://kan80.app/
|
||
*/
|
||
var charStr = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789';
|
||
let key = 'xinshijue';
|
||
let HOST = 'https://www.hdmyy.com';
|
||
let validUrl = HOST + '/index.php/verify/index.html?';
|
||
let validCheckUrl = 'https://www.hdmyy.com/index.php/ajax/verify_check?type=search&verify='
|
||
let siteKey = '';
|
||
let siteType = 0;
|
||
let COOKIE = 'PHPSESSID=' + randStr(26, true);
|
||
const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1';
|
||
let maxRetryTime = 5;
|
||
let currentRetryTime = 0;
|
||
async function request(reqUrl, timeout = 20000) {
|
||
let res = await req(reqUrl, {
|
||
method: 'get',
|
||
headers: {
|
||
'User-Agent': UA,
|
||
'Referer': HOST,
|
||
'Cookie': COOKIE
|
||
},
|
||
timeout: timeout,
|
||
});
|
||
return res.content;
|
||
}
|
||
|
||
// cfg = {skey: siteKey, ext: extend}
|
||
async function init(cfg) {
|
||
siteKey = cfg.skey;
|
||
siteType = cfg.stype;
|
||
}
|
||
|
||
async function home(filter) {
|
||
let classes = [{'type_id':1,'type_name':'电影'},{'type_id':2,'type_name':'电视剧'},{'type_id':3,'type_name':'综艺'},{'type_id':4,'type_name':'动漫'},{'type_id':63,'type_name':'纪录片'}];
|
||
let filterObj = {
|
||
'1':[{'key':'class','name':'剧情','init':'','value':[{'n':'全部','v':''},{'n':'喜剧','v':'喜剧'},{'n':'爱情','v':'爱情'},{'n':'恐怖','v':'恐怖'},{'n':'动作','v':'动作'},{'n':'科幻','v':'科幻'},{'n':'剧情','v':'剧情'},{'n':'战争','v':'战争'},{'n':'警匪','v':'警匪'},{'n':'犯罪','v':'犯罪'},{'n':'动画','v':'动画'},{'n':'奇幻','v':'奇幻'},{'n':'武侠','v':'武侠'},{'n':'冒险','v':'冒险'},{'n':'枪战','v':'枪战'},{'n':'恐怖','v':'恐怖'},{'n':'悬疑','v':'悬疑'},{'n':'惊悚','v':'惊悚'},{'n':'经典','v':'经典'},{'n':'青春','v':'青春'},{'n':'文艺','v':'文艺'},{'n':'微电影','v':'微电影'},{'n':'古装','v':'古装'},{'n':'历史','v':'历史'},{'n':'运动','v':'运动'},{'n':'农村','v':'农村'},{'n':'儿童','v':'儿童'},{'n':'网络电影','v':'网络电影'}]},{'key':'area','name':'地区','init':'','value':[{'n':'全部','v':''},{'n':'中国大陆','v':'中国大陆'},{'n':'中国香港','v':'中国香港'},{'n':'中国台湾','v':'中国台湾'},{'n':'美国','v':'美国'},{'n':'法国','v':'法国'},{'n':'英国','v':'英国'},{'n':'日本','v':'日本'},{'n':'韩国','v':'韩国'},{'n':'德国','v':'德国'},{'n':'泰国','v':'泰国'},{'n':'印度','v':'印度'},{'n':'意大利','v':'意大利'},{'n':'西班牙','v':'西班牙'},{'n':'加拿大','v':'加拿大'},{'n':'其他','v':'其他'}]},{'key':'year','name':'年份','init':'','value':[{'n':'全部','v':''},{'n':'2023','v':'2023'},{'n':'2022','v':'2022'},{'n':'2021','v':'2021'},{'n':'2020','v':'2020'},{'n':'2019','v':'2019'},{'n':'2018','v':'2018'},{'n':'2017','v':'2017'},{'n':'2016','v':'2016'},{'n':'2015','v':'2015'},{'n':'2014','v':'2014'},{'n':'2013','v':'2013'},{'n':'2012','v':'2012'},{'n':'2011','v':'2011'},{'n':'2010','v':'2010'}]},{'key':'by','name':'排序','value':[{'n':'时间','v':'time'},{'n':'人气','v':'hits'},{'n':'评分','v':'score'}]}],
|
||
'2':[{'key':'class','name':'剧情','init':'','value':[{'n':'全部','v':''},{'n':'爱情','v':'爱情'},{'n':'古装','v':'古装'},{'n':'悬疑','v':'悬疑'},{'n':'都市','v':'都市'},{'n':'喜剧','v':'喜剧'},{'n':'战争','v':'战争'},{'n':'剧情','v':'剧情'},{'n':'青春','v':'青春'},{'n':'历史','v':'历史'},{'n':'网剧','v':'网剧'},{'n':'奇幻','v':'奇幻'},{'n':'冒险','v':'冒险'},{'n':'励志','v':'励志'},{'n':'犯罪','v':'犯罪'},{'n':'商战','v':'商战'},{'n':'恐怖','v':'恐怖'},{'n':'穿越','v':'穿越'},{'n':'农村','v':'农村'},{'n':'人物','v':'人物'},{'n':'商业','v':'商业'},{'n':'生活','v':'生活'},{'n':'短剧','v':'短剧'},{'n':'其他','v':'其他'}]},{'key':'area','name':'地区','init':'','value':[{'n':'全部','v':''},{'n':'中国大陆','v':'中国大陆'},{'n':'中国香港','v':'中国香港'},{'n':'中国台湾','v':'中国台湾'},{'n':'韩国','v':'韩国'},{'n':'香港','v':'香港'},{'n':'台湾','v':'台湾'},{'n':'日本','v':'日本'},{'n':'美国','v':'美国'},{'n':'泰国','v':'泰国'},{'n':'英国','v':'英国'},{'n':'新加坡','v':'新加坡'},{'n':'其他','v':'其他'}]},{'key':'year','name':'年份','init':'','value':[{'n':'全部','v':''},{'n':'2023','v':'2023'},{'n':'2022','v':'2022'},{'n':'2021','v':'2021'},{'n':'2020','v':'2020'},{'n':'2019','v':'2019'},{'n':'2018','v':'2018'},{'n':'2017','v':'2017'},{'n':'2016','v':'2016'},{'n':'2015','v':'2015'},{'n':'2014','v':'2014'},{'n':'2013','v':'2013'},{'n':'2012','v':'2012'},{'n':'2011','v':'2011'},{'n':'2010','v':'2010'}]},{'key':'by','name':'排序','value':[{'n':'时间','v':'time'},{'n':'人气','v':'hits'},{'n':'评分','v':'score'}]}],
|
||
'3':[{'key':'class','name':'剧情','init':'','value':[{'n':'全部','v':''},{'n':'音乐','v':'音乐'},{'n':'情感','v':'情感'},{'n':'生活','v':'生活'},{'n':'职场','v':'职场'},{'n':'真人秀','v':'真人秀'},{'n':'搞笑','v':'搞笑'},{'n':'公益','v':'公益'},{'n':'艺术','v':'艺术'},{'n':'访谈','v':'访谈'},{'n':'益智','v':'益智'},{'n':'体育','v':'体育'},{'n':'少儿','v':'少儿'},{'n':'时尚','v':'时尚'},{'n':'人物','v':'人物'},{'n':'其他','v':'其他'}]},{'key':'area','name':'地区','init':'','value':[{'n':'全部','v':''},{'n':'中国大陆','v':'中国大陆'},{'n':'港台','v':'港台'},{'n':'韩国','v':'韩国'},{'n':'欧美','v':'欧美'},{'n':'其他','v':'其他'}]},{'key':'year','name':'年份','init':'','value':[{'n':'全部','v':''},{'n':'2023','v':'2023'},{'n':'2022','v':'2022'},{'n':'2021','v':'2021'},{'n':'2020','v':'2020'},{'n':'2019','v':'2019'},{'n':'2018','v':'2018'},{'n':'2017','v':'2017'},{'n':'2016','v':'2016'},{'n':'2015','v':'2015'},{'n':'2014','v':'2014'},{'n':'2013','v':'2013'},{'n':'2012','v':'2012'},{'n':'2011','v':'2011'},{'n':'2010','v':'2010'}]},{'key':'by','name':'排序','value':[{'n':'时间','v':'time'},{'n':'人气','v':'hits'},{'n':'评分','v':'score'}]}],
|
||
'4':[{'key':'class','name':'剧情','init':'','value':[{'n':'全部','v':''},{'n':'冒险','v':'冒险'},{'n':'战斗','v':'战斗'},{'n':'搞笑','v':'搞笑'},{'n':'经典','v':'经典'},{'n':'科幻','v':'科幻'},{'n':'玄幻','v':'玄幻'},{'n':'魔幻','v':'魔幻'},{'n':'武侠','v':'武侠'},{'n':'恋爱','v':'恋爱'},{'n':'推理','v':'推理'},{'n':'日常','v':'日常'},{'n':'校园','v':'校园'},{'n':'悬疑','v':'悬疑'},{'n':'真人','v':'真人'},{'n':'历史','v':'历史'},{'n':'竞技','v':'竞技'},{'n':'其他','v':'其他'}]},{'key':'area','name':'地区','init':'','value':[{'n':'全部','v':''},{'n':'中国大陆','v':'中国大陆'},{'n':'日本','v':'日本'},{'n':'韩国','v':'韩国'},{'n':'欧美','v':'欧美'},{'n':'其他','v':'其他'}]},{'key':'year','name':'年份','init':'','value':[{'n':'全部','v':''},{'n':'2023','v':'2023'},{'n':'2022','v':'2022'},{'n':'2021','v':'2021'},{'n':'2020','v':'2020'},{'n':'2019','v':'2019'},{'n':'2018','v':'2018'},{'n':'2017','v':'2017'},{'n':'2016','v':'2016'},{'n':'2015','v':'2015'},{'n':'2014','v':'2014'},{'n':'2013','v':'2013'},{'n':'2012','v':'2012'},{'n':'2011','v':'2011'},{'n':'2010','v':'2010'}]},{'key':'by','name':'排序','value':[{'n':'时间','v':'time'},{'n':'人气','v':'hits'},{'n':'评分','v':'score'}]}],
|
||
'63':[{'key':'by','name':'排序','value':[{'n':'时间','v':'time'},{'n':'人气','v':'hits'},{'n':'评分','v':'score'}]}],
|
||
};
|
||
|
||
return JSON.stringify({
|
||
class: classes,
|
||
filters: filterObj,
|
||
});
|
||
}
|
||
|
||
async function homeVod() {}
|
||
|
||
async function category(tid, pg, filter, extend) {
|
||
if (pg <= 0) pg = 1;
|
||
let page = '';
|
||
if (pg > 1) {
|
||
page = pg;
|
||
}
|
||
const link = HOST + '/vodshow/' + tid + '-' + (extend.area || '') + '-' + (extend.by || '') + '-' + (extend.class || '') + '-' + (extend.lang || '') + '-' + (extend.letter || '') + '---' + page + '---' + (extend.year || '') + '.html';
|
||
const html = await request(link);
|
||
const $ = load(html);
|
||
const items = $('.module-list .module-item');
|
||
const videos = _.map(items, (item) => {
|
||
const $item = $(item);
|
||
const link = $item.find('.module-item-content a:first').attr('href');
|
||
const title = $item.find('.video-name').text().trim();
|
||
const img = $item.find('.module-item-pic img:first').attr('data-src');
|
||
const remarks = $item.find('.module-item-text').text().trim();
|
||
return {
|
||
vod_id: link.replace(/.*?\/video\/(.*).html/g, '$1'),
|
||
vod_name: title,
|
||
vod_pic: img,
|
||
vod_remarks: remarks || '',
|
||
};
|
||
});
|
||
const hasMore = $('#page a.page-next:contains(下一页)').length > 0;
|
||
const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
|
||
const limit = 40;
|
||
return JSON.stringify({
|
||
page: parseInt(pg),
|
||
pagecount: pgCount,
|
||
limit: limit,
|
||
total: limit * pgCount,
|
||
list: videos,
|
||
});
|
||
}
|
||
|
||
async function detail(id) {
|
||
const html = await request(HOST + '/video/' + id + '.html');
|
||
const $ = load(html);
|
||
const vod = {
|
||
vod_id: id,
|
||
vod_name: $('h1.page-title').text().trim(),
|
||
vod_type: $('.video-info-aux a.tag-link:first').text().trim(),
|
||
vod_area: $('.video-info-aux a.tag-link:eq(2)').text().trim(),
|
||
vod_year: $('.video-info-aux a.tag-link:eq(1)').text().trim(),
|
||
vod_director: $('.video-info-main .video-info-items:contains(导演:)').text().substring(3).trim().replace(/(^\/|\/$)/g, '').trim(),
|
||
vod_actor: $('.video-info-main .video-info-items:contains(主演:)').text().substring(3).trim().replace(/(^\/|\/$)/g, '').trim(),
|
||
vod_pic: $('.video-cover img:first').attr('data-src'),
|
||
vod_remarks : $('.video-info-main .video-info-items:contains(备注:)').text().substring(3) || '',
|
||
vod_content: $('.video-info-main .video-info-items:contains(剧情:)').text().substring(3).trim().replace(/收起$/g, ''),
|
||
};
|
||
const playMap = {};
|
||
const tabs = $('.module-player-tab .module-tab-item');
|
||
const playlists = $('.module-player-list > .module-blocklist');
|
||
_.each(tabs, (tab, i) => {
|
||
const $tab = $(tab);
|
||
const from = $tab.find('span:first').text().trim();
|
||
if (from.includes('夸克')) return;
|
||
let list = playlists[i];
|
||
list = $(list).find('a');
|
||
_.each(list, (it) => {
|
||
const $it = $(it);
|
||
const title = $it.find('span:first').text().trim();
|
||
const playUrl = $it.attr('href');
|
||
if (!playMap.hasOwnProperty(from)) {
|
||
playMap[from] = [];
|
||
}
|
||
playMap[from].push(title + '$' + playUrl);
|
||
});
|
||
});
|
||
vod.vod_play_from = _.keys(playMap).join('$$$');
|
||
const urls = _.values(playMap);
|
||
const vod_play_url = _.map(urls, (urlist) => {
|
||
return urlist.join('#');
|
||
});
|
||
vod.vod_play_url = vod_play_url.join('$$$');
|
||
return JSON.stringify({
|
||
list: [vod],
|
||
});
|
||
}
|
||
|
||
async function play(flag, id, flags) {
|
||
const link = HOST + id;
|
||
const html = await request(link);
|
||
let $ = load(html);
|
||
let json = $('script:contains(player_aaaa)').text().replace('var player_aaaa=','');
|
||
let js = JSON.parse(json);
|
||
let playUrl = js.url;
|
||
if (js.encrypt == 1) {
|
||
playUrl = unescape(playUrl);
|
||
} else if (js.encrypt == 2) {
|
||
playUrl = unescape(base64Decode(playUrl));
|
||
}
|
||
//console.log('playUrl', playUrl);
|
||
//https://jx3.xn--1lq90i13mxk5bolhm8k.xn--fiqs8s/player/ec.php?code=zj&if=1&url=
|
||
let playHtml = await request('https://jx3.xn--1lq90i13mxk5bolhm8k.xn--fiqs8s/player/ec.php?code=zj&if=1&url=' + playUrl);
|
||
json = playHtml.match(/let ConFig = {([\w\W]*)},box/)[1];
|
||
const jsConfig = JSON.parse('{' + json.trim() + '}');
|
||
playUrl = decryptUrl(jsConfig);
|
||
return JSON.stringify({
|
||
parse: 0,
|
||
url: playUrl,
|
||
header: {
|
||
'User-Agent': UA,
|
||
}
|
||
});
|
||
}
|
||
|
||
function decryptUrl(jsConfig) {
|
||
const key = Crypto.enc.Utf8.parse('2890' + jsConfig.config.uid + 'tB959C');
|
||
const iv = Crypto.enc.Utf8.parse('2F131BE91247866E');
|
||
const mode = Crypto.mode.CBC;
|
||
const padding = Crypto.pad.Pkcs7;
|
||
const decrypted = Crypto.AES.decrypt(jsConfig.url, key, {
|
||
'iv': iv,
|
||
'mode': mode,
|
||
'padding': padding
|
||
});
|
||
const decryptedUrl = Crypto.enc.Utf8.stringify(decrypted);
|
||
return decryptedUrl;
|
||
}
|
||
|
||
function base64Decode(text) {
|
||
return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
|
||
}
|
||
|
||
async function search(wd, quick, pg) {
|
||
try{
|
||
if (!pg) pg = '';
|
||
let html = await request(HOST + '/vod-s/'+wd+'----------'+pg+'---.html');
|
||
const $ = load(html);
|
||
const title = $('title').text();
|
||
if(currentRetryTime >= maxRetryTime) {
|
||
currentRetryTime = 0;
|
||
return '{}';
|
||
}
|
||
if(title === '系统安全验证') {
|
||
currentRetryTime = currentRetryTime + 1;
|
||
if(currentRetryTime >= 1) {
|
||
await sleep(5000);
|
||
}
|
||
await validCode(validUrl);
|
||
return await search(wd, quick, pg);
|
||
} else {
|
||
const cards = $('div.module-item-pic');
|
||
let videos = _.map(cards, (n) => {
|
||
let id = $($(n).find('a')[0]).attr('href');
|
||
let name = $($(n).find('a')[0]).attr('title').replaceAll('立刻播放', '');
|
||
let pic = $($(n).find('img')[0]).attr('data-src');
|
||
return {
|
||
vod_id: id,
|
||
vod_name: name,
|
||
vod_pic: pic,
|
||
vod_remarks: '',
|
||
};
|
||
});
|
||
return JSON.stringify({
|
||
list: videos,
|
||
});
|
||
}
|
||
currentRetryTime = 0;
|
||
} catch(error) {
|
||
currentRetryTime = 0;
|
||
return '{}';
|
||
}
|
||
|
||
}
|
||
|
||
async function validCode(url) {
|
||
try {
|
||
//获取验证码的base64
|
||
const res = await req(url, {
|
||
buffer: 2,
|
||
headers: {
|
||
'User-Agent': UA,
|
||
'Referer': HOST,
|
||
'Cookie': COOKIE
|
||
}
|
||
});
|
||
const response = await req('https://api.nn.ci/ocr/b64/text', {
|
||
method: 'post',
|
||
data: res.content,
|
||
headers: {
|
||
'Content-Type': 'text/plain',
|
||
},
|
||
});
|
||
if(response['code'] === 200) {
|
||
let checkRes = await request(validCheckUrl + response.content);
|
||
}
|
||
} catch (error) {
|
||
console.error(error);
|
||
}
|
||
}
|
||
|
||
function randStr(len, withNum) {
|
||
var _str = '';
|
||
let containsNum = withNum === undefined ? true : withNum;
|
||
for (var i = 0; i < len; i++) {
|
||
let idx = _.random(0, containsNum ? charStr.length - 1 : charStr.length - 11);
|
||
_str += charStr[idx];
|
||
}
|
||
return _str;
|
||
}
|
||
|
||
function sleep(ms) {
|
||
//return new Promise(resolve => setTimeout(resolve, ms));
|
||
let now = new Date();
|
||
const exitTime = now.getTime() + ms;
|
||
while(true) {
|
||
now = new Date();
|
||
if(now.getTime() > exitTime) return;
|
||
}
|
||
}
|
||
|
||
|
||
export function __jsEvalReturn() {
|
||
return {
|
||
init: init,
|
||
home: home,
|
||
homeVod: homeVod,
|
||
category: category,
|
||
detail: detail,
|
||
play: play,
|
||
search: search,
|
||
validCode: validCode,
|
||
};
|
||
} |