Sync all projects

This commit is contained in:
github-actions[bot]
2026-07-22 14:45:04 +00:00
parent fb3776ddc4
commit 50f3df720b
64 changed files with 21626 additions and 24957 deletions
Binary file not shown.
Binary file not shown.
-17
View File
@@ -68,23 +68,6 @@
"api": "csp_Hxq",
"ext": "http://www.小不点.com/api/2026/fishhxq.php"
},
{
"key": "无极99",
"name": "无极 • APP",
"type": 3,
"api": "csp_App99",
"ext": {
"host": "http://111.170.140.70:19987/app/bn",
"LoginPath": "/app/log",
"version": "",
"appkey": "c403317c2a2946659b0bcbabdd5de43a",
"versionName": "1.0.1",
"name": "无极影视",
"package": "com.wujiys.app",
"buildNumber": "2001",
"buildSignature": "A0859BDC35AD3E81D4051E2A4678C77C62773EDB3423DDF1DEFF94CB331D398E"
}
},
{
"key": "橙子99",
"name": "橙子 • APP",
+567
View File
@@ -0,0 +1,567 @@
/*
@header({
searchable: 1,
filterable: 1,
quickSearch: 1,
title: '短剧聚合1[DRPY]',
author: 'Gemini',
'类型': '短剧',
lang: 'ds'
})
*/
globalThis.aggConfig = {
keys: 'd3dGiJc651gSQ8w1',
charMap: {
'+': 'P', '/': 'X', '0': 'M', '1': 'U', '2': 'l', '3': 'E', '4': 'r', '5': 'Y', '6': 'W', '7': 'b', '8': 'd', '9': 'J',
'A': '9', 'B': 's', 'C': 'a', 'D': 'I', 'E': '0', 'F': 'o', 'G': 'y', 'H': '_', 'I': 'H', 'J': 'G', 'K': 'i', 'L': 't',
'M': 'g', 'N': 'N', 'O': 'A', 'P': '8', 'Q': 'F', 'R': 'k', 'S': '3', 'T': 'h', 'U': 'f', 'V': 'R', 'W': 'q', 'X': 'C',
'Y': '4', 'Z': 'p', 'a': 'm', 'b': 'B', 'c': 'O', 'd': 'u', 'e': 'c', 'f': '6', 'g': 'K', 'h': 'x', 'i': '5', 'j': 'T',
'k': '-', 'l': '2', 'm': 'z', 'n': 'S', 'o': 'Z', 'p': '1', 'q': 'V', 'r': 'v', 's': 'j', 't': 'Q', 'u': '7', 'v': 'D',
'w': 'w', 'x': 'n', 'y': 'L', 'z': 'e'
},
headers: {
default: { 'User-Agent': 'okhttp/3.12.11', 'content-type': 'application/json; charset=utf-8' }
},
platform: {
星芽: { host: 'https://app.whjzjx.cn', url1: '/cloud/v2/theater/home_page?theater_class_id', url2: '/v2/theater_parent/detail', search: '/v3/search', classes: '/cloud/v2/theater/classes', rankDetail: '/cloud/v1/first_level_ranking/detail', loginUrl: 'https://u.shytkjgs.com/user/v1/account/login' },
西饭: { host: 'https://xifan-api-cn.youlishipin.com', url1: '/xifan/drama/portalPage', url2: '/xifan/drama/getDuanjuInfo', search: '/xifan/search/getSearchList' },
七猫: { host: 'https://api-store.qmplaylet.com', url1: '/api/v1/playlet/index', url2: 'https://api-read.qmplaylet.com/player/api/v1/playlet/info', search: '/api/v1/playlet/search' },
围观: { host: 'https://api.drama.9ddm.com', url1: '/drama/home/shortVideoTags', url2: '/drama/home/shortVideoDetail', search: '/drama/home/search' },
河马: { host: 'https://www.kuaikaw.cn', search: '/seo/video/6007' }
},
platformList: [
{ name: '七猫短剧', id: '七猫' },
{ name: '星芽短剧', id: '星芽' },
{ name: '西饭短剧', id: '西饭' },
{ name: '围观短剧', id: '围观' },
{ name: '河马短剧', id: '河马' }
],
search: { limit: 30, timeout: 6000 }
};
// ==================== 工具辅助函数 ====================
async function md5(str) {
return CryptoJS.MD5(str).toString(CryptoJS.enc.Hex).toLowerCase();
}
function base64Encode(text) {
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text));
}
function base64Decode(text) {
return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text));
}
function stripHtml(text) {
return String(text || '').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();
}
function joinTags(tags) {
if (Array.isArray(tags)) {
return tags.map(tag => {
if (!tag) return '';
if (typeof tag === 'string') return tag;
return tag.name || tag.title || tag.label || tag.text || '';
}).filter(Boolean).join(' ');
}
return String(tags || '');
}
function buildSearchRemark(platform, episodeText = '', extra = '') {
const parts = [platform];
const ep = String(episodeText || '').trim();
if (ep) parts.push(/集|期|完结|更新/.test(ep) ? ep : `${ep}`);
const suffix = String(extra || '').trim();
return suffix ? `${parts.join('')} ${suffix}` : parts.join('');
}
function parseNextData(html) {
try {
const match = String(html || '').match(/<script id="__NEXT_DATA__" type="application\/json">([\s\S]*?)<\/script>/);
return match?.[1] ? JSON.parse(match[1]) : null;
} catch (e) {
return null;
}
}
function normalizeHemaSearchBook(book) {
if (!book?.bookId) return null;
return {
vod_id: `河马@/drama/${book.bookId}`,
vod_name: book.bookName,
vod_pic: book.coverWap,
vod_remarks: buildSearchRemark('河马短剧', `${book.statusDesc || (book.status === 1 ? '完本' : '更新中') || ''} ${book.totalChapterNum || ''}`.trim()),
vod_tag: joinTags(book.bookTypeThree || book.tags || book.categoryName || book.categoryNames),
vod_content: [book.introduction, book.desc, book.bookDesc, book.actor, book.actress].filter(Boolean).join(' ')
};
}
function buildHemaTmpId() {
return Math.random().toString(36).slice(2, 18);
}
function getHemaHeaders(referer = 'https://www.kuaikaw.cn') {
return {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
Referer: referer,
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8'
};
}
function getHemaApiHeaders(referer) {
return {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
Referer: referer,
Origin: 'https://www.kuaikaw.cn',
'Content-Type': 'application/json',
Accept: 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
pname: 'www.kuaikaw.cn',
tmpid: buildHemaTmpId()
};
}
async function getQmParamsAndSign() {
const sessionId = Math.floor(Date.now()).toString();
const data = {
"static_score": "0.8", "uuid": "00000000-7fc7-08dc-0000-000000000000",
"device-id": "20250220125449b9b8cac84c2dd3d035c9052a2572f7dd0122edde3cc42a70",
"sourceuid": "aa7de295aad621a6", "refresh-type": "0", "model": "22021211RC",
"client-id": "aa7de295aad621a6", "brand": "Redmi", "sys-ver": "12", "phone-level": "H",
"wlb-uid": "aa7de295aad621a6", "session-id": sessionId
};
const jsonStr = JSON.stringify(data);
const base64Str = btoa(unescape(encodeURIComponent(jsonStr)));
let qmParams = '';
for (let i = 0; i < base64Str.length; i++) {
qmParams += globalThis.aggConfig.charMap[base64Str[i]] || base64Str[i];
}
const paramsStr = `AUTHORIZATION=app-version=10001application-id=com.duoduo.readchannel=unknownis-white=net-env=5platform=androidqm-params=${qmParams}reg=${globalThis.aggConfig.keys}`;
return { qmParams, sign: await md5(paramsStr) };
}
async function getHeaderX() {
const { qmParams, sign } = await getQmParamsAndSign();
return {
'net-env': '5', 'reg': '', 'channel': 'unknown', 'is-white': '', 'platform': 'android',
'application-id': 'com.duoduo.read', 'authorization': '', 'app-version': '10001',
'user-agent': 'webviewversion/0', 'qm-params': qmParams, 'sign': sign
};
}
// ==================== 主规则对象 ====================
var rule = {
类型: '短剧',
title: '聚合短剧1[短]',
author: 'Gemini',
host: '',
url: '',
searchUrl: '*',
searchable: 1,
quickSearch: 1,
filterable: 1,
timeout: 5000,
play_parse: true,
search_match: true,
headers: globalThis.aggConfig.headers.default,
filter_url: '{{fl.area}}',
filter_def: {
星芽: { area: '1', class2: '0', rank: '1' },
西饭: { area: '都市' },
七猫: { area: '0' },
围观: { area: '' },
河马: { area: '462' }
},
filter: {
七猫: [{
key: 'area', name: '分类',
value: [
{ n: '全部', v: '0' }, { n: '男频', v: '1' }, { n: '新剧', v: '3' }, { n: '现代言情', v: '21' },
{ n: '神豪', v: '37' }, { n: '萌宝', v: '356' }, { n: '穿越', v: '373' }, { n: '战神', v: '527' },
{ n: '神医', v: '1269' }, { n: '古装', v: '1272' }
]
}],
星芽: [{
key: 'area', name: '剧场',
value: [
{ n: '剧场', v: '1' }, { n: '热播短剧', v: '2' }, { n: '会员专享', v: '8' },
{ n: '星选好剧', v: '7' }, { n: '新剧', v: '3' }, { n: '阳光剧场', v: '5' }, { n: '排行榜', v: '9' }
]
}, {
key: 'class2', name: '类型',
value: [
{ n: '全部', v: '0' }, { n: '都市', v: '4' }, { n: '逆袭', v: '7' }, { n: '古装', v: '5' },
{ n: '亲情', v: '41' }, { n: '现代言情', v: '15' }, { n: '重生', v: '6' }, { n: '虐恋', v: '8' },
{ n: '玄幻', v: '35' }, { n: '穿越', v: '17' }, { n: '脑洞', v: '32' }, { n: '甜宠', v: '33' },
{ n: '古代言情', v: '37' }, { n: '战神', v: '24' }, { n: '历史', v: '40' }, { n: '赘婿', v: '26' },
{ n: '萌宝', v: '9' }, { n: '神医', v: '25' }
]
}, {
key: 'rank', name: '榜单',
value: [
{ n: '实时热榜', v: '1' }, { n: '热搜榜', v: '2' }, { n: '新剧榜', v: '3' },
{ n: '剧单榜', v: '4' }, { n: '口碑榜', v: '5' }
]
}],
西饭: [{
key: 'area', name: '分类',
value: [
{ n: '都市', v: '都市' }, { n: '甜宠', v: '甜宠' }, { n: '逆袭', v: '逆袭' },
{ n: '战神', v: '战神' }, { n: '古装', v: '古装' }, { n: '穿越', v: '穿越' }, { n: '萌宝', v: '萌宝' }
]
}],
围观: [{
key: 'area', name: '分类',
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: '分类',
value: [
{ n: '甜宠', v: '462' }, { n: '古装仙侠', v: '1102' }, { n: '现代言情', v: '1145' },
{ n: '青春', v: '1170' }, { n: '豪门恩怨', v: '585' }, { n: '逆袭', v: '417-464' },
{ n: '重生', v: '439-465' }, { n: '系统', v: '1159' }, { n: '总裁', v: '1147' }, { n: '职场商战', v: '943' }
]
}]
},
预处理: async function () {
const cfg = globalThis.aggConfig;
try {
const data = { 'device': '24250683a3bdb3f118dff25ba4b1cba1a' };
const options = {
method: 'POST',
headers: { 'User-Agent': 'okhttp/4.10.0', 'platform': '1', 'Content-Type': 'application/json' },
body: JSON.stringify(data)
};
let html = await request(cfg.platform.星芽.loginUrl, options);
const res = JSON.parse(html);
const token = res?.data?.token || res?.token;
this.xingya_headers = { ...rule.headers, authorization: token };
} catch (e) {
log(`星芽短剧token获取失败: ${e.message}`);
this.xingya_headers = rule.headers;
}
},
class_parse: () => ({
class: globalThis.aggConfig.platformList.map(item => ({
type_id: item.id,
type_name: item.name
}))
}),
推荐: async function () {
const cfg = globalThis.aggConfig;
const randomPlat = cfg.platformList[Math.floor(Math.random() * cfg.platformList.length)];
const platId = randomPlat.id;
const defaultFilter = this.filter_def?.[platId] || {};
const fakeContext = {
MY_CATE: platId,
MY_FL: defaultFilter,
MY_PAGE: 1,
...this
};
return await this.一级.call(fakeContext);
},
一级: async function () {
const { MY_CATE, MY_FL, MY_PAGE } = this;
const area = MY_FL?.area || '';
const plat = globalThis.aggConfig.platform[MY_CATE];
const cfg = globalThis.aggConfig;
let d = [];
if (!plat) return setResult(d);
const fetchStr = async (url, opt = {}) => await request(url, { headers: this.headers, ...opt });
try {
switch (MY_CATE) {
case '七猫': {
const sign = await md5(`operation=1playlet_privacy=1tag_id=${area}${cfg.keys}`);
const url = `${plat.host}${plat.url1}?tag_id=${area}&playlet_privacy=1&operation=1&sign=${sign}`;
const headers = { ...await getHeaderX(), ...cfg.headers.default };
const res = JSON.parse(await fetchStr(url, { headers }));
(res?.data?.list || []).forEach(item => {
d.push({ title: item.title, img: item.image_link, desc: `${item.total_episode_num}`, url: `七猫@${encodeURIComponent(item.playlet_id)}` });
});
break;
}
case '星芽': {
const class2 = MY_FL?.class2 || '0';
const headers = this.xingya_headers || cfg.headers.default;
if (area === '9') {
const rank = MY_FL?.rank || class2 || '1';
const res = JSON.parse(await fetchStr(`${plat.host}${plat.rankDetail}?id=${rank}`, { headers }));
(res?.data?.list || []).forEach(item => {
const i = item.theater || item;
if (!i?.id) return;
d.push({ title: i.title, img: i.cover_url, desc: `${i.total || ''}`, url: `星芽@${plat.host}${plat.url2}?theater_parent_id=${i.id}` });
});
} else {
const url = `${plat.host}${plat.url1}=${area}&type=1&class2_ids=${class2}&page_num=${MY_PAGE}&page_size=24`;
const res = JSON.parse(await fetchStr(url, { headers }));
(res?.data?.list || []).forEach(i => {
const item = i.theater || i;
if (!item?.id) return;
d.push({ title: item.title, img: item.cover_url, desc: `${item.total || ''}`, url: `星芽@${plat.host}${plat.url2}?theater_parent_id=${item.id}` });
});
}
break;
}
case '西饭': {
const typeName = area;
const searchUrl = `${plat.host}${plat.search}?reqType=search&offset=0&keyword=${encodeURIComponent(typeName || '')}&quickEngineVersion=-1&scene=`;
const res = JSON.parse(await fetchStr(searchUrl));
const elements = res?.result?.elements || [];
for (const block of elements) {
const contents = Array.isArray(block?.contents) ? block.contents : [];
for (const item of contents) {
const dj = item?.duanjuVo || {};
if (!dj.duanjuId) continue;
const categories = Array.isArray(dj.categories) ? dj.categories : [];
if (typeName && !categories.includes(typeName)) continue;
d.push({ title: dj.title, img: dj.coverImageUrl, desc: `${dj.total || ''}`, url: `西饭@${dj.duanjuId}#${dj.source}` });
}
}
break;
}
case '围观': {
const clientInfo = await md5(String(Date.now()).slice(-10));
const url = `${plat.host}${plat.search}?version_code=1500&version_name=1.5.0&device_name=Pixel%208%20Pro&device_type=phone&is_first_day=true&is_first_24h=true&app_launch_way=icon&default_homepage=homepage_interaction&device_owning_firm=Google&font_scale=default&os_type=1&clientInfo=${clientInfo}`;
const opt = {
method: 'POST',
headers: { 'User-Agent': 'okhttp/5.1.0', 'Content-Type': 'application/json; charset=utf-8' },
body: JSON.stringify({ audience: '全部', order: '最新', page: MY_PAGE, pageSize: 30, searchWord: '', subject: area || '' })
};
const res = JSON.parse(await fetchStr(url, opt));
(res?.data || []).forEach(i => {
d.push({ title: i.title, img: i.horzPoster || i.vertPoster, desc: `${i.episodeCount || ''}`, url: `围观@${i.oneId}` });
});
break;
}
case '河马': {
const url = `${plat.host}/browse/${area || '462'}/${MY_PAGE}`;
const html = await fetchStr(url, { headers: getHemaHeaders(url) });
const json = parseNextData(html);
const bookList = json?.props?.pageProps?.bookList || [];
for (const book of bookList) {
if (!book?.bookId) continue;
d.push({ title: book.bookName, img: book.coverWap, desc: `${book.statusDesc || ''} ${book.totalChapterNum || ''}`.trim(), url: `河马@/drama/${book.bookId}` });
}
break;
}
}
} catch (e) {
log(`${MY_CATE}一级加载失败: ${e.message}`);
}
return setResult(d);
},
二级: async function () {
const { orId } = this;
const [platform, ...rest] = orId.split('@');
const id = rest.join('@');
const cfg = globalThis.aggConfig;
const plat = cfg.platform[platform];
const fetchStr = async (url, opt = {}) => await request(url, { headers: this.headers, ...opt });
let VOD = {
vod_id: orId, vod_name: '未知', vod_pic: '', vod_remarks: '',
vod_content: '', vod_play_from: platform + '短剧', vod_play_url: ''
};
if (!plat) return VOD;
try {
switch (platform) {
case '七猫': {
const didDecoded = decodeURIComponent(id);
const sign = await md5(`playlet_id=${didDecoded}${cfg.keys}`);
const url = `${plat.url2}?playlet_id=${didDecoded}&sign=${sign}`;
const headers = { ...await getHeaderX(), ...cfg.headers.default };
const res = JSON.parse(await fetchStr(url, { headers }));
if (res?.data) {
const d = res.data;
VOD.vod_name = d.title; VOD.vod_pic = d.image_link; VOD.vod_remarks = `${d.total_episode_num}`; VOD.vod_content = d.intro;
VOD.vod_play_url = (d.play_list || []).map(i => `${i.sort}$${i.video_url}`).join('#');
}
break;
}
case '星芽': {
const headers = this.xingya_headers || cfg.headers.default;
const res = JSON.parse(await fetchStr(id, { headers }));
if (res?.data) {
const d = res.data;
VOD.vod_name = d.title; VOD.vod_pic = d.cover_url; VOD.vod_remarks = d.desc_tags + ''; VOD.vod_content = d.introduction || '';
VOD.vod_play_url = (d.theaters || []).map(i => `${i.num}$${i.son_video_url}`).join('#');
}
break;
}
case '西饭': {
const [duanjuId, source] = id.split('#');
const url = `${plat.host}${plat.url2}?duanjuId=${duanjuId}&source=${source}`;
const res = JSON.parse(await fetchStr(url));
if (res?.result) {
const d = res.result;
VOD.vod_name = d.title; VOD.vod_pic = d.coverImageUrl; VOD.vod_content = d.desc || '';
VOD.vod_remarks = d.updateStatus === 'over' ? `${d.total}集 已完结` : `更新${d.total}`;
VOD.vod_play_url = (d.episodeList || []).map(e => `${e.index}$${e.playUrl}`).join('#');
}
break;
}
case '围观': {
const clientInfo = await md5(String(Date.now()).slice(-10));
const url = `${plat.host}${plat.url2}?version_code=1500&version_name=1.5.0&device_name=Pixel%208%20Pro&device_type=phone&is_first_day=true&is_first_24h=true&app_launch_way=icon&default_homepage=homepage_interaction&device_owning_firm=Google&font_scale=default&os_type=1&clientInfo=${clientInfo}&oneId=${id}&page=1&pageSize=1000&userId=0&queryAll=true`;
const res = JSON.parse(await fetchStr(url, { headers: { 'User-Agent': 'okhttp/5.1.0', 'Content-Type': 'application/json; charset=utf-8' } }));
if (res?.data?.length) {
const episodes = res.data;
VOD.vod_name = res.title || episodes[0]?.title || VOD.vod_name;
VOD.vod_pic = res.vertPoster || episodes[0]?.vertPoster || '';
VOD.vod_remarks = `${episodes.length}`; VOD.vod_content = res.description || '';
VOD.vod_play_url = episodes.map(e => `${e.playOrder || e.title}$${base64Encode(JSON.stringify(e.videoClarityList || []))}`).join('#');
}
break;
}
case '河马': {
const didPath = id.startsWith('/drama/') ? id : `/drama/${id}`;
const html = await fetchStr(`${plat.host}${didPath}`, { headers: getHemaHeaders(`${plat.host}${didPath}`) });
const json = parseNextData(html);
const pageProps = json?.props?.pageProps || {};
const bookInfo = pageProps.bookInfoVo || {};
const chapterList = pageProps.chapterList || [];
VOD.vod_name = bookInfo.title || bookInfo.bookName || VOD.vod_name; VOD.vod_pic = bookInfo.coverWap || '';
VOD.vod_remarks = `${bookInfo.statusDesc || ''} ${bookInfo.totalChapterNum || ''}`.trim(); VOD.vod_content = bookInfo.introduction || '';
VOD.vod_play_url = chapterList.map(chapter => {
const chapterId = chapter.chapterId; const chapterName = chapter.chapterName;
const videoVo = chapter.chapterVideoVo || {}; const directUrl = videoVo.mp4 || videoVo.mp4720p || videoVo.vodMp4Url;
return `${chapterName}$${directUrl && /\.(mp4|m3u8)/.test(directUrl) ? directUrl : `${didPath.replace('/drama/', '')}+${chapterId}`}`;
}).join('#');
break;
}
}
} catch (e) {
VOD.vod_name = '加载失败';
}
return VOD;
},
搜索: async function (wd, quick, pg) {
const { KEY, MY_PAGE } = this;
const cfg = globalThis.aggConfig;
const d = [];
const timeout = cfg.search.timeout;
const wdLower = KEY.toLowerCase();
const tasks = cfg.platformList.map(async (p) => {
try {
const plat = cfg.platform[p.id];
let results = [];
if (p.id === '七猫') {
const sign = await md5(`page=${MY_PAGE}wd=${KEY}${cfg.keys}`);
const url = `${plat.host}${plat.search}?page=${MY_PAGE}&wd=${encodeURIComponent(KEY)}&sign=${sign}`;
const headerX = await getHeaderX();
const res = JSON.parse(await request(url, { headers: { ...headerX, ...cfg.headers.default }, timeout }));
(res?.data?.list || []).forEach(i => {
results.push({ title: i.title, img: i.image_link, desc: buildSearchRemark('七猫短剧', i.total_num || i.total_episode_num || '', i.hot_value || ''), url: `七猫@${encodeURIComponent(i.id || i.playlet_id)}` });
});
} else if (p.id === '星芽') {
const headers = this.xingya_headers || cfg.headers.default;
const res = JSON.parse(await request(plat.host + plat.search, { method: 'POST', headers, body: JSON.stringify({ text: KEY }), timeout }));
(res.data?.theater?.search_data || []).forEach(i => {
results.push({ title: i.title, img: i.cover_url, desc: buildSearchRemark('星芽短剧', i.total || i.current_num, i.play_amount_str || i.pv_str ? `播放:${i.play_amount_str || i.pv_str}` : ''), url: `星芽@${plat.host}${plat.url2}?theater_parent_id=${i.id}` });
});
} else if (p.id === '西饭') {
const url = `${plat.host}${plat.search}?reqType=search&offset=${(MY_PAGE - 1) * 30}&keyword=${encodeURIComponent(KEY)}&quickEngineVersion=-1&scene=`;
const res = JSON.parse(await request(url, { timeout }));
const elements = Array.isArray(res?.result?.elements) ? res.result.elements : [];
const contents = elements.flatMap(el => Array.isArray(el?.contents) ? el.contents : [el]);
contents.forEach(vod => {
const dj = vod?.duanjuVo || vod || {};
if (!dj.duanjuId || !dj.title) return;
results.push({ title: dj.title, img: dj.coverImageUrl, desc: buildSearchRemark('西饭短剧', dj.total), url: `西饭@${dj.duanjuId}#${dj.source || ''}` });
});
} else if (p.id === '围观') {
const clientInfo = await md5(String(Date.now()).slice(-10));
const url = `${plat.host}${plat.search}?version_code=1500&version_name=1.5.0&device_name=Pixel%208%20Pro&device_type=phone&is_first_day=true&is_first_24h=true&app_launch_way=icon&default_homepage=homepage_interaction&device_owning_firm=Google&font_scale=default&os_type=1&clientInfo=${clientInfo}`;
const res = JSON.parse(await request(url, {
method: 'POST',
headers: { 'User-Agent': 'okhttp/5.1.0', 'Content-Type': 'application/json; charset=utf-8' },
body: JSON.stringify({ audience: '', order: '', page: MY_PAGE, pageSize: 30, keyword: KEY, subject: '' }),
timeout
}));
(res?.data || []).forEach(i => {
results.push({ title: i.title, img: i.horzPoster || i.vertPoster, desc: buildSearchRemark('围观短剧', i.episodeCount || ''), url: `围观@${i.oneId}` });
});
} else if (p.id === '河马') {
const res = JSON.parse(await request(`${plat.host}${plat.search}`, {
method: 'POST',
headers: getHemaApiHeaders(`${plat.host}/search?searchValue=${encodeURIComponent(KEY)}`),
body: JSON.stringify({ sourceType: 1, keyword: KEY, index: MY_PAGE }),
timeout
}));
const apiBookList = Array.isArray(res?.data?.bookList) ? res.data.bookList : [];
apiBookList.map(normalizeHemaSearchBook).filter(Boolean).forEach(v => {
results.push({ title: v.vod_name, img: v.vod_pic, desc: v.vod_remarks, url: v.vod_id });
});
}
return results;
} catch (e) {
log(`搜索失败(平台:${p.name}):${e.message}`);
return [];
}
});
const settledResults = await Promise.allSettled(tasks);
const flatResults = settledResults
.filter(r => r.status === 'fulfilled')
.flatMap(r => r.value)
.map(item => ({ ...item, title: stripHtml(item.title) }));
return setResult(rule.search_match ? flatResults.filter(i => (i.title || '').toLowerCase().includes(wdLower)) : flatResults);
},
lazy: async function (flag, id, flags) {
const cfg = globalThis.aggConfig;
if (/七猫/.test(flag)) {
return { parse: 0, url: id };
}
if (/西饭/.test(flag)) {
return { parse: 0, url: id };
}
if (/围观/.test(flag)) {
try {
const ps = JSON.parse(base64Decode(id));
let urls = [];
for (const item of ps || []) {
if (item?.name && item?.url) {
urls.push(item.name, item.url);
}
}
return { parse: 0, url: urls.length ? urls : id, headers: { 'User-Agent': 'okhttp/5.1.0' } };
} catch (e) {
return { parse: 0, url: id };
}
}
if (/河马/.test(flag)) {
if (/\.(mp4|m3u8)(\?|$)/i.test(id)) {
return { parse: 0, url: id, header: getHemaHeaders() };
}
const parts = String(id || '').split('+');
if (parts.length >= 2) {
const [dramaId, chapterId] = parts;
const episodeUrl = `${cfg.platform.河马.host}/episode/${dramaId}/${chapterId}`;
const html = await request(episodeUrl, { headers: getHemaHeaders(episodeUrl) });
const json = parseNextData(html);
const videoInfo = json?.props?.pageProps?.chapterInfo?.chapterVideoVo || {};
const videoUrl = videoInfo.mp4 || videoInfo.mp4720p || videoInfo.vodMp4Url || (String(html).match(/(https?:\/\/[^"']+\.mp4[^"']*)/) || [])[1] || '';
return { parse: 0, url: videoUrl, header: getHemaHeaders() };
}
return { parse: 0, url: id, header: getHemaHeaders() };
}
return { parse: 0, url: id };
}
};
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.