From fc56c39bf4855401903af4689cd958aec24b4d39 Mon Sep 17 00:00:00 2001 From: XC-Pro <19840+xc-pro@noreply.example.org> Date: Wed, 12 Aug 2026 18:29:52 +0200 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=E3=80=8Cjs=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/孜然影视.js | 573 +++++++++++++++++++++++++++++++++++++++++++++++++ js/月光影视.js | 250 +++++++++++++++++++++ 2 files changed, 823 insertions(+) create mode 100644 js/孜然影视.js create mode 100644 js/月光影视.js diff --git a/js/孜然影视.js b/js/孜然影视.js new file mode 100644 index 0000000..2605d55 --- /dev/null +++ b/js/孜然影视.js @@ -0,0 +1,573 @@ +const _0x48c78e = _0x54f6; +(function (_0x3a7b4a, _0x58eae1) { + const _0x4c8dc3 = _0x54f6, _0x35fbe3 = _0x3a7b4a(); + while (!![]) { + try { + const _0x542978 = -parseInt(_0x4c8dc3(0xbb)) / (0x11c1 + -0x7 * 0xc2 + -0xc72) * (parseInt(_0x4c8dc3(0x10a)) / (0x3 * -0x591 + -0xd * -0x1c9 + -0x680)) + -parseInt(_0x4c8dc3(0xd8)) / (-0x98a + 0x1142 + -0x1 * 0x7b5) * (parseInt(_0x4c8dc3(0x12e)) / (-0xae6 + 0x2 * -0x11b1 + 0x2e4c)) + -parseInt(_0x4c8dc3(0xc3)) / (0xf1 * -0x8 + -0x9 * 0x192 + 0x15af) + parseInt(_0x4c8dc3(0x12f)) / (-0x5 * 0x4fb + 0x25ee + -0xd01) + -parseInt(_0x4c8dc3(0xa0)) / (0x221d * 0x1 + 0x3cd * 0x7 + 0x3 * -0x143b) + -parseInt(_0x4c8dc3(0x129)) / (-0x44a + 0x21b * 0x7 + -0x7 * 0x17d) * (parseInt(_0x4c8dc3(0xe6)) / (-0x1f5b + -0x158e + 0x34f2)) + parseInt(_0x4c8dc3(0x123)) / (-0x3c + -0x2dd * -0x8 + 0x2 * -0xb51); + if (_0x542978 === _0x58eae1) + break; + else + _0x35fbe3['push'](_0x35fbe3['shift']()); + } catch (_0x7090da) { + _0x35fbe3['push'](_0x35fbe3['shift']()); + } + } +}(_0x1e9c, -0x14f995 + -0x1b375 * -0x5 + 0x16ffe4)); +let host = _0x48c78e(0xea) + _0x48c78e(0xd3), headers = { 'User-Agent': _0x48c78e(0xf4) + _0x48c78e(0xcd) + _0x48c78e(0xb7) + _0x48c78e(0xe7) + _0x48c78e(0xdf) + _0x48c78e(0x103) + _0x48c78e(0xfa) + _0x48c78e(0xde) + _0x48c78e(0xb8) + _0x48c78e(0x12a) + _0x48c78e(0xb9) + _0x48c78e(0xc7) + _0x48c78e(0x11f) + _0x48c78e(0xe4) + _0x48c78e(0xa9) + _0x48c78e(0x126) }; +async function init(_0x9bf808) { +} +function _0x54f6(_0x9b69d, _0x3b17d3) { + const _0x1172b4 = _0x1e9c(); + return _0x54f6 = function (_0x4995e6, _0x53d438) { + _0x4995e6 = _0x4995e6 - (-0x4c3 + 0x755 * 0x1 + -0x1f2); + let _0x1f534e = _0x1172b4[_0x4995e6]; + return _0x1f534e; + }, _0x54f6(_0x9b69d, _0x3b17d3); +} +function getList(_0x20072d) { + const _0x5bc716 = _0x48c78e, _0x231d4b = { + 'PRLAd': function (_0x53aeed, _0x2d7483) { + return _0x53aeed && _0x2d7483; + }, + 'EfdfG': function (_0xddf542, _0x5f5c4a) { + return _0xddf542 + _0x5f5c4a; + }, + 'bcogk': _0x5bc716(0x10c), + 'BcNIl': function (_0x1f1ee8, _0x577a48, _0x5c0a59) { + return _0x1f1ee8(_0x577a48, _0x5c0a59); + }, + 'XNJcA': _0x5bc716(0xb6) + 'em' + }; + let _0x36de8c = [], _0x1e2c43 = _0x231d4b[_0x5bc716(0xf7)](pdfa, _0x20072d, _0x231d4b[_0x5bc716(0xa1)]); + return _0x1e2c43[_0x5bc716(0x122)](_0x5a9290 => { + const _0x5d2874 = _0x5bc716; + let _0x33172d = _0x5a9290[_0x5d2874(0xf8)](/detail\/id\/(\d+).html/), _0x1d7f97 = _0x5a9290[_0x5d2874(0xf8)](/title="(.*?)"/) || _0x5a9290[_0x5d2874(0xf8)](/alt="(.*?)"/), _0x5d05c7 = _0x5a9290[_0x5d2874(0xf8)](/data-original="(.*?)"/) || _0x5a9290[_0x5d2874(0xf8)](/src="(.*?)"/), _0x5adda3 = _0x5a9290[_0x5d2874(0xf8)](/
(.*?)<\/p>/s) || [ + '', + '' + ])[0xe5e + 0x1bcf + 0x1516 * -0x2][_0x162935(0x115)](/<.*?>/g, '')), + 'vod_play_from': _0x2d063d, + 'vod_play_url': _0x255937 + }] + }); +} +async function search(_0xcc2fac, _0x11f660, _0x10c825) { + const _0x3c2dcb = _0x48c78e, _0x37620f = { + 'jBGQl': function (_0x4ef2bd, _0x2c3bef) { + return _0x4ef2bd || _0x2c3bef; + }, + 'opeFo': function (_0x526496, _0x150358) { + return _0x526496 + _0x150358; + }, + 'NvAeg': function (_0x39f1d5, _0x2a82e8) { + return _0x39f1d5 > _0x2a82e8; + }, + 'edzDi': function (_0x477da0, _0x3f3ec0) { + return _0x477da0(_0x3f3ec0); + }, + 'clXmh': function (_0x2c117a, _0x1a8911) { + return _0x2c117a(_0x1a8911); + }, + 'iIdUe': function (_0x4e71dc, _0x18c868, _0x264bb4) { + return _0x4e71dc(_0x18c868, _0x264bb4); + }, + 'pEczO': function (_0x1fc3e6, _0x572b77) { + return _0x1fc3e6(_0x572b77); + } + }; + let _0x464799 = _0x37620f[_0x3c2dcb(0x11a)](_0x10c825, 0x7f * -0x2b + -0x1 * 0x218 + 0x176e), _0x3fb1f4 = _0x37620f[_0x3c2dcb(0xa6)](_0x37620f[_0x3c2dcb(0xa6)](host + (_0x3c2dcb(0xe1) + _0x3c2dcb(0x100) + 'h'), _0x37620f[_0x3c2dcb(0xfb)](_0x37620f[_0x3c2dcb(0xf3)](parseInt, _0x464799), -0x1 * -0x2d1 + 0xf57 + -0x1227) ? _0x3c2dcb(0x109) + _0x464799 : ''), _0x3c2dcb(0x105) + _0x37620f[_0x3c2dcb(0xfc)](encodeURIComponent, _0xcc2fac) + _0x3c2dcb(0xc5)), _0x2b47f1 = await _0x37620f[_0x3c2dcb(0xf0)](req, _0x3fb1f4, { 'headers': headers }); + return JSON[_0x3c2dcb(0xe2)]({ 'list': _0x37620f[_0x3c2dcb(0xc2)](getList, _0x2b47f1[_0x3c2dcb(0x104)]) }); +} +async function play(_0x20da54, _0x2cb770, _0x4fd940) { + const _0x3c0580 = _0x48c78e, _0x3d83af = { + 'gmpRQ': function (_0x4446bb, _0x3a33d1) { + return _0x4446bb + _0x3a33d1; + }, + 'pgqAT': function (_0x4a8928, _0x101ed7) { + return _0x4a8928 + _0x101ed7; + }, + 'qlsGE': _0x3c0580(0xe1) + _0x3c0580(0xcb) + _0x3c0580(0x116), + 'pyqKE': _0x3c0580(0xc5), + 'cIuHu': function (_0x5d3f0f, _0x4fcb0d, _0x52ba8c) { + return _0x5d3f0f(_0x4fcb0d, _0x52ba8c); + } + }; + let _0x1a8ab4 = _0x3d83af[_0x3c0580(0xae)](_0x3d83af[_0x3c0580(0xae)](_0x3d83af[_0x3c0580(0xbf)](host, _0x3d83af[_0x3c0580(0xa8)]), _0x2cb770), _0x3d83af[_0x3c0580(0xef)]), _0x184045 = await _0x3d83af[_0x3c0580(0x128)](req, _0x1a8ab4, { 'headers': headers }), _0x3c38b8 = _0x184045[_0x3c0580(0x104)][_0x3c0580(0xf8)](/"url":"([^"]+\.m3u8)"/); + if (_0x3c38b8) + return JSON[_0x3c0580(0xe2)]({ + 'parse': 0x0, + 'url': _0x3c38b8[-0x1c22 + 0x301 * -0x2 + 0x2225 * 0x1][_0x3c0580(0x115)](/\\/g, ''), + 'header': headers + }); + return JSON[_0x3c0580(0xe2)]({ + 'parse': 0x1, + 'url': _0x1a8ab4, + 'header': headers + }); +} +export default { + 'init': init, + 'home': home, + 'homeVod': homeVod, + 'category': category, + 'detail': detail, + 'search': search, + 'play': play +}; \ No newline at end of file diff --git a/js/月光影视.js b/js/月光影视.js new file mode 100644 index 0000000..7fb22e3 --- /dev/null +++ b/js/月光影视.js @@ -0,0 +1,250 @@ +/* +title: '月光影视', author: '小可乐/v5.12.1' +说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下 +"ext": { + "host": "xxxx", //站点网址 + "timeout": 6000 //请求超时,单位毫秒 +} +*/ +var HOST; +const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36'; +const DefHeader = {'User-Agent': MOBILE_UA}; +const KParams = { + headers: {'User-Agent': MOBILE_UA}, + timeout: 5000 +}; + +async function init(cfg) { + try { + let host = cfg.ext?.host?.trim() || 'https://www.dzwhs.com'; + HOST = host.replace(/\/$/, ''); + KParams.headers['Referer'] = HOST; + let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10); + KParams.timeout = parseTimeout > 0 ? parseTimeout : 5000; + KParams.resHtml = await request(HOST); + } catch (e) { + console.error('初始化参数失败:', e.message); + } +} + +async function home(filter) { + try { + let resHtml = KParams.resHtml; + if (!resHtml) {throw new Error('源码为空');} + let classes = cutStr(resHtml, '/zwhstp', '/a>', '', false, 1, true).map(it => { + let cName = cutStr(it, '>', '<', '分类名'); + let cId = cutStr(it, '/', '.', '分类值'); + return {type_name: cName, type_id: cId}; + }); + let filters = { + "1":[ + {"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"动作片","v":"6"},{"n":"喜剧片","v":"7"},{"n":"爱情片","v":"8"},{"n":"科幻片","v":"9"},{"n":"恐怖片","v":"10"},{"n":"剧情片","v":"11"},{"n":"战争片","v":"12"},{"n":"纪录片","v":"13"},{"n":"悬疑片","v":"14"},{"n":"犯罪片","v":"15"},{"n":"奇幻片","v":"16"},{"n":"动画片","v":"31"},{"n":"预告片","v":"32"}]} + ], + "2":[ + {"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"国产剧","v":"17"},{"n":"港台剧","v":"18"},{"n":"日韩剧","v":"20"},{"n":"欧美剧","v":"21"},{"n":"海外剧","v":"22"}]} + ], + "3":[ + {"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"大陆综艺","v":"23"},{"n":"日韩综艺","v":"24"},{"n":"欧美综艺","v":"25"},{"n":"港台综艺","v":"26"}]} + ], + "4":[ + {"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"国产动漫","v":"27"},{"n":"日韩动漫","v":"28"},{"n":"欧美动漫","v":"29"},{"n":"其他动漫","v":"30"}]} + ] + }; + return JSON.stringify({class: classes, filters: filters}); + } catch (e) { + console.error('获取分类失败:', e.message); + return JSON.stringify({class: [], filters: {}}); + } +} + +async function homeVod() { + try { + let resHtml = KParams.resHtml; + let VODS = getVodList(resHtml); + return JSON.stringify({list: VODS}); + } catch (e) { + console.error('推荐页获取失败:', e.message); + return JSON.stringify({list: []}); + } +} + +async function category(tid, pg, filter, extend) { + try { + pg = parseInt(pg, 10); + pg = pg > 0 ? pg : 1; + let cateUrl = `${HOST}/zwhstp/${extend?.cateId ?? tid}-${pg}.html`; + let resHtml = await request(cateUrl); + let VODS = getVodList(resHtml); + let pagecount = 999; + return JSON.stringify({list: VODS, page: pg, pagecount: pagecount, limit: 30, total: 30*pagecount}); + } catch (e) { + console.error('类别页获取失败:', e.message); + return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0}); + } +} + +async function search(wd, quick, pg) { + try { + pg = parseInt(pg, 10); + pg = pg > 0 ? pg : 1; + let searchUrl = `${HOST}/zwhstp/id.html?wd=${wd}&page=${pg}`; + let resHtml = await request(searchUrl); + let VODS = getVodList(resHtml); + return JSON.stringify({list: VODS, page: pg, pagecount: 10, limit: 30, total: 300}); + } catch (e) { + console.error('搜索页获取失败:', e.message); + return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0}); + } +} + +function getVodList(khtml) { + try { + if (!khtml) {throw new Error('源码为空');} + let kvods = []; + let listArr = cutStr(khtml, 'lazyload"', '/a>', '', false, 1, true); + for (let it of listArr) { + let kname = cutStr(it, 'title="', '"', '名称'); + let kpic = cutStr(it, 'data-original="', '"', '图片'); + let kremarks = cutStr(it, 'text-right">', '<', '状态'); + kvods.push({ + vod_name: kname, + vod_pic: kpic, + vod_remarks: kremarks, + vod_id: `${cutStr(it, 'href="', '"', 'Id')}@${kname}@${kpic}@${kremarks}` + }); + } + return kvods; + } catch (e) { + console.error(`生成视频列表失败:`, e.message); + return []; + } +} + +async function detail(ids) { + try { + let [id, kname, kpic, kremarks] = ids.split('@'); + let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id; + let resHtml = await request(detailUrl); + if (!resHtml) {throw new Error('源码为空');} + let intros = cutStr(resHtml, 'stui-content col-pd', 'play-btn', '', false); + let ktabs = cutStr(resHtml, 'pull-right">', '/h3>', '', false, 1, true).map((it,idx) => cutStr(it, 'title">', '<', `线-${idx+1}`)); + let kurls = cutStr(resHtml, '"stui-content__playlist', '', '', false, 1, true).map(item => { + let kurl = cutStr(item, '', '', false, 1, true).map(it => { return cutStr(it, '>', '<', 'noEpi') + '$' + cutStr(it, 'href="', '"', 'noUrl'); }); + return kurl.join('#'); + }); + let VOD = { + vod_id: detailUrl, + vod_name: kname, + vod_pic: kpic, + type_name: cutStr(intros, '类型:', '', '1000'), + vod_area: cutStr(intros, '地区:', '', '导演'), + vod_actor: cutStr(intros, '主演:', '
', '主演'), + vod_content: cutStr(intros, 'detail-content£>', '', '简介'), + vod_play_from: ktabs.join('$$$'), + vod_play_url: kurls.join('$$$') + }; + return JSON.stringify({list: [VOD]}); + } catch (e) { + console.error('详情页获取失败:', e.message); + return JSON.stringify({list: []}); + } +} + +async function play(flag, ids, flags) { + try { + let playUrl = !/^http/.test(ids) ? `${HOST}${ids}` : ids; + let kp = 0; + let resHtml = await request(playUrl); + let kcode = safeParseJSON(cutStr(resHtml, 'var player_£=', '<', '', false)); + let kurl = kcode?.url ?? ''; + if (!/m3u8|mp4|mkv/.test(kurl)) { + kp = 1; + kurl = playUrl; + } + return JSON.stringify({jx: 0, parse: kp, url: kurl, header: DefHeader}); + } catch (e) { + console.error('播放失败:', e.message); + return JSON.stringify({jx: 0, parse: 0, url: '', header: {}}); + } +} + +function cutStr(str, prefix = '', suffix = '', defaultVal = 'cutFaile', clean = true, i = 1, all = false) { + try { + if (!str || typeof str !== 'string') {throw new Error('被截取对象需为非空字符串');} + const dealStr = ds => String(ds).replace(/<[^>]*?>/g, ' ').replace(/( |\u00A0|\s)+/g, ' ').trim().replace(/\s+/g, ' '); + const esc = s => String(s).replace(/[.*+?${}()|[\]\\/^]/g, '\\$&'); + let pre = esc(prefix).replace(/£/g, '[^]*?'); + let end = esc(suffix); + let regex = new RegExp(`${pre ? pre : '^'}([^]*?)${end ? end : '$'}`, 'g'); + let matchArr = [...str.matchAll(regex)]; + if (all) { + return matchArr.map(it => { + const val = it[1] ?? defaultVal; + return clean && val !== defaultVal ? dealStr(val) : val; + }); + } + i = parseInt(i, 10); + if (isNaN(i) || i < 1) {throw new Error('序号需为大于0的整数');} + i = i - 1; + if (i >= matchArr.length) {throw new Error('序号越界');} + let result = matchArr[i][1] ?? defaultVal; + return clean && result !== defaultVal ? dealStr(result) : result; + } catch (e) { + console.error(`字符串截取失败:`, e.message); + return all ? ['cutErr'] : 'cutErr'; + } +} + +function safeParseJSON(jStr){ + try {return JSON.parse(jStr);} catch(e) {return null;} +} + +async function request(reqUrl, options = {}) { + try { + if (typeof reqUrl !== 'string' || !reqUrl.trim()) { throw new Error('reqUrl需为字符串且非空'); } + if (typeof options !== 'object' || Array.isArray(options) || !options) { throw new Error('options类型需为非null对象'); } + options.method = options.method?.toLowerCase() || 'get'; + if (['get', 'head'].includes(options.method)) { + delete options.data; + delete options.postType; + } else { + options.data = options.data ?? ''; + options.postType = options.postType?.toLowerCase() || 'form'; + } + let {headers, timeout, charset, toBase64 = false, ...restOpts } = options; + const optObj = { + headers: (typeof headers === 'object' && !Array.isArray(headers) && headers) ? headers : KParams.headers, + timeout: parseInt(timeout, 10) > 0 ? parseInt(timeout, 10) : KParams.timeout, + charset: charset?.toLowerCase() || 'utf-8', + buffer: toBase64 ? 2 : 0, + ...restOpts + }; + const res = await req(reqUrl, optObj); + if (options.withHeaders) { + const resHeaders = typeof res.headers === 'object' && !Array.isArray(res.headers) && res.headers ? res.headers : {}; + const resWithHeaders = { ...resHeaders, body: res?.content ?? '' }; + return JSON.stringify(resWithHeaders); + } + return res?.content ?? ''; + } catch (e) { + console.error(`${reqUrl}→请求失败:`, e.message); + return options?.withHeaders ? JSON.stringify({ body: '' }) : ''; + } +} + +export function __jsEvalReturn() { + return { + init: init, + home: home, + homeVod: homeVod, + category: category, + search: search, + detail: detail, + play: play, + proxy: null + }; +} \ No newline at end of file