255 lines
10 KiB
JavaScript
255 lines
10 KiB
JavaScript
// ==UserScript==
|
|
// @name mqtv
|
|
// @namespace gmspider
|
|
// @version 2024.11.12
|
|
// @description 麻雀视频 GMSpider
|
|
// @author Luomo
|
|
// @match https://www.mqtv.cc/*
|
|
// @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/Spiders-Lib@main/lib/browser-extension-url-match-1.2.0.min.js
|
|
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/ajaxhook.umd.min.js
|
|
// @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];
|
|
}
|
|
Object.freeze(GMSpiderArgs);
|
|
let hookConfigs = {
|
|
"homeContent": [{
|
|
dataKey: "VodList",
|
|
matcher: matchPattern("https://*/libs/VodList.api.php?*").assertValid()
|
|
}],
|
|
"categoryContent": [{
|
|
dataKey: "VodList",
|
|
matcher: matchPattern("https://*/libs/VodList.api.php?*").assertValid(),
|
|
onRequestHook: function (config, handler) {
|
|
let url = new URL(config.url, window.location.origin);
|
|
url.searchParams.set('page', GMSpiderArgs.fArgs[1]);
|
|
config.url = url.pathname + url.search;
|
|
}
|
|
}],
|
|
"detailContent": [{
|
|
dataKey: "VodInfo",
|
|
matcher: matchPattern("https://*/libs/VodInfo.api.php?*").assertValid()
|
|
}],
|
|
"playerContent": [{
|
|
dataKey: "VodInfo",
|
|
matcher: matchPattern("https://*/libs/VodInfo.api.php?*").assertValid(),
|
|
onResponseHook: function (response, handler) {
|
|
console.log("playerContent", response);
|
|
let anchor = window.location.hash.split("#").at(1);
|
|
let vodInfo = JSON.parse(response.response)?.data;
|
|
vodInfo.playinfo.forEach((playinfo) => {
|
|
playinfo.player.forEach((player, index) => {
|
|
if (player.url === anchor) {
|
|
localStorage.setItem("history", JSON.stringify({
|
|
val: [{
|
|
"id": vodInfo.id,
|
|
"type": vodInfo.type,
|
|
"title": vodInfo.title,
|
|
"img": vodInfo.img,
|
|
"url": player.url,
|
|
"episode": player.no,
|
|
"ensite": playinfo.ensite,
|
|
"cnsite": playinfo.cnsite,
|
|
"num": index
|
|
}],
|
|
exp: new Date().getTime() + 60 * 1000,
|
|
}));
|
|
}
|
|
})
|
|
});
|
|
console.log("history", localStorage.getItem("history"));
|
|
}
|
|
}],
|
|
"searchContent": [{
|
|
dataKey: "VodList",
|
|
matcher: matchPattern("https://*/libs/VodList.api.php?*").assertValid()
|
|
}],
|
|
};
|
|
const GmSpider = (function () {
|
|
const categoryFilterCachePrefix = "category.";
|
|
|
|
function formatVodList(vodList) {
|
|
let vods = [];
|
|
vodList.forEach(function (vod) {
|
|
vods.push({
|
|
vod_id: vod.url,
|
|
vod_name: vod.title,
|
|
vod_pic: vod.img,
|
|
vod_remarks: vod.remark
|
|
})
|
|
})
|
|
return vods;
|
|
}
|
|
|
|
return {
|
|
homeContent: function (filter) {
|
|
let result = {
|
|
class: [
|
|
{type_id: "movie", type_name: "电影"},
|
|
{type_id: "tv", type_name: "电视剧"},
|
|
{type_id: "va", type_name: "综艺"},
|
|
{type_id: "ct", type_name: "动漫"}
|
|
],
|
|
filters: {},
|
|
list: []
|
|
};
|
|
result.list.push(...formatVodList(hookResult.VodList?.data?.ct?.[0]?.show), ...formatVodList(hookResult.VodList?.data?.movie?.[0]?.show), ...formatVodList(hookResult.VodList?.data?.tv?.[0]?.show));
|
|
return result;
|
|
},
|
|
categoryContent: function (tid, pg, filter, extend) {
|
|
let result = {
|
|
list: [],
|
|
pagecount: pg
|
|
};
|
|
result.list = formatVodList(hookResult.VodList?.data)
|
|
if (result.list.length >= 25) {
|
|
result.pagecount = pg + 1;
|
|
}
|
|
return result;
|
|
},
|
|
detailContent: function (ids) {
|
|
const vodInfo = hookResult.VodInfo.data;
|
|
let vodPlayData = [];
|
|
hookResult.VodInfo.data.playinfo.forEach((item) => {
|
|
let media = [];
|
|
item.player.forEach((player) => {
|
|
media.push({
|
|
name: player.no,
|
|
type: "webview",
|
|
ext: {
|
|
replace: {
|
|
url: ids[0],
|
|
anchor: player.url
|
|
}
|
|
}
|
|
});
|
|
})
|
|
vodPlayData.push({
|
|
from: item.cnsite,
|
|
media: media
|
|
})
|
|
});
|
|
return {
|
|
vod_id: vodInfo.id,
|
|
vod_name: vodInfo.title,
|
|
vod_pic: vodInfo.img,
|
|
vod_actor: vodInfo.actor,
|
|
vod_director: vodInfo.director,
|
|
vod_area: vodInfo.area,
|
|
vod_year: vodInfo.year,
|
|
vod_remarks: vodInfo.remark,
|
|
vod_play_data: vodPlayData
|
|
};
|
|
},
|
|
playerContent: function (flag, id, vipFlags) {
|
|
return {
|
|
type: "match"
|
|
};
|
|
},
|
|
searchContent: function (key, quick, pg) {
|
|
let result = {
|
|
list: [],
|
|
pagecount: 1
|
|
};
|
|
let _gotData = function (src) {
|
|
console.log("_gotSrc hook failed");
|
|
};
|
|
const targetNode = $("#leo-load-list-1")[0];
|
|
const config = {childList: true, subtree: true};
|
|
const observer = new MutationObserver((mutationsList) => {
|
|
mutationsList.forEach((mutation) => {
|
|
_gotData();
|
|
});
|
|
});
|
|
observer.observe(targetNode, {childList: true, subtree: true});
|
|
return new Promise(function (resolve) {
|
|
_gotData = resolve;
|
|
}).then(function () {
|
|
let $ = unsafeWindow.$;
|
|
$(".leo-list-item-s").each(function () {
|
|
result.list.push({
|
|
vod_id: $(this).find(".leo-list-item-title a").attr("href"),
|
|
vod_name:$(this).find(".leo-list-item-title a").attr("title"),
|
|
vod_pic: $(this).find(".leo-list-item-pic img").data("original")
|
|
});
|
|
})
|
|
return result;
|
|
});
|
|
}
|
|
};
|
|
})();
|
|
let spiderExecuted = false;
|
|
let dataReadyCount = 0;
|
|
let hookResult = {};
|
|
const {unProxy, originXhr} = proxy({
|
|
onRequest: (config, handler) => {
|
|
let requestUrl = config.url;
|
|
if (!requestUrl.startsWith("http")) {
|
|
requestUrl = window.location.origin + requestUrl;
|
|
}
|
|
hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => {
|
|
if (typeof hookConfig.onRequestHook === "function" && hookConfig.matcher.match(requestUrl)) {
|
|
hookConfig.onRequestHook(config, handler);
|
|
}
|
|
});
|
|
handler.next(config);
|
|
},
|
|
onResponse: (response, handler) => {
|
|
if (!spiderExecuted) {
|
|
let dataTodoCount = 0;
|
|
let requestUrl = response.config.url;
|
|
if (!requestUrl.startsWith("http")) {
|
|
requestUrl = window.location.origin + requestUrl;
|
|
}
|
|
hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => {
|
|
if (typeof hookConfig.dataKey !== "undefined") {
|
|
if (hookConfig?.require !== false) {
|
|
dataTodoCount++;
|
|
}
|
|
if (hookConfig.matcher.match(requestUrl)) {
|
|
if (hookConfig?.require !== false) {
|
|
dataReadyCount++;
|
|
}
|
|
try {
|
|
let data = JSON.parse(response.response);
|
|
if (typeof data === 'object' && data) {
|
|
hookResult[hookConfig.dataKey] = data;
|
|
} else {
|
|
hookResult[hookConfig.dataKey] = response.response;
|
|
}
|
|
} catch (e) {
|
|
}
|
|
}
|
|
}
|
|
if (typeof hookConfig.onResponseHook === "function" && hookConfig.matcher.match(requestUrl)) {
|
|
hookConfig.onResponseHook(response, handler);
|
|
}
|
|
});
|
|
if (dataTodoCount === dataReadyCount) {
|
|
spiderExecuted = true;
|
|
|
|
async function asyncRun() {
|
|
const result = await GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs);
|
|
console.log(result);
|
|
if (typeof GmSpiderInject !== 'undefined' && spiderExecuted) {
|
|
GmSpiderInject.SetSpiderResult(JSON.stringify(result));
|
|
}
|
|
}
|
|
|
|
asyncRun();
|
|
}
|
|
}
|
|
handler.next(response);
|
|
}
|
|
}, unsafeWindow)
|
|
})(); |