N3RDN/JN/EXT/userScripts/hitv.user.js
2024-12-11 20:30:52 +08:00

259 lines
12 KiB
JavaScript

// ==UserScript==
// @name hitv
// @namespace gmspider
// @version 2024.11.12
// @description Hi视频 GMSpider
// @author Luomo
// @match https://www.upfuhn.com/*
// @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/Spiders-Lib@main/lib/browser-extension-url-match-1.2.0.min.js
// @require https://scriptcat.org/lib/637/1.4.3/ajaxHooker.js
// @grant GM_setValue
// @grant GM_getValue
// @grant unsafeWindow
// @run-at document-start
// ==/UserScript==
console.log(JSON.stringify(GM_info));
(function () {
const GMSpiderArgs = {};
if (typeof GmSpiderInject !== 'undefined') {
let args = JSON.parse(GmSpiderInject.GetSpiderArgs());
GMSpiderArgs.fName = args.shift();
GMSpiderArgs.fArgs = args;
} else {
GMSpiderArgs.fName = "searchContent";
GMSpiderArgs.fArgs = [true];
// GMSpiderArgs.fName = "categoryContent";
// GMSpiderArgs.fArgs = ["82", 2, true, {tag: "动作", y: "2024", o: "1", a: "大陆"}];
}
Object.freeze(GMSpiderArgs);
let hookConfigs = {
"homeContent": [{
matcher: matchPattern("https://*/v1/report_channel_data").assertValid(),
onResponseHook: function (response) {
Array.from(document.querySelectorAll(".left-wrap .tab-box:nth-child(2) .swiper-slide span"))
.find(el => el.textContent === "全部").dispatchEvent(new Event("click"));
}
}, {
dataKey: "ys_video_sites", matcher: matchPattern("https://*/v1/ys_video_sites?*").assertValid()
}], "categoryContent": [{
matcher: matchPattern("https://*/v1/report_channel_data").assertValid(),
onResponseHook: function (response) {
const extend = GMSpiderArgs.fArgs[3];
let tag = extend?.tag ?? "全部"
Array.from(document.querySelectorAll(".left-wrap .tab-box:nth-child(2) .swiper-slide span"))
.find(el => el.textContent === tag).dispatchEvent(new Event("click"));
}
}, {
dataKey: "ys_video_sites",
matcher: matchPattern("https://*/v1/ys_video_sites?*").assertValid(),
onRequestHook: function (response) {
const page = GMSpiderArgs.fArgs[1];
const filter = GMSpiderArgs.fArgs[2];
const extend = GMSpiderArgs.fArgs[3];
const url = new URL(response.url);
const params = new URLSearchParams(url.search);
params.set("pn", page)
if (filter) {
params.set("a", extend?.a ?? "");
params.set("y", extend?.y ?? "");
params.set("o", extend?.o ?? 0);
}
url.search = params.toString();
response.url = url.toString();
}
}],
"detailContent": [{
dataKey: "meta", matcher: matchPattern("https://*/v1/report_channel_data").assertValid()
}],
"searchContent": [{
dataKey: "meta", matcher: matchPattern("https://*/v1/report_channel_data").assertValid()
}],
};
const GmSpider = (function () {
const categoryFilterCachePrefix = "category_";
const filterTag = {
key: "tag", name: "分类", value: []
};
const filterArea = {
key: "o", name: "地区", value: []
};
const filterYear = {
key: "y", name: "年份", value: []
};
const filterSort = {
key: "o",
name: "排序",
value: [{n: "综合", v: "0"}, {n: "最新", v: "2"}, {n: "最热", v: "1"}, {n: "评分", v: "5"},]
};
return {
homeContent: function (filter) {
let result = {
class: [{type_id: "85", type_name: "短剧"}, {type_id: "81", type_name: "电影"}, {
type_id: "82",
type_name: "电视剧"
}, {type_id: "83", type_name: "综艺"}, {type_id: "84", type_name: "动漫"},], filters: {}, list: []
};
document.querySelectorAll(".left-wrap .tab-box:nth-child(3) .swiper-slide span").forEach((filter) => {
filterArea.value.push({
n: filter.textContent, v: filter.textContent,
})
});
document.querySelectorAll(".left-wrap .tab-box:nth-child(4) .swiper-slide span").forEach((filter) => {
filterYear.value.push({
n: filter.textContent, v: filter.textContent,
})
});
result.class.forEach((category) => {
const categoryFilter = [];
const cacheFilter = localStorage.getItem(categoryFilterCachePrefix + category.type_id);
if (typeof cacheFilter !== "undefined" && cacheFilter !== null) {
categoryFilter.push(JSON.parse(cacheFilter));
}
categoryFilter.push(filterArea, filterYear, filterSort);
result.filters[category.type_id] = categoryFilter;
})
hookResult.ys_video_sites.data.data.forEach((media) => {
result.list.push({
vod_id: media.video_site_id,
vod_name: media.video_name,
vod_pic: media.video_vertical_url,
vod_remarks: "评分:" + media.score,
vod_year: media.years
})
});
return result;
}, categoryContent: function (tid, pg, filter, extend) {
let result = {
list: [], pagecount: Math.ceil(hookResult.ys_video_sites.data.total / 21)
};
document.querySelectorAll(".left-wrap .tab-box:nth-child(2) .swiper-slide span").forEach((filter) => {
filterTag.value.push({
n: filter.textContent, v: filter.textContent,
})
});
localStorage.setItem(categoryFilterCachePrefix + tid, JSON.stringify(filterTag));
hookResult.ys_video_sites.data.data.forEach((media) => {
result.list.push({
vod_id: media.video_site_id,
vod_name: media.video_name,
vod_pic: media.video_vertical_url,
vod_remarks: "评分:" + media.score,
vod_year: media.years
})
})
return result;
}, detailContent: function (ids) {
let playUrl = [];
let vod = {};
const formatData = JSON.parse(document.getElementById("__NUXT_DATA__").innerHTML);
formatData.forEach((data) => {
if (typeof (vod?.vod_id) == "undefined" && typeof (data?.video_desc) === "number") {
vod = {
vod_id: formatData[data.video_site_id],
vod_name: formatData[data.video_name],
vod_content: formatData[data.video_desc],
vod_year: formatData[data.years],
vod_area: formatData[data.area],
vod_actor: formatData[data.main_actor],
type_name: formatData[data.tag],
vod_play_data: [{
from: "Hi视频", url: playUrl
}]
};
}
if (typeof (data?.series_num) === "number") {
playUrl.push({
name: formatData[data.series_num],
value: {
type: "finalUrl", data: {
header: {
"User-Agent": window.navigator.userAgent, "Referer": window.location.href
}, url: formatData[data.video_url]
}
}
})
}
})
return vod;
}, searchContent: function (key, quick, pg) {
const result = {
list: [],
page: pg,
pagecount: 1
};
const formatData = JSON.parse(document.getElementById("__NUXT_DATA__").innerHTML);
console.log(formatData);
formatData.forEach((data) => {
if (typeof (data?.first_video_series) === "number") {
let firstVideo = formatData[data.first_video_series];
result.list.push({
vod_id: formatData[firstVideo.video_site_id],
vod_name: formatData[firstVideo.video_name],
vod_pic: formatData[firstVideo.video_vertical_url],
vod_remarks: formatData[firstVideo.tag],
vod_year: formatData[firstVideo.years]
})
formatData[data.video_sites].forEach((videoIndex) => {
let video = formatData[videoIndex];
result.list.push({
vod_id: formatData[video.video_site_id],
vod_name: formatData[video.video_name],
vod_pic: formatData[video.video_vertical_url],
vod_remarks: formatData[video.tag],
vod_year: formatData[video.years]
})
})
}
})
return result;
}
};
})();
let spiderExecuted = false;
let dataReadyCount = 0;
let hookResult = {};
ajaxHooker.hook(request => {
hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => {
if (typeof hookConfig.onRequestHook === "function" && hookConfig.matcher.match(request.url)) {
hookConfig.onRequestHook(request);
}
});
if (!spiderExecuted) {
let dataTodoCount = 0;
hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => {
if (typeof hookConfig.dataKey !== "undefined") {
if (hookConfig?.require !== false) {
dataTodoCount++;
}
}
if (hookConfig.matcher.match(request.url)) {
request.response = res => {
if (typeof hookConfig.onResponseHook === "function") {
hookConfig.onResponseHook(res);
}
if (typeof hookConfig.dataKey !== "undefined") {
if (hookConfig?.require !== false) {
dataReadyCount++;
}
let data = JSON.parse(res.text);
if (typeof data === 'object' && data) {
hookResult[hookConfig.dataKey] = data;
} else {
hookResult[hookConfig.dataKey] = res.text;
}
if (dataTodoCount === dataReadyCount) {
spiderExecuted = true;
const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs);
console.log(result);
if (typeof GmSpiderInject !== 'undefined' && spiderExecuted) {
GmSpiderInject.SetSpiderResult(JSON.stringify(result));
}
}
}
};
}
});
}
});
})();