├── .gitignore ├── Spiders-Lib ├── GM.jar ├── ajaxHooker-1.4.3.js ├── ajaxhook-3.0.3.min.js ├── browser-extension-url-match-1.2.0.min.js └── maccms-1.0.2.js ├── index.json └── userScripts ├── bilfun.user.js ├── dandantu.user.js ├── fantuan.user.js ├── freeok.user.js ├── gaze.user.js ├── hitv.user.js ├── huochetaidu.user.js ├── juyeye.user.js ├── kkys.user.js ├── mqtv.user.js ├── pipiys.user.js ├── ppdys.user.js ├── ppxys.user.js ├── yirenmeng.user.js ├── ysfp.user.js └── zxzjhd.user.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea -------------------------------------------------------------------------------- /Spiders-Lib/GM.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatVodSpider-GM/SFW-Spiders/bdf5c0bb8a7a41ce6871a163736e9fb7104a1221/Spiders-Lib/GM.jar -------------------------------------------------------------------------------- /Spiders-Lib/ajaxHooker-1.4.3.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name ajaxHooker 3 | // @author cxxjackie 4 | // @version 1.4.3 5 | // @supportURL https://bbs.tampermonkey.net.cn/thread-3284-1-1.html 6 | // ==/UserScript== 7 | 8 | var ajaxHooker = function() { 9 | 'use strict'; 10 | const version = '1.4.3'; 11 | const hookInst = { 12 | hookFns: [], 13 | filters: [] 14 | }; 15 | const win = window.unsafeWindow || document.defaultView || window; 16 | let winAh = win.__ajaxHooker; 17 | const resProto = win.Response.prototype; 18 | const xhrResponses = ['response', 'responseText', 'responseXML']; 19 | const fetchResponses = ['arrayBuffer', 'blob', 'formData', 'json', 'text']; 20 | const fetchInitProps = ['method', 'headers', 'body', 'mode', 'credentials', 'cache', 'redirect', 21 | 'referrer', 'referrerPolicy', 'integrity', 'keepalive', 'signal', 'priority']; 22 | const xhrAsyncEvents = ['readystatechange', 'load', 'loadend']; 23 | const getType = ({}).toString.call.bind(({}).toString); 24 | const getDescriptor = Object.getOwnPropertyDescriptor.bind(Object); 25 | const emptyFn = () => {}; 26 | const errorFn = e => console.error(e); 27 | function isThenable(obj) { 28 | return obj && ['object', 'function'].includes(typeof obj) && typeof obj.then === 'function'; 29 | } 30 | function catchError(fn, ...args) { 31 | try { 32 | const result = fn(...args); 33 | if (isThenable(result)) return result.then(null, errorFn); 34 | return result; 35 | } catch (err) { 36 | console.error(err); 37 | } 38 | } 39 | function defineProp(obj, prop, getter, setter) { 40 | Object.defineProperty(obj, prop, { 41 | configurable: true, 42 | enumerable: true, 43 | get: getter, 44 | set: setter 45 | }); 46 | } 47 | function readonly(obj, prop, value = obj[prop]) { 48 | defineProp(obj, prop, () => value, emptyFn); 49 | } 50 | function writable(obj, prop, value = obj[prop]) { 51 | Object.defineProperty(obj, prop, { 52 | configurable: true, 53 | enumerable: true, 54 | writable: true, 55 | value: value 56 | }); 57 | } 58 | function parseHeaders(obj) { 59 | const headers = {}; 60 | switch (getType(obj)) { 61 | case '[object String]': 62 | for (const line of obj.trim().split(/[\r\n]+/)) { 63 | const [header, value] = line.split(/\s*:\s*/); 64 | if (!header) break; 65 | const lheader = header.toLowerCase(); 66 | headers[lheader] = lheader in headers ? `${headers[lheader]}, ${value}` : value; 67 | } 68 | break; 69 | case '[object Headers]': 70 | for (const [key, val] of obj) { 71 | headers[key] = val; 72 | } 73 | break; 74 | case '[object Object]': 75 | return {...obj}; 76 | } 77 | return headers; 78 | } 79 | function stopImmediatePropagation() { 80 | this.ajaxHooker_isStopped = true; 81 | } 82 | class SyncThenable { 83 | then(fn) { 84 | fn && fn(); 85 | return new SyncThenable(); 86 | } 87 | } 88 | class AHRequest { 89 | constructor(request) { 90 | this.request = request; 91 | this.requestClone = {...this.request}; 92 | } 93 | shouldFilter(filters) { 94 | const {type, url, method, async} = this.request; 95 | return filters.length && !filters.find(obj => { 96 | switch (true) { 97 | case obj.type && obj.type !== type: 98 | case getType(obj.url) === '[object String]' && !url.includes(obj.url): 99 | case getType(obj.url) === '[object RegExp]' && !obj.url.test(url): 100 | case obj.method && obj.method.toUpperCase() !== method.toUpperCase(): 101 | case 'async' in obj && obj.async !== async: 102 | return false; 103 | } 104 | return true; 105 | }); 106 | } 107 | waitForRequestKeys() { 108 | const requestKeys = ['url', 'method', 'abort', 'headers', 'data']; 109 | if (!this.request.async) { 110 | win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => { 111 | if (this.shouldFilter(filters)) return; 112 | hookFns.forEach(fn => { 113 | if (getType(fn) === '[object Function]') catchError(fn, this.request); 114 | }); 115 | requestKeys.forEach(key => { 116 | if (isThenable(this.request[key])) this.request[key] = this.requestClone[key]; 117 | }); 118 | }); 119 | return new SyncThenable(); 120 | } 121 | const promises = []; 122 | win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => { 123 | if (this.shouldFilter(filters)) return; 124 | promises.push(Promise.all(hookFns.map(fn => catchError(fn, this.request))).then(() => 125 | Promise.all(requestKeys.map(key => Promise.resolve(this.request[key]).then( 126 | val => this.request[key] = val, 127 | () => this.request[key] = this.requestClone[key] 128 | ))) 129 | )); 130 | }); 131 | return Promise.all(promises); 132 | } 133 | waitForResponseKeys(response) { 134 | const responseKeys = this.request.type === 'xhr' ? xhrResponses : fetchResponses; 135 | if (!this.request.async) { 136 | if (getType(this.request.response) === '[object Function]') { 137 | catchError(this.request.response, response); 138 | responseKeys.forEach(key => { 139 | if ('get' in getDescriptor(response, key) || isThenable(response[key])) { 140 | delete response[key]; 141 | } 142 | }); 143 | } 144 | return new SyncThenable(); 145 | } 146 | return Promise.resolve(catchError(this.request.response, response)).then(() => 147 | Promise.all(responseKeys.map(key => { 148 | const descriptor = getDescriptor(response, key); 149 | if (descriptor && 'value' in descriptor) { 150 | return Promise.resolve(descriptor.value).then( 151 | val => response[key] = val, 152 | () => delete response[key] 153 | ); 154 | } else { 155 | delete response[key]; 156 | } 157 | })) 158 | ); 159 | } 160 | } 161 | const proxyHandler = { 162 | get(target, prop) { 163 | const descriptor = getDescriptor(target, prop); 164 | if (descriptor && !descriptor.configurable && !descriptor.writable && !descriptor.get) return target[prop]; 165 | const ah = target.__ajaxHooker; 166 | if (ah && ah.proxyProps) { 167 | if (prop in ah.proxyProps) { 168 | const pDescriptor = ah.proxyProps[prop]; 169 | if ('get' in pDescriptor) return pDescriptor.get(); 170 | if (typeof pDescriptor.value === 'function') return pDescriptor.value.bind(ah); 171 | return pDescriptor.value; 172 | } 173 | if (typeof target[prop] === 'function') return target[prop].bind(target); 174 | } 175 | return target[prop]; 176 | }, 177 | set(target, prop, value) { 178 | const descriptor = getDescriptor(target, prop); 179 | if (descriptor && !descriptor.configurable && !descriptor.writable && !descriptor.set) return true; 180 | const ah = target.__ajaxHooker; 181 | if (ah && ah.proxyProps && prop in ah.proxyProps) { 182 | const pDescriptor = ah.proxyProps[prop]; 183 | pDescriptor.set ? pDescriptor.set(value) : (pDescriptor.value = value); 184 | } else { 185 | target[prop] = value; 186 | } 187 | return true; 188 | } 189 | }; 190 | class XhrHooker { 191 | constructor(xhr) { 192 | const ah = this; 193 | Object.assign(ah, { 194 | originalXhr: xhr, 195 | proxyXhr: new Proxy(xhr, proxyHandler), 196 | resThenable: new SyncThenable(), 197 | proxyProps: {}, 198 | proxyEvents: {} 199 | }); 200 | xhr.addEventListener('readystatechange', e => { 201 | if (ah.proxyXhr.readyState === 4 && ah.request && typeof ah.request.response === 'function') { 202 | const response = { 203 | finalUrl: ah.proxyXhr.responseURL, 204 | status: ah.proxyXhr.status, 205 | responseHeaders: parseHeaders(ah.proxyXhr.getAllResponseHeaders()) 206 | }; 207 | const tempValues = {}; 208 | for (const key of xhrResponses) { 209 | try { 210 | tempValues[key] = ah.originalXhr[key]; 211 | } catch (err) {} 212 | defineProp(response, key, () => { 213 | return response[key] = tempValues[key]; 214 | }, val => { 215 | delete response[key]; 216 | response[key] = val; 217 | }); 218 | } 219 | ah.resThenable = new AHRequest(ah.request).waitForResponseKeys(response).then(() => { 220 | for (const key of xhrResponses) { 221 | ah.proxyProps[key] = {get: () => { 222 | if (!(key in response)) response[key] = tempValues[key]; 223 | return response[key]; 224 | }}; 225 | } 226 | }); 227 | } 228 | ah.dispatchEvent(e); 229 | }); 230 | xhr.addEventListener('load', e => ah.dispatchEvent(e)); 231 | xhr.addEventListener('loadend', e => ah.dispatchEvent(e)); 232 | for (const evt of xhrAsyncEvents) { 233 | const onEvt = 'on' + evt; 234 | ah.proxyProps[onEvt] = { 235 | get: () => ah.proxyEvents[onEvt] || null, 236 | set: val => ah.addEvent(onEvt, val) 237 | }; 238 | } 239 | for (const method of ['setRequestHeader', 'addEventListener', 'removeEventListener', 'open', 'send']) { 240 | ah.proxyProps[method] = {value: ah[method]}; 241 | } 242 | } 243 | toJSON() {} // Converting circular structure to JSON 244 | addEvent(type, event) { 245 | if (type.startsWith('on')) { 246 | this.proxyEvents[type] = typeof event === 'function' ? event : null; 247 | } else { 248 | if (typeof event === 'object' && event !== null) event = event.handleEvent; 249 | if (typeof event !== 'function') return; 250 | this.proxyEvents[type] = this.proxyEvents[type] || new Set(); 251 | this.proxyEvents[type].add(event); 252 | } 253 | } 254 | removeEvent(type, event) { 255 | if (type.startsWith('on')) { 256 | this.proxyEvents[type] = null; 257 | } else { 258 | if (typeof event === 'object' && event !== null) event = event.handleEvent; 259 | this.proxyEvents[type] && this.proxyEvents[type].delete(event); 260 | } 261 | } 262 | dispatchEvent(e) { 263 | e.stopImmediatePropagation = stopImmediatePropagation; 264 | defineProp(e, 'target', () => this.proxyXhr); 265 | defineProp(e, 'currentTarget', () => this.proxyXhr); 266 | this.proxyEvents[e.type] && this.proxyEvents[e.type].forEach(fn => { 267 | this.resThenable.then(() => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e)); 268 | }); 269 | if (e.ajaxHooker_isStopped) return; 270 | const onEvent = this.proxyEvents['on' + e.type]; 271 | onEvent && this.resThenable.then(onEvent.bind(this.proxyXhr, e)); 272 | } 273 | setRequestHeader(header, value) { 274 | this.originalXhr.setRequestHeader(header, value); 275 | if (!this.request) return; 276 | const headers = this.request.headers; 277 | headers[header] = header in headers ? `${headers[header]}, ${value}` : value; 278 | } 279 | addEventListener(...args) { 280 | if (xhrAsyncEvents.includes(args[0])) { 281 | this.addEvent(args[0], args[1]); 282 | } else { 283 | this.originalXhr.addEventListener(...args); 284 | } 285 | } 286 | removeEventListener(...args) { 287 | if (xhrAsyncEvents.includes(args[0])) { 288 | this.removeEvent(args[0], args[1]); 289 | } else { 290 | this.originalXhr.removeEventListener(...args); 291 | } 292 | } 293 | open(method, url, async = true, ...args) { 294 | this.request = { 295 | type: 'xhr', 296 | url: url.toString(), 297 | method: method.toUpperCase(), 298 | abort: false, 299 | headers: {}, 300 | data: null, 301 | response: null, 302 | async: !!async 303 | }; 304 | this.openArgs = args; 305 | this.resThenable = new SyncThenable(); 306 | ['responseURL', 'readyState', 'status', 'statusText', ...xhrResponses].forEach(key => { 307 | delete this.proxyProps[key]; 308 | }); 309 | return this.originalXhr.open(method, url, async, ...args); 310 | } 311 | send(data) { 312 | const ah = this; 313 | const xhr = ah.originalXhr; 314 | const request = ah.request; 315 | if (!request) return xhr.send(data); 316 | request.data = data; 317 | new AHRequest(request).waitForRequestKeys().then(() => { 318 | if (request.abort) { 319 | if (typeof request.response === 'function') { 320 | Object.assign(ah.proxyProps, { 321 | responseURL: {value: request.url}, 322 | readyState: {value: 4}, 323 | status: {value: 200}, 324 | statusText: {value: 'OK'} 325 | }); 326 | xhrAsyncEvents.forEach(evt => xhr.dispatchEvent(new Event(evt))); 327 | } 328 | } else { 329 | xhr.open(request.method, request.url, request.async, ...ah.openArgs); 330 | for (const header in request.headers) { 331 | xhr.setRequestHeader(header, request.headers[header]); 332 | } 333 | xhr.send(request.data); 334 | } 335 | }); 336 | } 337 | } 338 | function fakeXHR() { 339 | const xhr = new winAh.realXHR(); 340 | if ('__ajaxHooker' in xhr) console.warn('检测到不同版本的ajaxHooker,可能发生冲突!'); 341 | xhr.__ajaxHooker = new XhrHooker(xhr); 342 | return xhr.__ajaxHooker.proxyXhr; 343 | } 344 | fakeXHR.prototype = win.XMLHttpRequest.prototype; 345 | Object.keys(win.XMLHttpRequest).forEach(key => fakeXHR[key] = win.XMLHttpRequest[key]); 346 | function fakeFetch(url, options = {}) { 347 | if (!url) return winAh.realFetch.call(win, url, options); 348 | return new Promise(async (resolve, reject) => { 349 | const init = {}; 350 | if (getType(url) === '[object Request]') { 351 | for (const prop of fetchInitProps) init[prop] = url[prop]; 352 | if (url.body) init.body = await url.arrayBuffer(); 353 | url = url.url; 354 | } 355 | url = url.toString(); 356 | Object.assign(init, options); 357 | init.method = init.method || 'GET'; 358 | init.headers = init.headers || {}; 359 | const request = { 360 | type: 'fetch', 361 | url: url, 362 | method: init.method.toUpperCase(), 363 | abort: false, 364 | headers: parseHeaders(init.headers), 365 | data: init.body, 366 | response: null, 367 | async: true 368 | }; 369 | const req = new AHRequest(request); 370 | await req.waitForRequestKeys(); 371 | if (request.abort) { 372 | if (typeof request.response === 'function') { 373 | const response = { 374 | finalUrl: request.url, 375 | status: 200, 376 | responseHeaders: {} 377 | }; 378 | await req.waitForResponseKeys(response); 379 | const key = fetchResponses.find(k => k in response); 380 | let val = response[key]; 381 | if (key === 'json' && typeof val === 'object') { 382 | val = catchError(JSON.stringify.bind(JSON), val); 383 | } 384 | const res = new Response(val, { 385 | status: 200, 386 | statusText: 'OK' 387 | }); 388 | defineProp(res, 'type', () => 'basic'); 389 | defineProp(res, 'url', () => request.url); 390 | resolve(res); 391 | } else { 392 | reject(new DOMException('aborted', 'AbortError')); 393 | } 394 | return; 395 | } 396 | init.method = request.method; 397 | init.headers = request.headers; 398 | init.body = request.data; 399 | winAh.realFetch.call(win, request.url, init).then(res => { 400 | if (typeof request.response === 'function') { 401 | const response = { 402 | finalUrl: res.url, 403 | status: res.status, 404 | responseHeaders: parseHeaders(res.headers) 405 | }; 406 | fetchResponses.forEach(key => res[key] = function() { 407 | if (key in response) return Promise.resolve(response[key]); 408 | return resProto[key].call(this).then(val => { 409 | response[key] = val; 410 | return req.waitForResponseKeys(response).then(() => key in response ? response[key] : val); 411 | }); 412 | }); 413 | } 414 | resolve(res); 415 | }, reject); 416 | }); 417 | } 418 | function fakeFetchClone() { 419 | const descriptors = Object.getOwnPropertyDescriptors(this); 420 | const res = winAh.realFetchClone.call(this); 421 | Object.defineProperties(res, descriptors); 422 | return res; 423 | } 424 | winAh = win.__ajaxHooker = winAh || { 425 | version, fakeXHR, fakeFetch, fakeFetchClone, 426 | realXHR: win.XMLHttpRequest, 427 | realFetch: win.fetch, 428 | realFetchClone: resProto.clone, 429 | hookInsts: new Set() 430 | }; 431 | if (winAh.version !== version) console.warn('检测到不同版本的ajaxHooker,可能发生冲突!'); 432 | win.XMLHttpRequest = winAh.fakeXHR; 433 | win.fetch = winAh.fakeFetch; 434 | resProto.clone = winAh.fakeFetchClone; 435 | winAh.hookInsts.add(hookInst); 436 | return { 437 | hook: fn => hookInst.hookFns.push(fn), 438 | filter: arr => { 439 | if (Array.isArray(arr)) hookInst.filters = arr; 440 | }, 441 | protect: () => { 442 | readonly(win, 'XMLHttpRequest', winAh.fakeXHR); 443 | readonly(win, 'fetch', winAh.fakeFetch); 444 | readonly(resProto, 'clone', winAh.fakeFetchClone); 445 | }, 446 | unhook: () => { 447 | winAh.hookInsts.delete(hookInst); 448 | if (!winAh.hookInsts.size) { 449 | writable(win, 'XMLHttpRequest', winAh.realXHR); 450 | writable(win, 'fetch', winAh.realFetch); 451 | writable(resProto, 'clone', winAh.realFetchClone); 452 | delete win.__ajaxHooker; 453 | } 454 | } 455 | }; 456 | }(); -------------------------------------------------------------------------------- /Spiders-Lib/ajaxhook-3.0.3.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r=t();for(var n in r)("object"==typeof exports?exports:e)[n]=r[n]}}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=2)}([function(e,t,r){"use strict";function n(e,t){var r={};for(var n in e)r[n]=e[n];return r.target=r.currentTarget=t,r}function o(e,t){function r(t){return function(){var r=this[u][t];if(p){var n=this.hasOwnProperty(t+"_")?this[t+"_"]:r,o=(e[t]||{}).getter;return o&&o(n,this)||n}return r}}function o(t){return function(r){var o=this[u];if(p){var i=this,s=e[t];if("on"===t.substring(0,2))i[t+"_"]=r,o[t]=function(s){s=n(s,i),e[t]&&e[t].call(i,o,s)||r.call(i,s)};else{var a=(s||{}).setter;r=a&&a(r,i)||r,this[t+"_"]=r;try{o[t]=r}catch(e){}}}else o[t]=r}}function a(t){return function(){var r=[].slice.call(arguments);if(e[t]&&p){var n=e[t].call(this,r,this[u]);if(n)return n}return this[u][t].apply(this[u],r)}}function c(){p=!1,t.XMLHttpRequest===v&&(t.XMLHttpRequest=f,v.prototype.constructor=f,f=void 0)}t=t||window;var f=t.XMLHttpRequest,p=!0,v=function(){for(var e=new f,t=0;t1&&void 0!==arguments[1]?arguments[1]:"u",r=s(e),n=Object.values(r),o=function(t){return t.replace(new RegExp("[".concat(n.join(""),"]"),a(new Set([].concat(a(e),a("g")))).join("")),(function(t){return r[t]}))};return new u.RegexFragment(o(t))},e.exact=function(t,e){return(0,u.regex)(e)(n||(n=o(["",""])),t)},e.regexLength=function(t){return t.replace(/\\(?:\w\{[^}]+\}|u[0-9a-f]{4}|x[0-9a-f]{2}|[0-8]{3}|c[A-Z]|.)/gi,".").length},e.getContextAgnosticMap=void 0;var u=r(438),c=Array.from({length:128},(function(t,e){return String.fromCodePoint(e)})),i=new Map,s=function(t){var e=i.get(t);if(e)return e;var r=Object.fromEntries(function(t){var e=new Set(t);return e.delete("i"),t=a(e).join(""),c.map((function(e){var r="\\x".concat(e.codePointAt(0).toString(16).padStart(2,"0")),n=r,o=r,a=r;try{var u=new RegExp("[".concat(e,"]"),t);new RegExp("[".concat(e).concat(e,"]"),t),new RegExp("[".concat(e).concat(e,"\0]"),t),u.test(e)&&!c.filter((function(t){return t!==e})).some((function(t){return u.test(t)}))?n=e:(new RegExp("[\\".concat(e,"]"),t),n="\\".concat(e))}catch(r){try{new RegExp("[\\".concat(e,"]"),t),n="\\".concat(e)}catch(t){}}try{var i=new RegExp("^".concat(e,"$"),t);i.test(e)&&!c.filter((function(t){return t!==e})).some((function(t){return i.test(t)}))?o=e:(new RegExp("\\".concat(e),t),o="\\".concat(e))}catch(r){try{new RegExp("\\".concat(e),t),o="\\".concat(e)}catch(t){}}if(n!==o)try{new RegExp("\\".concat(e),t),new RegExp("\\".concat(e),t),a="\\".concat(e)}catch(t){}else a=[n,o].sort((function(t,e){return e.length-t.length}))[0];return{ch:e,agnostic:a,inClass:n,outsideClass:o}})).filter((function(t){return t.inClass!==t.ch||t.outsideClass!==t.ch}))}(t).map((function(t){return[t.ch,t.agnostic]})));return i.set(t,r),r};e.getContextAgnosticMap=s},403:function(t,e,r){"use strict";Object.defineProperty(e,"Sz",{enumerable:!0,get:function(){return n.regex}}),Object.defineProperty(e,"pH",{enumerable:!0,get:function(){return n.RegexFragment}}),Object.defineProperty(e,"PB",{enumerable:!0,get:function(){return o.regexEscape}});var n=r(438),o=r(98),a=r(761),u=r(690)},690:function(t,e,r){"use strict";var n=r(235).default;Object.defineProperty(e,"__esModule",{value:!0}),e.proxy=void 0;var o=r(438),a=new Proxy(o.regex,{get:function(t,e){return t("_"===e?"":e)},apply:function(t,e,r){return t.apply(void 0,n(r))}});e.proxy=a},438:function(t,e,r){"use strict";var n=r(488).default,o=r(235).default,a=r(218).default,u=r(608).default,c=r(590).default,i=r(680).default,s=r(929).default;Object.defineProperty(e,"__esModule",{value:!0}),e.regex=function(){for(var t=arguments.length,e=new Array(t),r=0;r0&&void 0!==arguments[0]?arguments[0]:{};return function(e){for(var r=arguments.length,a=new Array(r>1?r-1:0),u=1;ut.length)&&(e=t.length);for(var r=0,n=new Array(e);r1&&void 0!==arguments[1]?arguments[1]:{},a=r.rawHost,u=r.rawPathAndQuery,c=o.defaultScheme,i=void 0===c?"https":c,s=o.subdomain,f=void 0===s?"":s,x=o.pathAndQueryReplacer,h=void 0===x?"":x,y=o.rootDomain,v=void 0===y?"example.com":y,g=o.strict,m=void 0===g||g,b="*"===r.scheme?i:r.scheme;n="file"===b?"":"*"===a?[f,v].filter(Boolean).join("."):a.replace(/^\*./,f?"".concat(f,"."):"");var w=(m?u:"/*").replace(/\*/g,"-".concat(h,"-")).replace((0,l.Sz)("g")(t||(t=p()(["-+(",")"])),d),"$1").replace((0,l.Sz)("g")(e||(e=p()(["(",")-+"])),d),"$1").replace(/\/+/g,"/");try{return new URL("".concat(b,"://").concat(n).concat(w))}catch(t){return null}}var h,y,v,g=r(488),m=r.n(g),b="",w=(0,l.Sz)()(h||(h=p()(["\n\t^\n\t\t(*|w+) # scheme\n\t\t://\n\t\t(\n\t\t\t* | # Any host\n\t\t\t[^/#]* # Only the given host (optional only if scheme is file)\n\t\t)\n\t\t(/[^\r\n#]*) # path\n\t$\n"],["\n\t^\n\t\t(\\*|\\w+) # scheme\n\t\t://\n\t\t(\n\t\t\t\\* | # Any host\n\t\t\t[^/\\#]* # Only the given host (optional only if scheme is file)\n\t\t)\n\t\t(/[^\\r\\n\\#]*) # path\n\t$\n"])));function _(t){if(t===b)return{pattern:t,scheme:"*",rawHost:"*",rawPathAndQuery:"/*"};var e=t.match(w);if(!e)return null;var r=m()(e,4);return{pattern:t,scheme:r[1],rawHost:r[2],rawPathAndQuery:r[3]}}var j,O,S,M=function(t){try{return encodeURI(decodeURI(t))}catch(t){return t}};function E(t){return function(e){var r;try{var n=e instanceof URL?e.href:e;r=new URL(n);var o=M(r.pathname),a=M(r.search);if(o instanceof Error||a instanceof Error)return!1;r.pathname=o,r.href.endsWith("?")||(r.search=a)}catch(t){return!1}return t(r)}}function P(t,e){var r,n=e.supportedSchemes,o=e.schemeStarMatchesWs,a=e.strict;if(t===b)return E((function(t){return(0,l.Sz)()(j||(j=p()(["\n\t\t\t\t^\n\t\t\t\t\t(?:",")\n\t\t\t\t\t:\n\t\t\t\t$\n\t\t\t"])),n).test(t.protocol)}));var u=null===(r=t.match(/^(urn|data):/))||void 0===r?void 0:r[1];if(u)return new TypeError('browser-extension-url-match does not currently support scheme "'.concat(u,'"'));var c=_(t);if(!c){try{var i=new URL(t);if(i.hash||i.href.endsWith("#"))return new TypeError('Pattern cannot contain a hash: "'.concat(t,'" contains hash "').concat(i.hash||"#",'"'));if(!t.slice(i.origin.length).startsWith("/"))return new TypeError('Pattern "'.concat(t,'" does not contain a path. Use "').concat(t,'/*" to match any paths with that origin or "').concat(t,'/" to match that URL alone'))}catch(t){}return new TypeError('Pattern "'.concat(t,'" is invalid'))}var s=c.scheme,f=c.rawPathAndQuery;if("*"!==s&&!n.includes(s))return new TypeError('Scheme "'.concat(s,'" is not supported'));var d=(0,l.Sz)()(O||(O=p()(["",":"])),"*"===s?new l.pH(["https?",o&&"wss?"].filter(Boolean).join("|")):s),h=function(t){var e=t.pattern,r=t.scheme,n=t.rawHost;if(!n&&"file"!==r)return new TypeError('Host is optional only if the scheme is "file".');var o=n.includes("*");if(o){var a=n.split("*.");if(n.length>1&&(2!==a.length||a[0]||!a[1]))return new TypeError('Host can contain only one wildcard at the start, in the form "*."')}var u=x(t,{subdomain:""});if(!u)return new TypeError('Pattern "'.concat(e,'" cannot be used to construct a valid URL.'));var c=u.host;if(/:\d+$/.test(c))return new TypeError('Host "'.concat(n,'" cannot include a port number. All ports are matched by default.'));if(/[^.a-z0-9\-]/.test(c))return new TypeError('Host "'.concat(n,'" contains invalid characters.'));var i=o?"*."+c:c;return"*"===n?/.+/:i.startsWith("*.")?(0,l.Sz)()(y||(y=p()(["\n\t\t\t^\n\t\t\t\t(?:[^.]+.)* # any number of dot-terminated segments\n\t\t\t\t"," # rest after leading *.\n\t\t\t$\n\t\t"],["\n\t\t\t^\n\t\t\t\t(?:[^.]+\\.)* # any number of dot-terminated segments\n\t\t\t\t"," # rest after leading *.\n\t\t\t$\n\t\t"])),i.slice(2)):(0,l.Sz)()(v||(v=p()(["^","$"])),i)}(c);if(h instanceof Error)return h;var g=a?M(f):"/*";if(g instanceof Error)return g;var m=(0,l.Sz)()(S||(S=p()(["^","$"])),new l.pH(g.split("*").map((function(t){return(0,l.PB)(t)})).join(".*")));return E((function(t){var e=t.pathname+(t.href.endsWith("?")?"?":t.search);return d.test(t.protocol)&&h.test(t.hostname)&&m.test(e)}))}function A(){if(!this.valid)throw new TypeError(this.error.message);return this}function R(t){return function(e){var r=c()(c()({},s),t),n=P(e,r);return n instanceof Error?{valid:!1,error:n,assertValid:A}:{valid:!0,match:n,get examples(){return function(t,e){var r=_(t),n=e.supportedSchemes,o=e.strict,u=["","www","foo.bar"],c=["example.com"],i=["","foo","/bar/baz/"],s=n.flatMap((function(t){return u.flatMap((function(e){return c.flatMap((function(n){return i.flatMap((function(a){return x(r,{defaultScheme:t,subdomain:e,rootDomain:n,pathAndQueryReplacer:a,strict:o})}))}))}))}));return a()(new Set(s.filter(Boolean).map((function(t){return t.href}))))}(e,r).filter((function(t){return n(t)})).slice(0,100)},patterns:[e],config:r,assertValid:A}}}function T(t){return t.every((function(t){return t.valid}))}function $(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r="string"==typeof t?[t]:a()(new Set(t));if(1===r.length)return R(e)(r[0]);var n=r.map(R(e));if(T(n))return{valid:!0,get examples(){return a()(new Set(n.flatMap((function(t){return t.examples}))))},match:function(t){return n.some((function(e){return e.match(t)}))},patterns:r,config:e,assertValid:A};var o=n.find((function(t){return!t.valid}));return{valid:!1,error:o.error,assertValid:A}}}(),n}()})); -------------------------------------------------------------------------------- /Spiders-Lib/maccms-1.0.2.js: -------------------------------------------------------------------------------- 1 | // let option ={ 2 | // playerContent: { 3 | // defaultResult: { 4 | // class: [{ 5 | // type_id: 6, 6 | // type_name: "短剧" 7 | // }] 8 | // } 9 | // } 10 | // } 11 | var MacCmsGMSpiderTool = { 12 | formatImgUrl: function (url, configPicUserAgent, customBaseUrl) { 13 | if (!url.startsWith("http")) { 14 | if (customBaseUrl) { 15 | url = customBaseUrl + url; 16 | } else { 17 | url = window.location.origin + url; 18 | } 19 | } 20 | if (configPicUserAgent) { 21 | url = url + "@User-Agent=" + window.navigator.userAgent; 22 | } 23 | return url; 24 | } 25 | } 26 | var MacCmsGMSpider = function (options) { 27 | const categoryFilterCachePrefix = "category_"; 28 | 29 | function getVodList() { 30 | if (options?.getVodList) { 31 | return options.getVodList(); 32 | } 33 | let vodList = []; 34 | $("a.module-item").each(function () { 35 | vodList.push({ 36 | vod_id: $(this).attr("href"), 37 | vod_name: $(this).find(".module-poster-item-title").text().trim(), 38 | vod_pic: MacCmsGMSpiderTool.formatImgUrl($(this).find(".module-item-pic img").data("original"), options?.configPicUserAgent), 39 | vod_remarks: $(this).find(".module-item-douban").text().trim(), 40 | vod_year: $(this).find(".module-item-note").text().trim() 41 | }) 42 | }); 43 | return vodList; 44 | } 45 | 46 | function getSearchVodList() { 47 | let vodList = []; 48 | $(".module-card-item").each(function () { 49 | vodList.push({ 50 | vod_id: $(this).find(".module-card-item-poster").attr("href"), 51 | vod_name: $(this).find(".module-card-item-title").text().trim(), 52 | vod_pic: MacCmsGMSpiderTool.formatImgUrl($(this).find(".module-item-pic img").data("original"), options?.configPicUserAgent), 53 | vod_remarks: $(this).find(".module-item-douban").text().trim(), 54 | vod_year: $(this).find(".module-item-note").text().trim() 55 | }) 56 | }); 57 | return vodList; 58 | } 59 | 60 | function getPageCount(currentPage) { 61 | if (options?.pageCountStyle) { 62 | return $(options?.pageCountStyle).length > 0 ? currentPage + 1 : currentPage; 63 | } else { 64 | return $("#page").find(".page-link:last").attr("href")?.split(/[/.]/).at(2).split("-").at(8) || 1; 65 | } 66 | } 67 | 68 | function cacheCategoryFilter(tid) { 69 | let filters; 70 | if (options?.getCategoryFilter) { 71 | filters = options.getCategoryFilter(); 72 | } else { 73 | filters = getCategoryFilter(); 74 | } 75 | localStorage.setItem(categoryFilterCachePrefix + tid, JSON.stringify(filters)); 76 | } 77 | 78 | function getCategoryFilter() { 79 | const filters = []; 80 | $(".module-class-item").each(function () { 81 | const filter = { 82 | key: "", 83 | name: $(this).find(".module-item-title").text().trim(), 84 | value: [] 85 | } 86 | $(this).find(".module-item-box a").each(function () { 87 | const params = $(this).attr("href").split(/[/.]/).at(2).split("-").slice(1); 88 | filter.key = "index" + params.findIndex((element) => element.length > 0) 89 | filter.value.push({ 90 | n: $(this).text().trim(), 91 | v: params.find((element) => element.length > 0) || "" 92 | }) 93 | }) 94 | filters.push(filter); 95 | }) 96 | return filters; 97 | } 98 | 99 | return { 100 | homeContent: function (filter) { 101 | const option = options.homeContent; 102 | let result = Object.assign({ 103 | class: [], 104 | filters: {}, 105 | list: [] 106 | }, option?.defaultResult || {}); 107 | $(option.category.select).slice(...option.category.slice).each(function () { 108 | let categoryHref = $(this).find("a").attr("href"); 109 | if (categoryHref.startsWith("http")) { 110 | if (categoryHref.startsWith(window.location.origin)) { 111 | categoryHref = categoryHref.substring(window.location.origin.length); 112 | } else { 113 | return true; 114 | } 115 | } 116 | const categoryId = categoryHref.split(/[/.]/).at(2); 117 | result.class.push({ 118 | type_id: categoryId, 119 | type_name: $(this).find("a").text().trim() 120 | }); 121 | }) 122 | result.class.forEach(function (item) { 123 | const cacheFilter = localStorage.getItem(categoryFilterCachePrefix + item.type_id); 124 | if (typeof cacheFilter !== "undefined" && cacheFilter !== null) { 125 | result.filters[item.type_id] = JSON.parse(cacheFilter); 126 | } 127 | }) 128 | result.list = getVodList(); 129 | return result; 130 | }, 131 | categoryContent: function (tid, pg, filter, extend) { 132 | let result = { 133 | list: [], 134 | pagecount: getPageCount(pg) 135 | }; 136 | cacheCategoryFilter(tid); 137 | result.list = getVodList(); 138 | return result; 139 | }, 140 | detailContent: function (ids) { 141 | if (options?.detailContent?.customFunction) { 142 | return options.detailContent.customFunction(ids); 143 | } 144 | let items = {}; 145 | $(".module-info-item").each(function () { 146 | items[$(this).find(".module-info-item-title").text().trim().replace(":", "")] = $(this).find(".module-info-item-content").text().trim(); 147 | }); 148 | let vodPlayData = []; 149 | $("#y-playList .module-tab-item").each(function (i) { 150 | let media = []; 151 | $(`.module-play-list:eq(${i}) .module-play-list-link`).each(function () { 152 | media.push({ 153 | name: $(this).text().trim(), 154 | type: "webview", 155 | ext: { 156 | replace: { 157 | playUrl: $(this).attr("href"), 158 | } 159 | } 160 | }); 161 | }) 162 | vodPlayData.push({ 163 | from: $(this).data("dropdown-value"), 164 | media: media 165 | }) 166 | }) 167 | 168 | return vod = { 169 | vod_id: ids[0], 170 | vod_name: $(".module-info-heading h1").text().trim(), 171 | vod_pic: MacCmsGMSpiderTool.formatImgUrl($(".module-info-poster .module-item-pic img").data("original"),options?.configPicUserAgent), 172 | vod_remarks: items?.["更新"] || "", 173 | vod_director: items?.["导演"] || "", 174 | vod_actor: items?.["主演"] || "", 175 | vod_content: $(".module-info-introduction-content").text().trim(), 176 | vod_play_data: vodPlayData 177 | }; 178 | }, 179 | playerContent: function (flag, id, vipFlags) { 180 | if (options?.playerContent?.OkPlayer) { 181 | if ($("#playleft iframe").contents()[0].readyState === 'complete') { 182 | $("#playleft iframe").contents().find("#start").click(); 183 | } else { 184 | $('#playleft iframe').on("load", function () { 185 | $("#playleft iframe").contents().ready(function () { 186 | $("#playleft iframe").contents().find("#start").click(); 187 | }) 188 | }); 189 | } 190 | } 191 | return { 192 | type: "match" 193 | }; 194 | }, 195 | searchContent: function (key, quick, pg) { 196 | const result = { 197 | list: [], 198 | pagecount: getPageCount(pg) 199 | }; 200 | result.list = getSearchVodList(); 201 | return result; 202 | } 203 | }; 204 | } -------------------------------------------------------------------------------- /index.json: -------------------------------------------------------------------------------- 1 | { 2 | "spider": "./Spiders-Lib/GM.jar;md5;7dd67a73e49dbf1cd32f56e329fce7b3", 3 | "sites": [ 4 | { 5 | "key": "hitv", 6 | "name": "Hi视频 | 自营", 7 | "type": 3, 8 | "searchable": 1, 9 | "changeable": 1, 10 | "quickSearch": 0, 11 | "style": { 12 | "type": "rect", 13 | "ratio": 0.71 14 | }, 15 | "api": "csp_GM", 16 | "ext": { 17 | "userScript": "./userScripts/hitv.user.js", 18 | "debug": false, 19 | "webViewSettings": { 20 | "blockNetworkImage": true, 21 | "blockList": [ 22 | "https://*.google-analytics.com/*" 23 | ] 24 | }, 25 | "spider": { 26 | "homeContent": { 27 | "loadUrl": "https://www.upfuhn.com/column/0.html" 28 | }, 29 | "categoryContent": { 30 | "loadUrl": "https://www.upfuhn.com/column/${tid}.html" 31 | }, 32 | "detailContent": { 33 | "loadUrl": "https://www.upfuhn.com/play/${id}-1-0.html" 34 | }, 35 | "searchContent": { 36 | "loadUrl": "https://www.upfuhn.com/search/${key}.html" 37 | } 38 | } 39 | } 40 | }, 41 | { 42 | "key": "mqtv", 43 | "name": "麻雀视频 | 自营", 44 | "type": 3, 45 | "searchable": 1, 46 | "changeable": 1, 47 | "quickSearch": 0, 48 | "style": { 49 | "type": "rect", 50 | "ratio": 0.71 51 | }, 52 | "api": "csp_GM", 53 | "ext": { 54 | "userScript": "./userScripts/mqtv.user.js", 55 | "debug": false, 56 | "webViewSettings": { 57 | "blockNetworkImage": true, 58 | "blockList": [ 59 | "https://hm.baidu.com/*", 60 | "https://*.n3f2.cn/*" 61 | ] 62 | }, 63 | "playUrlMatch": [ 64 | "https://*/obj/tos-*", 65 | "*://*/*.mp4*", 66 | "*://*/*.m3u8*" 67 | ], 68 | "spider": { 69 | "homeContent": { 70 | "loadUrl": "https://www.mqtv.cc/" 71 | }, 72 | "categoryContent": { 73 | "loadUrl": "https://www.mqtv.cc/type/${tid}" 74 | }, 75 | "detailContent": { 76 | "loadUrl": "https://www.mqtv.cc${id}" 77 | }, 78 | "playerContent": { 79 | "loadUrl": "https://www.mqtv.cc${url}#${anchor}" 80 | }, 81 | "searchContent": { 82 | "loadUrl": "https://www.mqtv.cc/search/${key}" 83 | } 84 | } 85 | } 86 | }, 87 | { 88 | "key": "gaze", 89 | "name": "注视影视 | 自营", 90 | "type": 3, 91 | "searchable": 1, 92 | "changeable": 1, 93 | "quickSearch": 0, 94 | "style": { 95 | "type": "rect", 96 | "ratio": 0.66 97 | }, 98 | "api": "csp_GM", 99 | "ext": { 100 | "userScript": "./userScripts/gaze.user.js", 101 | "debug": false, 102 | "webViewSettings": { 103 | "blockNetworkImage": true, 104 | "blockList": [ 105 | "https://*.bytecdntp.com/cdn/expire-1-M/font-awesome/*", 106 | "https://*.clarity.ms/*", 107 | "https://gaze.run/visitorslog.php*", 108 | "*.css*" 109 | ] 110 | }, 111 | "playUrlMatch": [ 112 | "https://dl-b.cloud.189.cn/corp/downloadFile.action?*", 113 | "https://gaze.run/gaze_filey/pb/*.m3u8", 114 | "https://*/obj/tos*" 115 | ], 116 | "spider": { 117 | "homeContent": { 118 | "loadUrl": "https://gaze.run/filter" 119 | }, 120 | "categoryContent": { 121 | "loadUrl": "https://gaze.run/filter" 122 | }, 123 | "detailContent": { 124 | "loadUrl": "https://gaze.run/play/${id}" 125 | }, 126 | "playerContent": { 127 | "loadUrl": "https://gaze.run/play/${mcid}#${path}" 128 | }, 129 | "searchContent": { 130 | "loadUrl": "https://gaze.run/filter" 131 | } 132 | } 133 | } 134 | }, 135 | { 136 | "key": "zxzjhd", 137 | "name": "在线之家 | 自营", 138 | "type": 3, 139 | "searchable": 1, 140 | "changeable": 1, 141 | "quickSearch": 0, 142 | "style": { 143 | "type": "rect", 144 | "ratio": 0.71 145 | }, 146 | "api": "csp_GM", 147 | "ext": { 148 | "userScript": "./userScripts/zxzjhd.user.js", 149 | "debug": false, 150 | "webViewSettings": { 151 | "blockNetworkImage": true, 152 | "blockList": [ 153 | "https://hm.baidu.com/*", 154 | "https://*.51.la/*" 155 | ] 156 | }, 157 | "playUrlMatch": [ 158 | "*://*/*.mp4*" 159 | ], 160 | "spider": { 161 | "homeContent": { 162 | "loadUrl": "https://www.zxzjhd.com/" 163 | }, 164 | "categoryContent": { 165 | "loadUrl": "https://www.zxzjhd.com/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 166 | }, 167 | "detailContent": { 168 | "loadUrl": "https://www.zxzjhd.com${id}" 169 | }, 170 | "playerContent": { 171 | "loadUrl": "https://www.zxzjhd.com${playUrl}" 172 | }, 173 | "searchContent": { 174 | "loadUrl": "https://www.zxzjhd.com/vodsearch/${key}----------${pg:-1}---.html" 175 | } 176 | } 177 | } 178 | }, 179 | { 180 | "key": "kkys", 181 | "name": "可可影视 | 聚合", 182 | "type": 3, 183 | "searchable": 0, 184 | "changeable": 1, 185 | "quickSearch": 0, 186 | "style": { 187 | "type": "rect", 188 | "ratio": 0.71 189 | }, 190 | "api": "csp_GM", 191 | "ext": { 192 | "userScript": "./userScripts/kkys.user.js", 193 | "debug": false, 194 | "webViewSettings": { 195 | "blockNetworkImage": true, 196 | "blockList": [ 197 | "https://hm.baidu.com/*", 198 | "https://*/disable-devtool/*" 199 | ] 200 | }, 201 | "playUrlMatch": [ 202 | "https://*/*.m3u8*" 203 | ], 204 | "spider": { 205 | "homeContent": { 206 | "loadUrl": "https://www.kkys01.com/" 207 | }, 208 | "categoryContent": { 209 | "loadUrl": "https://www.kkys01.com/show/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-3}-${pg:-1}.html" 210 | }, 211 | "detailContent": { 212 | "loadUrl": "https://www.kkys01.com${id}" 213 | }, 214 | "playerContent": { 215 | "loadUrl": "https://www.kkys01.com${playUrl}" 216 | }, 217 | "searchContent": { 218 | "loadUrl": "https://www.kkys01.com/search?k=${key}&page=${pg:-1}" 219 | } 220 | } 221 | } 222 | }, 223 | { 224 | "key": "ppxys", 225 | "name": "皮皮虾影视 | 自营", 226 | "type": 3, 227 | "searchable": 1, 228 | "changeable": 1, 229 | "quickSearch": 0, 230 | "style": { 231 | "type": "rect", 232 | "ratio": 0.71 233 | }, 234 | "api": "csp_GM", 235 | "ext": { 236 | "userScript": "./userScripts/ppxys.user.js", 237 | "debug": false, 238 | "webViewSettings": { 239 | "blockNetworkImage": true, 240 | "blockList": [ 241 | "https://hm.baidu.com/*", 242 | "*://*.51.la/*", 243 | "*://*.ctyunxs.cn/*" 244 | ] 245 | }, 246 | "playUrlMatch": [ 247 | "*://*/*.mp4*" 248 | ], 249 | "spider": { 250 | "homeContent": { 251 | "loadUrl": "http://www.ppxys.vip/" 252 | }, 253 | "categoryContent": { 254 | "loadUrl": "http://www.ppxys.vip/s/${tid}${index0:-}${index1:-}${index2:-}${index3:-}${index4:-}${index5:-}/page/${pg:-1}.html" 255 | }, 256 | "detailContent": { 257 | "loadUrl": "http://www.ppxys.vip${id}" 258 | }, 259 | "playerContent": { 260 | "loadUrl": "http://www.ppxys.vip${playUrl}" 261 | }, 262 | "searchContent": { 263 | "loadUrl": "http://www.ppxys.vip/search?k=${key}&page=${pg:-1}" 264 | } 265 | } 266 | } 267 | }, 268 | { 269 | "key": "yfsp", 270 | "name": "爱壹帆 | 自营🚧", 271 | "type": 3, 272 | "searchable": 1, 273 | "changeable": 1, 274 | "quickSearch": 0, 275 | "style": { 276 | "type": "rect", 277 | "ratio": 0.75 278 | }, 279 | "api": "csp_GM", 280 | "ext": { 281 | "userScript": "./userScripts/ysfp.user.js", 282 | "debug": false, 283 | "webViewSettings": { 284 | "blockNetworkImage": true, 285 | "blockList": [ 286 | "*.png*", 287 | "*.mp3*", 288 | "*.css*", 289 | "https://*.googletagmanager.com/*", 290 | "https://*.google-analytics.com/*" 291 | ] 292 | }, 293 | "spider": { 294 | "homeContent": { 295 | "loadUrl": "https://m.yfsp.tv/" 296 | }, 297 | "categoryContent": { 298 | "loadUrl": "https://m.yfsp.tv/list/${tid}?type=${index-0:-0}${index-1:-,0}${index-2:-,0}${index-3:-,0}${index-4:-,0}${index-5:-}" 299 | }, 300 | "detailContent": { 301 | "loadUrl": "https://m.yfsp.tv/play/${id}" 302 | }, 303 | "playerContent": { 304 | "loadUrl": "https://m.yfsp.tv/play/${mediaKey}?id=${episodeKey}" 305 | }, 306 | "searchContent": { 307 | "loadUrl": "https://m.yfsp.tv/search" 308 | } 309 | } 310 | } 311 | }, 312 | { 313 | "key": "bilfun", 314 | "name": "BILFUN | 聚合", 315 | "type": 3, 316 | "searchable": 1, 317 | "changeable": 1, 318 | "quickSearch": 0, 319 | "style": { 320 | "type": "rect", 321 | "ratio": 0.71 322 | }, 323 | "api": "csp_GM", 324 | "ext": { 325 | "userScript": "./userScripts/bilfun.user.js", 326 | "debug": false, 327 | "webViewSettings": { 328 | "blockNetworkImage": true, 329 | "blockList": [ 330 | "https://*.51.la/*", 331 | "https://collect-v6.51.la/*" 332 | ] 333 | }, 334 | "playUrlMatch": [ 335 | "*://*/*.m3u8*" 336 | ], 337 | "spider": { 338 | "homeContent": { 339 | "loadUrl": "https://bilfun.cc/" 340 | }, 341 | "categoryContent": { 342 | "loadUrl": "https://bilfun.cc/bilfunshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 343 | }, 344 | "detailContent": { 345 | "loadUrl": "https://bilfun.cc${id}" 346 | }, 347 | "playerContent": { 348 | "loadUrl": "https://bilfun.cc${playUrl}" 349 | }, 350 | "searchContent": { 351 | "loadUrl": "https://bilfun.cc/bilfunsearch/${key}----------${pg:-1}---.html" 352 | } 353 | } 354 | } 355 | }, 356 | { 357 | "key": "huochetaidu", 358 | "name": "火车太堵 | 聚合", 359 | "type": 3, 360 | "searchable": 1, 361 | "changeable": 1, 362 | "quickSearch": 0, 363 | "style": { 364 | "type": "rect", 365 | "ratio": 0.71 366 | }, 367 | "api": "csp_GM", 368 | "ext": { 369 | "userScript": "./userScripts/huochetaidu.user.js", 370 | "debug": false, 371 | "webViewSettings": { 372 | "blockNetworkImage": true, 373 | "blockList": [ 374 | "https://hm.baidu.com/*" 375 | ] 376 | }, 377 | "playUrlMatch": [ 378 | "*://*/*.m3u8*" 379 | ], 380 | "spider": { 381 | "homeContent": { 382 | "loadUrl": "https://www.tdgo.shop/" 383 | }, 384 | "categoryContent": { 385 | "loadUrl": "https://www.tdgo.shop/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 386 | }, 387 | "detailContent": { 388 | "loadUrl": "https://www.tdgo.shop${id}" 389 | }, 390 | "playerContent": { 391 | "loadUrl": "https://www.tdgo.shop${playUrl}" 392 | }, 393 | "searchContent": { 394 | "loadUrl": "https://www.tdgo.shop/vodsearch/${key}----------${pg:-1}---.html" 395 | } 396 | } 397 | } 398 | }, 399 | { 400 | "key": "fantuan", 401 | "name": "饭团影视 | 聚合", 402 | "type": 3, 403 | "searchable": 1, 404 | "changeable": 1, 405 | "quickSearch": 0, 406 | "style": { 407 | "type": "rect", 408 | "ratio": 0.71 409 | }, 410 | "api": "csp_GM", 411 | "ext": { 412 | "userScript": "./userScripts/fantuan.user.js", 413 | "debug": false, 414 | "webViewSettings": { 415 | "blockNetworkImage": true, 416 | "blockList": [ 417 | "https://hm.baidu.com/*" 418 | ] 419 | }, 420 | "playUrlMatch": [ 421 | "*://*/*.m3u8*" 422 | ], 423 | "spider": { 424 | "homeContent": { 425 | "loadUrl": "https://www.fantuan.vip/" 426 | }, 427 | "categoryContent": { 428 | "loadUrl": "https://www.fantuan.vip/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 429 | }, 430 | "detailContent": { 431 | "loadUrl": "https://www.fantuan.vip${id}" 432 | }, 433 | "playerContent": { 434 | "loadUrl": "https://www.fantuan.vip${playUrl}" 435 | }, 436 | "searchContent": { 437 | "loadUrl": "https://www.fantuan.vip/vodsearch/${key}----------${pg:-1}---.html" 438 | } 439 | } 440 | } 441 | }, 442 | { 443 | "key": "pipiys", 444 | "name": "皮皮影视 | 聚合", 445 | "type": 3, 446 | "searchable": 1, 447 | "changeable": 1, 448 | "quickSearch": 0, 449 | "style": { 450 | "type": "rect", 451 | "ratio": 0.71 452 | }, 453 | "api": "csp_GM", 454 | "ext": { 455 | "userScript": "./userScripts/pipiys.user.js", 456 | "debug": false, 457 | "webViewSettings": { 458 | "blockNetworkImage": true, 459 | "blockList": [ 460 | "https://hm.baidu.com/*" 461 | ] 462 | }, 463 | "playUrlMatch": [ 464 | "*://*/*.m3u8*" 465 | ], 466 | "spider": { 467 | "homeContent": { 468 | "loadUrl": "https://www.pipiys1.com/" 469 | }, 470 | "categoryContent": { 471 | "loadUrl": "https://www.pipiys1.com/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 472 | }, 473 | "detailContent": { 474 | "loadUrl": "https://www.pipiys1.com${id}" 475 | }, 476 | "playerContent": { 477 | "loadUrl": "https://www.pipiys1.com${playUrl}" 478 | }, 479 | "searchContent": { 480 | "loadUrl": "https://www.pipiys1.com/vodsearch/${key}----------${pg:-1}---.html" 481 | } 482 | } 483 | } 484 | }, 485 | { 486 | "key": "freeok", 487 | "name": "FreeOK | 聚合", 488 | "type": 3, 489 | "searchable": 1, 490 | "changeable": 1, 491 | "quickSearch": 0, 492 | "style": { 493 | "type": "rect", 494 | "ratio": 0.71 495 | }, 496 | "api": "csp_GM", 497 | "ext": { 498 | "userScript": "./userScripts/freeok.user.js", 499 | "debug": false, 500 | "webViewSettings": { 501 | "blockNetworkImage": true, 502 | "blockList": [ 503 | "https://hm.baidu.com/*" 504 | ] 505 | }, 506 | "playUrlMatch": [ 507 | "*://*/*.m3u8*" 508 | ], 509 | "spider": { 510 | "homeContent": { 511 | "loadUrl": "https://www.freeok.la/" 512 | }, 513 | "categoryContent": { 514 | "loadUrl": "https://www.freeok.la/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 515 | }, 516 | "detailContent": { 517 | "loadUrl": "https://www.freeok.la${id}" 518 | }, 519 | "playerContent": { 520 | "loadUrl": "https://www.freeok.la${playUrl}" 521 | }, 522 | "searchContent": { 523 | "loadUrl": "https://www.freeok.la/vodsearch/${key}----------${pg:-1}---.html" 524 | } 525 | } 526 | } 527 | }, 528 | { 529 | "key": "ppdys", 530 | "name": "皮皮蛋影视 | 聚合", 531 | "type": 3, 532 | "searchable": 1, 533 | "changeable": 1, 534 | "quickSearch": 0, 535 | "style": { 536 | "type": "rect", 537 | "ratio": 0.71 538 | }, 539 | "api": "csp_GM", 540 | "ext": { 541 | "userScript": "./userScripts/ppdys.user.js", 542 | "debug": false, 543 | "webViewSettings": { 544 | "blockNetworkImage": true, 545 | "blockList": [ 546 | "https://hm.baidu.com/*" 547 | ] 548 | }, 549 | "playUrlMatch": [ 550 | "*://*/*.m3u8*" 551 | ], 552 | "spider": { 553 | "homeContent": { 554 | "loadUrl": "https://www.ppdys.me/" 555 | }, 556 | "categoryContent": { 557 | "loadUrl": "https://www.ppdys.me/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 558 | }, 559 | "detailContent": { 560 | "loadUrl": "https://www.ppdys.me${id}" 561 | }, 562 | "playerContent": { 563 | "loadUrl": "https://www.ppdys.me${playUrl}" 564 | }, 565 | "searchContent": { 566 | "loadUrl": "https://www.ppdys.me/vodsearch/${key}----------${pg:-1}---.html" 567 | } 568 | } 569 | } 570 | }, 571 | { 572 | "key": "dandantu", 573 | "name": "蛋蛋兔 | 聚合", 574 | "type": 3, 575 | "searchable": 1, 576 | "changeable": 1, 577 | "quickSearch": 0, 578 | "style": { 579 | "type": "rect", 580 | "ratio": 0.71 581 | }, 582 | "api": "csp_GM", 583 | "ext": { 584 | "userScript": "./userScripts/dandantu.user.js", 585 | "debug": false, 586 | "webViewSettings": { 587 | "blockNetworkImage": true, 588 | "blockList": [ 589 | "https://hm.baidu.com/*" 590 | ] 591 | }, 592 | "playUrlMatch": [ 593 | "*://*/*.m3u8*" 594 | ], 595 | "spider": { 596 | "homeContent": { 597 | "loadUrl": "https://www.dandantu.cc/" 598 | }, 599 | "categoryContent": { 600 | "loadUrl": "https://www.dandantu.cc/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 601 | }, 602 | "detailContent": { 603 | "loadUrl": "https://www.dandantu.cc${id}" 604 | }, 605 | "playerContent": { 606 | "loadUrl": "https://www.dandantu.cc${playUrl}" 607 | }, 608 | "searchContent": { 609 | "loadUrl": "https://www.dandantu.cc/vodsearch/${key}----------${pg:-1}---.html" 610 | } 611 | } 612 | } 613 | }, 614 | { 615 | "key": "juyeye", 616 | "name": "剧爷爷 | 聚合", 617 | "type": 3, 618 | "searchable": 1, 619 | "changeable": 1, 620 | "quickSearch": 0, 621 | "style": { 622 | "type": "rect", 623 | "ratio": 0.71 624 | }, 625 | "api": "csp_GM", 626 | "ext": { 627 | "userScript": "./userScripts/juyeye.user.js", 628 | "debug": false, 629 | "webViewSettings": { 630 | "blockNetworkImage": true, 631 | "blockList": [ 632 | "https://hm.baidu.com/*" 633 | ] 634 | }, 635 | "playUrlMatch": [ 636 | "*://*/*.m3u8*" 637 | ], 638 | "spider": { 639 | "homeContent": { 640 | "loadUrl": "https://www.juyeye.cc/" 641 | }, 642 | "categoryContent": { 643 | "loadUrl": "https://www.juyeye.cc/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 644 | }, 645 | "detailContent": { 646 | "loadUrl": "https://www.juyeye.cc${id}" 647 | }, 648 | "playerContent": { 649 | "loadUrl": "https://www.juyeye.cc${playUrl}" 650 | }, 651 | "searchContent": { 652 | "loadUrl": "https://www.juyeye.cc/vodsearch/${key}----------${pg:-1}---.html" 653 | } 654 | } 655 | } 656 | }, 657 | { 658 | "key": "yirenmeng", 659 | "name": "番茄影视 | 聚合", 660 | "type": 3, 661 | "searchable": 1, 662 | "changeable": 1, 663 | "quickSearch": 0, 664 | "style": { 665 | "type": "rect", 666 | "ratio": 0.71 667 | }, 668 | "api": "csp_GM", 669 | "ext": { 670 | "userScript": "./userScripts/yirenmeng.user.js", 671 | "debug": false, 672 | "webViewSettings": { 673 | "blockNetworkImage": true, 674 | "blockList": [ 675 | "https://hm.baidu.com/*" 676 | ] 677 | }, 678 | "playUrlMatch": [ 679 | "*://*/*.m3u8*" 680 | ], 681 | "spider": { 682 | "homeContent": { 683 | "loadUrl": "https://www.yirenmeng.com/" 684 | }, 685 | "categoryContent": { 686 | "loadUrl": "https://www.yirenmeng.com/vodshow/${tid}-${index0:-}-${index1:-}-${index2:-}-${index3:-}-${index4:-}-${index5:-}-${index6:-}-${pg:-1}-${index8:-}-${index9:-}-${index10:-}.html" 687 | }, 688 | "detailContent": { 689 | "loadUrl": "https://www.yirenmeng.com${id}" 690 | }, 691 | "playerContent": { 692 | "loadUrl": "https://www.yirenmeng.com${playUrl}" 693 | }, 694 | "searchContent": { 695 | "loadUrl": "https://www.yirenmeng.com/vodsearch/${key}----------${pg:-1}---.html" 696 | } 697 | } 698 | } 699 | } 700 | ] 701 | } -------------------------------------------------------------------------------- /userScripts/bilfun.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | homeContent: { 26 | category: { 27 | select: ".navbar-item", 28 | slice: [1, 6] 29 | }, 30 | defaultResult: { 31 | class: [{ 32 | type_id: "6", 33 | type_name: "短剧" 34 | }] 35 | } 36 | } 37 | }) 38 | 39 | $(document).ready(function () { 40 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 41 | console.log(result); 42 | if (typeof GmSpiderInject !== 'undefined') { 43 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 44 | } 45 | }); 46 | })(); 47 | 48 | -------------------------------------------------------------------------------- /userScripts/dandantu.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 5] 30 | } 31 | }, 32 | playerContent: { 33 | OkPlayer: true 34 | } 35 | }); 36 | $(document).ready(function () { 37 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 38 | console.log(result); 39 | if (typeof GmSpiderInject !== 'undefined') { 40 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 41 | } 42 | }); 43 | })(); 44 | 45 | -------------------------------------------------------------------------------- /userScripts/fantuan.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 5] 30 | } 31 | }, 32 | playerContent: { 33 | OkPlayer: true 34 | } 35 | }); 36 | $(document).ready(function () { 37 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 38 | console.log(result); 39 | if (typeof GmSpiderInject !== 'undefined') { 40 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 41 | } 42 | }); 43 | })(); 44 | 45 | -------------------------------------------------------------------------------- /userScripts/freeok.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "playerContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 5] 30 | } 31 | }, 32 | playerContent: { 33 | OkPlayer: true 34 | } 35 | }); 36 | $(document).ready(function () { 37 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 38 | console.log(result); 39 | if (typeof GmSpiderInject !== 'undefined') { 40 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 41 | } 42 | }); 43 | })(); 44 | 45 | -------------------------------------------------------------------------------- /userScripts/gaze.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name gaze 3 | // @namespace gmspider 4 | // @version 2024.12.01 5 | // @description gaze GMSpider 6 | // @author Luomo 7 | // @match https://gaze.run/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/npm/ajax-hook@3.0.3/dist/ajaxhook.umd.min.js 10 | // @require https://cdn.jsdelivr.net/npm/blob-util@2.0.2/dist/blob-util.min.js 11 | // @grant unsafeWindow 12 | // @run-at document-end 13 | // ==/UserScript== 14 | console.log(JSON.stringify(GM_info)); 15 | (function () { 16 | Object.defineProperty(Object.prototype, '_detectLoopStopped', { 17 | set: function () { 18 | return true; 19 | }, 20 | get: function () { 21 | console.log("devtools-detector disabled"); 22 | return false; 23 | } 24 | }); 25 | })(); 26 | (function () { 27 | const GMSpiderArgs = {}; 28 | if (typeof GmSpiderInject !== 'undefined') { 29 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 30 | GMSpiderArgs.fName = args.shift(); 31 | GMSpiderArgs.fArgs = args; 32 | } else { 33 | GMSpiderArgs.fName = "detailContent"; 34 | GMSpiderArgs.fArgs = [true]; 35 | } 36 | Object.freeze(GMSpiderArgs); 37 | 38 | let _gotData = function (data) { 39 | console.log("_gotData hook failed", data) 40 | }; 41 | let hookRequestUrl = ""; 42 | const {unProxy, originXhr} = proxy({ 43 | onRequest: (config, handler) => { 44 | let params = {}; 45 | switch (GMSpiderArgs.fName) { 46 | case "categoryContent": 47 | let filter = GMSpiderArgs.fArgs[3]; 48 | params = { 49 | mform: GMSpiderArgs.fArgs[0], 50 | mcountry: filter?.mcountry ?? "all", 51 | "tag_arr[]": filter?.mtag ?? "all", 52 | page: GMSpiderArgs.fArgs[1], 53 | sort: filter?.sort ?? "updatetime", 54 | album: "all", 55 | title: "", 56 | years: filter?.years ?? "all", 57 | }; 58 | break; 59 | case "searchContent": 60 | let title = GMSpiderArgs.fArgs[0]; 61 | params = { 62 | mform: "all", 63 | mcountry: "all", 64 | "tag_arr[]": "all", 65 | page: GMSpiderArgs.fArgs[2], 66 | sort: "updatetime", 67 | album: "all", 68 | title: GMSpiderArgs.fArgs[0], 69 | years: "all", 70 | }; 71 | break; 72 | } 73 | if (config.url.includes("filter_movielist")) { 74 | if (!$.isEmptyObject(params)) { 75 | config.body = $.param(params) 76 | } 77 | } 78 | handler.next(config); 79 | }, 80 | onResponse: (response, handler) => { 81 | if (response.config.url.includes("filter_movielist")) { 82 | let data = JSON.parse(response.response); 83 | _gotData(data); 84 | } 85 | handler.next(response); 86 | } 87 | }, unsafeWindow) 88 | 89 | let _gotSrc = function (src) { 90 | console.log("_gotSrc hook failed", data) 91 | }; 92 | let _player; 93 | Object.defineProperty(unsafeWindow, 'player', { 94 | configurable: true, 95 | get: () => _player, 96 | set: (player) => { 97 | _player = new Proxy(player, { 98 | get(target, prop) { 99 | if (prop === "src") { 100 | // console.log("src", src); 101 | return new Proxy(target[prop], { 102 | apply: (target, thisArg, argumentsList) => { 103 | _gotSrc(argumentsList[0]); 104 | // return false; 105 | return Reflect.apply(target, thisArg, argumentsList); 106 | } 107 | }); 108 | } else { 109 | return Reflect.get(target, prop); 110 | } 111 | } 112 | }) 113 | }, 114 | }); 115 | const GmSpider = (function () { 116 | function listVideos(result) { 117 | return new Promise(function (resolve) { 118 | _gotData = resolve; 119 | }).then(async (movieList) => { 120 | console.log("movelist", movieList); 121 | movieList.mlist.forEach(function (item) { 122 | result.list.push({ 123 | vod_id: item.mid, 124 | vod_name: item.title, 125 | vod_pic: item.cover_img, 126 | vod_remarks: "豆瓣 " + item.grade, 127 | vod_year: item.definition 128 | }) 129 | }) 130 | result.pagecount = movieList.pages; 131 | return result; 132 | }); 133 | } 134 | 135 | async function getPlay(src) { 136 | let playData = {}; 137 | if (src.startsWith("blob:")) { 138 | let blob = await fetch(src).then(r => r.blob()); 139 | await blobUtil.blobToBinaryString(blob).then(function (fileData) { 140 | fileData = fileData.replaceAll(' ', ""); 141 | playData = { 142 | type: "file", 143 | ext: { 144 | header: { 145 | "User-Agent": window.navigator.userAgent, 146 | "Referer": window.location.href 147 | }, 148 | file: fileData 149 | } 150 | } 151 | }); 152 | } else { 153 | playData = { 154 | type: "match" 155 | } 156 | } 157 | return playData; 158 | } 159 | 160 | return { 161 | homeContent: function (filter) { 162 | const defaultFilters = [{ 163 | key: "mcountry", 164 | name: "地区", 165 | value: [] 166 | }, { 167 | key: "mtag", 168 | name: "类型", 169 | value: [] 170 | }, { 171 | key: "sort", 172 | name: "排序", 173 | value: [] 174 | }]; 175 | defaultFilters.forEach((item) => { 176 | $(`.${item.key} .filter-item a`).each(function () { 177 | item.value.push({ 178 | n: $(this).text(), 179 | v: $(this).data("filter") 180 | }); 181 | }) 182 | }) 183 | let yearFilter = [{ 184 | n: "全部年份", 185 | v: "all" 186 | }]; 187 | let thisYear = new Date().getFullYear(); 188 | for (let i = 0; i <= 20; i++) { 189 | yearFilter.push({ 190 | n: thisYear - i, 191 | v: thisYear - i, 192 | }) 193 | } 194 | defaultFilters.push({ 195 | key: "years", 196 | name: "年份", 197 | value: yearFilter 198 | }) 199 | const result = { 200 | class: [ 201 | {type_id: "1", type_name: "电影"}, 202 | {type_id: "2", type_name: "电视剧"}, 203 | {type_id: "bangumi", type_name: "番剧"}, 204 | {type_id: "chinese_cartoon", type_name: "国漫"}, 205 | ], 206 | filters: { 207 | "1": defaultFilters, 208 | "2": defaultFilters, 209 | "bangumi": defaultFilters, 210 | "chinese_cartoon": defaultFilters, 211 | }, 212 | list: [] 213 | }; 214 | return listVideos(result); 215 | }, 216 | categoryContent: function (tid, pg, filter, extend) { 217 | console.log(tid, pg, filter, JSON.stringify(extend)); 218 | let result = { 219 | list: [], 220 | limit: 24, 221 | pagecount: 0 222 | }; 223 | return listVideos(result); 224 | }, 225 | detailContent: function (ids) { 226 | let media = []; 227 | $("#btngroup .playbtn").each(function () { 228 | media.push({ 229 | name: $(this).text().trim(), 230 | type: "webview", 231 | ext: { 232 | replace: { 233 | mcid: unsafeWindow.mcid, 234 | path: $(this).data("path") 235 | } 236 | } 237 | }) 238 | }) 239 | return { 240 | vod_id: ids[0], 241 | vod_name: $(".d-flex .grade:first").text().trim(), 242 | vod_pic: $(".d-flex .pimgs").attr("src"), 243 | vod_remarks: $(".d-flex .grade:eq(1)").text().trim(), 244 | vod_content: $(".d-flex p").text().trim(), 245 | vod_play_data: [{ 246 | from: "注视影视", 247 | media: media 248 | }] 249 | }; 250 | }, 251 | playerContent: function (flag, id, vipFlags) { 252 | console.log(flag, id, unsafeWindow.mid); 253 | localStorage.setItem('mobj' + unsafeWindow.mid, JSON.stringify({ 254 | video_index: window.location.hash.split("#").at(1), 255 | video_time: 1 256 | })); 257 | return new Promise(function (resolve) { 258 | _gotSrc = resolve; 259 | }).then(async (playerSrc) => { 260 | return await getPlay(playerSrc.src); 261 | }); 262 | }, 263 | searchContent: function (key, quick, pg) { 264 | const result = { 265 | list: [], 266 | page: pg, 267 | pagecount: 0 268 | }; 269 | return listVideos(result); 270 | } 271 | }; 272 | })(); 273 | $(unsafeWindow).on("load", async function () { 274 | if (document.readyState === 'complete') { 275 | const result = await GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 276 | console.log(GMSpiderArgs.fName, JSON.stringify(result)); 277 | if (typeof GmSpiderInject !== 'undefined') { 278 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 279 | } 280 | } 281 | }); 282 | })(); 283 | 284 | -------------------------------------------------------------------------------- /userScripts/hitv.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name hitv 3 | // @namespace gmspider 4 | // @version 2024.11.12 5 | // @description Hi视频 GMSpider 6 | // @author Luomo 7 | // @match https://www.upfuhn.com/* 8 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/Spiders-Lib@main/lib/browser-extension-url-match-1.2.0.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/ajaxHooker-1.4.3.js 10 | // @grant GM_setValue 11 | // @grant GM_getValue 12 | // @grant unsafeWindow 13 | // @run-at document-start 14 | // ==/UserScript== 15 | console.log(JSON.stringify(GM_info)); 16 | (function () { 17 | const GMSpiderArgs = {}; 18 | if (typeof GmSpiderInject !== 'undefined') { 19 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 20 | GMSpiderArgs.fName = args.shift(); 21 | GMSpiderArgs.fArgs = args; 22 | } else { 23 | // GMSpiderArgs.fName = "homeContent"; 24 | // GMSpiderArgs.fArgs = [true]; 25 | GMSpiderArgs.fName = "searchContent"; 26 | GMSpiderArgs.fArgs = ["82", 2, true, {tag: "动作", y: "2024", o: "1", a: "大陆"}]; 27 | } 28 | Object.freeze(GMSpiderArgs); 29 | let hookConfigs = { 30 | "homeContent": [ 31 | { 32 | matcher: matchPattern("https://*/*/meta/*.json").assertValid(), 33 | onResponseHook: function (response) { 34 | let executed = false; 35 | unsafeWindow.useNuxtApp().hook('link:prefetch', () => { 36 | if (!executed) { 37 | Array.from(document.querySelectorAll(".left-wrap .tab-box:nth-child(2) .swiper-slide span")).find(el => el.textContent === "全部").dispatchEvent(new Event("click")); 38 | } 39 | executed = true; 40 | }); 41 | } 42 | }, 43 | { 44 | dataKey: "ys_video_sites", matcher: matchPattern("https://*/v1/ys_video_sites?*").assertValid() 45 | } 46 | ], 47 | "categoryContent": [{ 48 | matcher: matchPattern("https://*/*/meta/*.json").assertValid(), 49 | onResponseHook: function (response) { 50 | const extend = GMSpiderArgs.fArgs[3]; 51 | let tag = extend?.tag ?? "全部" 52 | let executed = false; 53 | unsafeWindow.useNuxtApp().hook('link:prefetch', () => { 54 | if (!executed) { 55 | Array.from(document.querySelectorAll(".left-wrap .tab-box:nth-child(2) .swiper-slide span")) 56 | .find(el => el.textContent === tag).dispatchEvent(new Event("click")); 57 | } 58 | executed = true; 59 | }); 60 | } 61 | }, { 62 | dataKey: "ys_video_sites", 63 | matcher: matchPattern("https://*/v1/ys_video_sites?*").assertValid(), 64 | onRequestHook: function (response) { 65 | const page = GMSpiderArgs.fArgs[1]; 66 | const filter = GMSpiderArgs.fArgs[2]; 67 | const extend = GMSpiderArgs.fArgs[3]; 68 | const url = new URL(response.url); 69 | const params = new URLSearchParams(url.search); 70 | params.set("pn", page) 71 | if (filter) { 72 | params.set("a", extend?.a ?? ""); 73 | params.set("y", extend?.y ?? ""); 74 | params.set("o", extend?.o ?? 0); 75 | } 76 | url.search = params.toString(); 77 | response.url = url.toString(); 78 | } 79 | }], 80 | "detailContent": [{ 81 | dataKey: "meta", 82 | matcher: matchPattern("https://*/*/meta/*.json").assertValid(), 83 | }], 84 | "searchContent": [{ 85 | dataKey: "meta", 86 | matcher: matchPattern("https://*/*/meta/*.json").assertValid(), 87 | }], 88 | }; 89 | const GmSpider = (function () { 90 | const categoryFilterCachePrefix = "category_"; 91 | const filterTag = { 92 | key: "tag", name: "分类", value: [] 93 | }; 94 | const filterArea = { 95 | key: "o", name: "地区", value: [] 96 | }; 97 | const filterYear = { 98 | key: "y", name: "年份", value: [] 99 | }; 100 | const filterSort = { 101 | key: "o", 102 | name: "排序", 103 | value: [{n: "综合", v: "0"}, {n: "最新", v: "2"}, {n: "最热", v: "1"}, {n: "评分", v: "5"},] 104 | }; 105 | return { 106 | homeContent: function (filter) { 107 | //清理cookie 108 | document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); }); 109 | let result = { 110 | class: [{type_id: "85", type_name: "短剧"}, {type_id: "81", type_name: "电影"}, { 111 | type_id: "82", 112 | type_name: "电视剧" 113 | }, {type_id: "83", type_name: "综艺"}, {type_id: "84", type_name: "动漫"},], filters: {}, list: [] 114 | }; 115 | document.querySelectorAll(".left-wrap .tab-box:nth-child(3) .swiper-slide span").forEach((filter) => { 116 | filterArea.value.push({ 117 | n: filter.textContent, v: filter.textContent, 118 | }) 119 | }); 120 | document.querySelectorAll(".left-wrap .tab-box:nth-child(4) .swiper-slide span").forEach((filter) => { 121 | filterYear.value.push({ 122 | n: filter.textContent, v: filter.textContent, 123 | }) 124 | }); 125 | result.class.forEach((category) => { 126 | const categoryFilter = []; 127 | const cacheFilter = localStorage.getItem(categoryFilterCachePrefix + category.type_id); 128 | if (typeof cacheFilter !== "undefined" && cacheFilter !== null) { 129 | categoryFilter.push(JSON.parse(cacheFilter)); 130 | } 131 | categoryFilter.push(filterArea, filterYear, filterSort); 132 | result.filters[category.type_id] = categoryFilter; 133 | }) 134 | hookResult.ys_video_sites.data.data.forEach((media) => { 135 | result.list.push({ 136 | vod_id: media.video_site_id, 137 | vod_name: media.video_name, 138 | vod_pic: media.video_vertical_url, 139 | vod_remarks: "评分:" + media.score, 140 | vod_year: media.years 141 | }) 142 | }); 143 | return result; 144 | }, categoryContent: function (tid, pg, filter, extend) { 145 | let result = { 146 | list: [], pagecount: Math.ceil(hookResult.ys_video_sites.data.total / 21) 147 | }; 148 | document.querySelectorAll(".left-wrap .tab-box:nth-child(2) .swiper-slide span").forEach((filter) => { 149 | filterTag.value.push({ 150 | n: filter.textContent, v: filter.textContent, 151 | }) 152 | }); 153 | localStorage.setItem(categoryFilterCachePrefix + tid, JSON.stringify(filterTag)); 154 | hookResult.ys_video_sites.data.data.forEach((media) => { 155 | result.list.push({ 156 | vod_id: media.video_site_id, 157 | vod_name: media.video_name, 158 | vod_pic: media.video_vertical_url, 159 | vod_remarks: "评分:" + media.score, 160 | vod_year: media.years 161 | }) 162 | }) 163 | return result; 164 | }, detailContent: function (ids) { 165 | let playUrl = []; 166 | let vod = {}; 167 | const nuxtData = JSON.parse(JSON.stringify(unsafeWindow.__NUXT__.data)); 168 | for (const [key, value] of Object.entries(nuxtData)) { 169 | if (typeof (value.data?.ys_video_site) != "undefined") { 170 | value.data.data.forEach((item) => { 171 | playUrl.push({ 172 | name: item.series_num, 173 | type: "finalUrl", 174 | ext: { 175 | header: { 176 | "User-Agent": window.navigator.userAgent, 177 | "Referer": window.location.href 178 | }, 179 | url: item.video_url 180 | } 181 | }) 182 | }) 183 | const ysVideoSite = value.data.ys_video_site; 184 | vod = { 185 | vod_id: ysVideoSite.video_site_id, 186 | vod_name: ysVideoSite.video_name, 187 | vod_content: ysVideoSite.video_desc, 188 | vod_year: ysVideoSite.years, 189 | vod_area: ysVideoSite.area, 190 | vod_actor: ysVideoSite.main_actor, 191 | type_name: ysVideoSite.tag, 192 | vod_play_data: [{ 193 | from: "Hi视频", 194 | media: playUrl 195 | }] 196 | }; 197 | 198 | } 199 | } 200 | return vod; 201 | }, searchContent: function (key, quick, pg) { 202 | const result = { 203 | list: [], 204 | page: pg, 205 | pagecount: 1 206 | }; 207 | const nuxtData = JSON.parse(JSON.stringify(unsafeWindow.__NUXT__.data)); 208 | for (const [key, value] of Object.entries(nuxtData)) { 209 | if (typeof (value.data?.first_video_series) != "undefined") { 210 | if (value.data.first_video_series != null) { 211 | const firstVideo = value.data.first_video_series 212 | result.list.push({ 213 | vod_id: firstVideo.video_site_id, 214 | vod_name: firstVideo.video_name, 215 | vod_pic: firstVideo.video_vertical_url, 216 | vod_remarks: firstVideo.tag, 217 | vod_year: firstVideo.years 218 | }) 219 | } 220 | value.data.video_sites.forEach((video) => { 221 | result.list.push({ 222 | vod_id: video.video_site_id, 223 | vod_name: video.video_name, 224 | vod_pic: video.video_vertical_url, 225 | vod_remarks: video.tag, 226 | vod_year: video.years 227 | }) 228 | }) 229 | } 230 | } 231 | return result; 232 | } 233 | }; 234 | })(); 235 | let spiderExecuted = false; 236 | let dataReadyCount = 0; 237 | let hookResult = {}; 238 | ajaxHooker.hook(request => { 239 | hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => { 240 | if (typeof hookConfig.onRequestHook === "function" && hookConfig.matcher.match(request.url.startsWith("http") ? request.url : unsafeWindow.window.location.origin + request.url)) { 241 | hookConfig.onRequestHook(request); 242 | } 243 | }); 244 | if (!spiderExecuted) { 245 | let dataTodoCount = 0; 246 | hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => { 247 | if (typeof hookConfig.dataKey !== "undefined") { 248 | if (hookConfig?.require !== false) { 249 | dataTodoCount++; 250 | } 251 | } 252 | if (hookConfig.matcher.match(request.url.startsWith("http") ? request.url : unsafeWindow.window.location.origin + request.url)) { 253 | request.response = res => { 254 | if (typeof hookConfig.onResponseHook === "function") { 255 | hookConfig.onResponseHook(res); 256 | } 257 | if (typeof hookConfig.dataKey !== "undefined") { 258 | if (hookConfig?.require !== false) { 259 | dataReadyCount++; 260 | } 261 | let data = JSON.parse(res.text); 262 | if (typeof data === 'object' && data) { 263 | hookResult[hookConfig.dataKey] = data; 264 | } else { 265 | hookResult[hookConfig.dataKey] = res.text; 266 | } 267 | if (dataTodoCount === dataReadyCount) { 268 | spiderExecuted = true; 269 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 270 | console.log(result); 271 | if (typeof GmSpiderInject !== 'undefined' && spiderExecuted) { 272 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 273 | } 274 | } 275 | } 276 | }; 277 | } 278 | 279 | }); 280 | } 281 | }); 282 | })(); -------------------------------------------------------------------------------- /userScripts/huochetaidu.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: true, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 6] 30 | } 31 | } 32 | }); 33 | $(document).ready(function () { 34 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 35 | console.log(result); 36 | if (typeof GmSpiderInject !== 'undefined') { 37 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 38 | } 39 | }); 40 | })(); 41 | 42 | -------------------------------------------------------------------------------- /userScripts/juyeye.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 5] 30 | } 31 | }, 32 | playerContent: { 33 | OkPlayer: true 34 | } 35 | }); 36 | $(document).ready(function () { 37 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 38 | console.log(result); 39 | if (typeof GmSpiderInject !== 'undefined') { 40 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 41 | } 42 | }); 43 | })(); 44 | 45 | -------------------------------------------------------------------------------- /userScripts/kkys.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "detailContent"; 21 | GMSpiderArgs.fArgs = [1]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | pageCountStyle: ".page-item-next", 27 | homeContent: { 28 | category: { 29 | select: ".menu-item", 30 | slice: [1, 6] 31 | } 32 | }, 33 | detailContent: { 34 | customFunction: function (ids) { 35 | let items = {}; 36 | $(".detail-box-main .detail-info-row").each(function () { 37 | items[$(this).find(".detail-info-row-side").text().trim().replace(":", "")] = $(this).find(".detail-info-row-main").text().trim(); 38 | }); 39 | let vodPlayData = []; 40 | $(".episode-box-header .source-item").each(function (i) { 41 | if ($(this).find(".source-item-label").text().trim() === "4K(高峰不卡)") { 42 | return true; 43 | } 44 | let media = []; 45 | $(`.episode-list:eq(${i}) .episode-item`).each(function () { 46 | media.push({ 47 | name: $(this).text().trim(), 48 | type: "webview", 49 | ext: { 50 | replace: { 51 | playUrl: $(this).attr("href"), 52 | } 53 | } 54 | }); 55 | }) 56 | vodPlayData.push({ 57 | from: $(this).find(".source-item-label").text().trim(), 58 | media: media 59 | }) 60 | }) 61 | 62 | return vod = { 63 | vod_id: ids[0], 64 | vod_name: $(".module-info-heading h1").text().trim(), 65 | vod_pic: MacCmsGMSpiderTool.formatImgUrl($(".detail-box .detail-pic img").data("original") || $(".detail-box .detail-pic img").attr("src"), false, unsafeWindow?.RDUL[0]), 66 | vod_director: items?.["导演"] || "", 67 | vod_actor: items?.["演员"] || "", 68 | vod_year: items?.["首映"] || "", 69 | type_name: $(".detail-tags-item").map(function () { 70 | return $(this).text().trim(); 71 | }).get().join(" "), 72 | vod_content: $(".detail-box-main .detail-desc").text().trim(), 73 | vod_play_data: vodPlayData 74 | }; 75 | } 76 | }, 77 | getVodList: function () { 78 | let vodList = []; 79 | $("a.v-item").each(function () { 80 | let vodPic; 81 | vodList.push({ 82 | vod_id: $(this).attr("href"), 83 | vod_name: $(this).find(".v-item-title").text().trim(), 84 | vod_pic: MacCmsGMSpiderTool.formatImgUrl($(this).find(".v-item-cover img").data("original") || $(this).find(".v-item-cover img").attr("src"), false, unsafeWindow?.RDUL[0]), 85 | vod_remarks: $(this).find(".v-item-top-left").text().trim(), 86 | vod_year: $(this).find(".v-item-bottom").text().trim() 87 | }) 88 | }); 89 | return vodList; 90 | }, 91 | getCategoryFilter: function () { 92 | const filters = []; 93 | $(".filter-row").each(function () { 94 | const filter = { 95 | key: "", 96 | name: $(this).find(".filter-row-side").text().trim(), 97 | value: [] 98 | } 99 | $(this).find("a.filter-item").each(function () { 100 | const params = $(this).attr("href").split(/[/.]/).at(2).split("-").slice(1); 101 | filter.key = "index" + params.findIndex((element) => element.length > 0) 102 | filter.value.push({ 103 | n: $(this).text().trim(), 104 | v: params.find((element) => element.length > 0) || "" 105 | }) 106 | }) 107 | filters.push(filter); 108 | }) 109 | return filters; 110 | } 111 | }); 112 | $(document).ready(function () { 113 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 114 | console.log(result); 115 | if (typeof GmSpiderInject !== 'undefined') { 116 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 117 | } 118 | }); 119 | })(); 120 | 121 | -------------------------------------------------------------------------------- /userScripts/mqtv.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name mqtv 3 | // @namespace gmspider 4 | // @version 2024.11.12 5 | // @description 麻雀视频 GMSpider 6 | // @author Luomo 7 | // @match https://www.mqtv.cc/* 8 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/Spiders-Lib@main/lib/browser-extension-url-match-1.2.0.min.js 9 | // @require https://cdn.jsdelivr.net/npm/ajax-hook@3.0.3/dist/ajaxhook.umd.min.js 10 | // @grant unsafeWindow 11 | // @run-at document-start 12 | // ==/UserScript== 13 | console.log(JSON.stringify(GM_info)); 14 | (function () { 15 | const GMSpiderArgs = {}; 16 | if (typeof GmSpiderInject !== 'undefined') { 17 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 18 | GMSpiderArgs.fName = args.shift(); 19 | GMSpiderArgs.fArgs = args; 20 | } else { 21 | GMSpiderArgs.fName = "searchContent"; 22 | GMSpiderArgs.fArgs = [true]; 23 | } 24 | Object.freeze(GMSpiderArgs); 25 | let hookConfigs = { 26 | "homeContent": [{ 27 | dataKey: "VodList", 28 | matcher: matchPattern("https://*/libs/VodList.api.php?*").assertValid() 29 | }], 30 | "categoryContent": [{ 31 | dataKey: "VodList", 32 | matcher: matchPattern("https://*/libs/VodList.api.php?*").assertValid(), 33 | onRequestHook: function (config, handler) { 34 | let url = new URL(config.url, window.location.origin); 35 | url.searchParams.set('page', GMSpiderArgs.fArgs[1]); 36 | config.url = url.pathname + url.search; 37 | } 38 | }], 39 | "detailContent": [{ 40 | dataKey: "VodInfo", 41 | matcher: matchPattern("https://*/libs/VodInfo.api.php?*").assertValid() 42 | }], 43 | "playerContent": [{ 44 | dataKey: "VodInfo", 45 | matcher: matchPattern("https://*/libs/VodInfo.api.php?*").assertValid(), 46 | onResponseHook: function (response, handler) { 47 | console.log("playerContent", response); 48 | let anchor = window.location.hash.split("#").at(1); 49 | let vodInfo = JSON.parse(response.response)?.data; 50 | vodInfo.playinfo.forEach((playinfo) => { 51 | playinfo.player.forEach((player, index) => { 52 | if (player.url === anchor) { 53 | localStorage.setItem("history", JSON.stringify({ 54 | val: [{ 55 | "id": vodInfo.id, 56 | "type": vodInfo.type, 57 | "title": vodInfo.title, 58 | "img": vodInfo.img, 59 | "url": player.url, 60 | "episode": player.no, 61 | "ensite": playinfo.ensite, 62 | "cnsite": playinfo.cnsite, 63 | "num": index 64 | }], 65 | exp: new Date().getTime() + 60 * 1000, 66 | })); 67 | } 68 | }) 69 | }); 70 | console.log("history", localStorage.getItem("history")); 71 | } 72 | }], 73 | "searchContent": [{ 74 | dataKey: "VodList", 75 | matcher: matchPattern("https://*/libs/VodList.api.php?*").assertValid() 76 | }], 77 | }; 78 | const GmSpider = (function () { 79 | const categoryFilterCachePrefix = "category."; 80 | 81 | function formatVodList(vodList) { 82 | let vods = []; 83 | vodList.forEach(function (vod) { 84 | vods.push({ 85 | vod_id: vod.url, 86 | vod_name: vod.title, 87 | vod_pic: vod.img, 88 | vod_remarks: vod.remark 89 | }) 90 | }) 91 | return vods; 92 | } 93 | 94 | return { 95 | homeContent: function (filter) { 96 | let result = { 97 | class: [ 98 | {type_id: "movie", type_name: "电影"}, 99 | {type_id: "tv", type_name: "电视剧"}, 100 | {type_id: "va", type_name: "综艺"}, 101 | {type_id: "ct", type_name: "动漫"} 102 | ], 103 | filters: {}, 104 | list: [] 105 | }; 106 | result.list.push(...formatVodList(hookResult.VodList?.data?.ct?.[0]?.show), ...formatVodList(hookResult.VodList?.data?.movie?.[0]?.show), ...formatVodList(hookResult.VodList?.data?.tv?.[0]?.show)); 107 | return result; 108 | }, 109 | categoryContent: function (tid, pg, filter, extend) { 110 | let result = { 111 | list: [], 112 | pagecount: pg 113 | }; 114 | result.list = formatVodList(hookResult.VodList?.data) 115 | if (result.list.length >= 25) { 116 | result.pagecount = pg + 1; 117 | } 118 | return result; 119 | }, 120 | detailContent: function (ids) { 121 | const vodInfo = hookResult.VodInfo.data; 122 | let vodPlayData = []; 123 | hookResult.VodInfo.data.playinfo.forEach((item) => { 124 | let media = []; 125 | item.player.forEach((player) => { 126 | media.push({ 127 | name: player.no, 128 | type: "webview", 129 | ext: { 130 | replace: { 131 | url: ids[0], 132 | anchor: player.url 133 | } 134 | } 135 | }); 136 | }) 137 | vodPlayData.push({ 138 | from: item.cnsite, 139 | media: media 140 | }) 141 | }); 142 | return { 143 | vod_id: vodInfo.id, 144 | vod_name: vodInfo.title, 145 | vod_pic: vodInfo.img, 146 | vod_actor: vodInfo.actor, 147 | vod_director: vodInfo.director, 148 | vod_area: vodInfo.area, 149 | vod_year: vodInfo.year, 150 | vod_remarks: vodInfo.remark, 151 | vod_play_data: vodPlayData 152 | }; 153 | }, 154 | playerContent: function (flag, id, vipFlags) { 155 | return { 156 | type: "match" 157 | }; 158 | }, 159 | searchContent: function (key, quick, pg) { 160 | let result = { 161 | list: [], 162 | pagecount: 1 163 | }; 164 | let _gotData = function (src) { 165 | console.log("_gotSrc hook failed"); 166 | }; 167 | const targetNode = $("#leo-load-list-1")[0]; 168 | const config = {childList: true, subtree: true}; 169 | const observer = new MutationObserver((mutationsList) => { 170 | mutationsList.forEach((mutation) => { 171 | _gotData(); 172 | }); 173 | }); 174 | observer.observe(targetNode, {childList: true, subtree: true}); 175 | return new Promise(function (resolve) { 176 | _gotData = resolve; 177 | }).then(function () { 178 | let $ = unsafeWindow.$; 179 | $(".leo-list-item-s").each(function () { 180 | result.list.push({ 181 | vod_id: $(this).find(".leo-list-item-title a").attr("href"), 182 | vod_name:$(this).find(".leo-list-item-title a").attr("title"), 183 | vod_pic: $(this).find(".leo-list-item-pic img").data("original") 184 | }); 185 | }) 186 | return result; 187 | }); 188 | } 189 | }; 190 | })(); 191 | let spiderExecuted = false; 192 | let dataReadyCount = 0; 193 | let hookResult = {}; 194 | const {unProxy, originXhr} = proxy({ 195 | onRequest: (config, handler) => { 196 | let requestUrl = config.url; 197 | if (!requestUrl.startsWith("http")) { 198 | requestUrl = window.location.origin + requestUrl; 199 | } 200 | hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => { 201 | if (typeof hookConfig.onRequestHook === "function" && hookConfig.matcher.match(requestUrl)) { 202 | hookConfig.onRequestHook(config, handler); 203 | } 204 | }); 205 | handler.next(config); 206 | }, 207 | onResponse: (response, handler) => { 208 | if (!spiderExecuted) { 209 | let dataTodoCount = 0; 210 | let requestUrl = response.config.url; 211 | if (!requestUrl.startsWith("http")) { 212 | requestUrl = window.location.origin + requestUrl; 213 | } 214 | hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => { 215 | if (typeof hookConfig.dataKey !== "undefined") { 216 | if (hookConfig?.require !== false) { 217 | dataTodoCount++; 218 | } 219 | if (hookConfig.matcher.match(requestUrl)) { 220 | if (hookConfig?.require !== false) { 221 | dataReadyCount++; 222 | } 223 | try { 224 | let data = JSON.parse(response.response); 225 | if (typeof data === 'object' && data) { 226 | hookResult[hookConfig.dataKey] = data; 227 | } else { 228 | hookResult[hookConfig.dataKey] = response.response; 229 | } 230 | } catch (e) { 231 | } 232 | } 233 | } 234 | if (typeof hookConfig.onResponseHook === "function" && hookConfig.matcher.match(requestUrl)) { 235 | hookConfig.onResponseHook(response, handler); 236 | } 237 | }); 238 | if (dataTodoCount === dataReadyCount) { 239 | spiderExecuted = true; 240 | 241 | async function asyncRun() { 242 | const result = await GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 243 | console.log(result); 244 | if (typeof GmSpiderInject !== 'undefined' && spiderExecuted) { 245 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 246 | } 247 | } 248 | 249 | asyncRun(); 250 | } 251 | } 252 | handler.next(response); 253 | } 254 | }, unsafeWindow) 255 | })(); -------------------------------------------------------------------------------- /userScripts/pipiys.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 7] 30 | } 31 | } 32 | }); 33 | $(document).ready(function () { 34 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 35 | console.log(result); 36 | if (typeof GmSpiderInject !== 'undefined') { 37 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 38 | } 39 | }); 40 | })(); 41 | 42 | -------------------------------------------------------------------------------- /userScripts/ppdys.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 6] 30 | } 31 | } 32 | }); 33 | $(document).ready(function () { 34 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 35 | console.log(result); 36 | if (typeof GmSpiderInject !== 'undefined') { 37 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 38 | } 39 | }); 40 | })(); 41 | 42 | -------------------------------------------------------------------------------- /userScripts/ppxys.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "detailContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 4] 30 | } 31 | }, 32 | detailContent: { 33 | customFunction: function (ids) { 34 | let vodPlayData = []; 35 | $(".player-list").each(function (i) { 36 | let media = []; 37 | $(this).find(".module-play-list .module-play-list-link").each(function () { 38 | media.push({ 39 | name: $(this).text().trim(), 40 | type: "webview", 41 | ext: { 42 | replace: { 43 | playUrl: $(this).attr("href"), 44 | } 45 | } 46 | }); 47 | }) 48 | vodPlayData.push({ 49 | from: $(this).find(".module-tab-item").children().remove().end().text().trim(), 50 | media: media 51 | }) 52 | }) 53 | 54 | return vod = { 55 | vod_id: ids[0], 56 | vod_name: $(".module-player-side .module-info-heading h1").text().trim(), 57 | type_name: $(".module-player-side .module-info-tag-link a").map(function () { 58 | return $(this).attr("title"); 59 | }).get().join(" "), 60 | vod_play_data: vodPlayData 61 | }; 62 | } 63 | }, 64 | getCategoryFilter: function () { 65 | const filters = []; 66 | $(".module-class-item").each(function (i) { 67 | const filter = { 68 | key: "", 69 | name: $(this).find(".module-item-title").text().trim(), 70 | value: [] 71 | } 72 | $(this).find(".module-item-box a").each(function () { 73 | const params = $(this).attr("href").split(/[/.]/); 74 | if (params.length > 4) { 75 | filter.key = "index" + i; 76 | filter.value.push({ 77 | n: $(this).text().trim(), 78 | v: `/${params[3]}/${params[4]}` 79 | }) 80 | } 81 | }) 82 | filters.push(filter); 83 | }) 84 | return filters; 85 | } 86 | }); 87 | $(document).ready(function () { 88 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 89 | if (typeof GmSpiderInject !== 'undefined') { 90 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 91 | } 92 | }); 93 | })(); 94 | 95 | -------------------------------------------------------------------------------- /userScripts/yirenmeng.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = [true]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | homeContent: { 27 | category: { 28 | select: ".navbar-item", 29 | slice: [1, 8] 30 | } 31 | } 32 | }); 33 | $(document).ready(function () { 34 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 35 | console.log(result); 36 | if (typeof GmSpiderInject !== 'undefined') { 37 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 38 | } 39 | }); 40 | })(); 41 | 42 | -------------------------------------------------------------------------------- /userScripts/ysfp.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name yfsp 3 | // @namespace gmspider 4 | // @version 2024.11.12 5 | // @description 爱壹帆 GMSpider 6 | // @author Luomo 7 | // @match https://m.yfsp.tv/* 8 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/Spiders-Lib@main/lib/browser-extension-url-match-1.2.0.min.js 9 | // @require https://cdn.jsdelivr.net/npm/ajax-hook@3.0.3/dist/ajaxhook.umd.min.js 10 | // @grant GM_setValue 11 | // @grant GM_getValue 12 | // @grant unsafeWindow 13 | // @run-at document-start 14 | // ==/UserScript== 15 | console.log(JSON.stringify(GM_info)); 16 | (function () { 17 | const GMSpiderArgs = {}; 18 | if (typeof GmSpiderInject !== 'undefined') { 19 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 20 | GMSpiderArgs.fName = args.shift(); 21 | GMSpiderArgs.fArgs = args; 22 | } else { 23 | // GMSpiderArgs.fName = "homeContent"; 24 | // GMSpiderArgs.fArgs = [true]; 25 | // GMSpiderArgs.fName = "categoryContent"; 26 | // GMSpiderArgs.fArgs = ["movie", 2, true, {}]; 27 | // GMSpiderArgs.fName = "detailContent"; 28 | // GMSpiderArgs.fArgs = [["XOkJ0XqSwI2"]]; 29 | GMSpiderArgs.fName = "searchContent"; 30 | GMSpiderArgs.fArgs = ["小巷人家", false, 1]; 31 | } 32 | Object.freeze(GMSpiderArgs); 33 | (function () { 34 | switch (GMSpiderArgs.fName) { 35 | case "searchContent": 36 | localStorage.setItem("historyList", JSON.stringify([GMSpiderArgs.fArgs [0]])); 37 | break; 38 | } 39 | })(); 40 | let hookConfigs = { 41 | "homeContent": [{ 42 | dataKey: "navigationbar", 43 | matcher: matchPattern("https://*.yfsp.tv/api/list/navigationbar?*").assertValid() 44 | }, { 45 | dataKey: "index", 46 | matcher: matchPattern("https://*.yfsp.tv/api/list/index?*").assertValid() 47 | }], 48 | "categoryContent": [{ 49 | dataKey: "filtertagsdata", 50 | matcher: matchPattern("https://*.yfsp.tv/api/list/getfiltertagsdata?*").assertValid() 51 | }, { 52 | dataKey: "conditionfilterdata", 53 | matcher: matchPattern("https://*.yfsp.tv/api/list/getconditionfilterdata?*").assertValid(), 54 | onRequestHook: function (config, handler) { 55 | let url = new URL(config.url); 56 | url.searchParams.set('page', GMSpiderArgs.fArgs[1]); 57 | config.url = url.toString(); 58 | } 59 | }], 60 | "detailContent": [{ 61 | dataKey: "videodetails", 62 | matcher: matchPattern("https://*.yfsp.tv/api/video/videodetails?*").assertValid() 63 | }, { 64 | dataKey: "playdata", 65 | matcher: matchPattern("https://*.yfsp.tv/api/video/getplaydata?*").assertValid() 66 | }, { 67 | dataKey: "videochoosegather", 68 | require: false, 69 | matcher: matchPattern("https://*.yfsp.tv/api/video/videochoosegather?*").assertValid() 70 | }], 71 | "playerContent": [{ 72 | dataKey: "playdata", 73 | matcher: matchPattern("https://*.yfsp.tv/api/video/getplaydata?*").assertValid() 74 | }], 75 | "searchContent": [{ 76 | dataKey: "titlegetdata", 77 | matcher: matchPattern("https://*.yfsp.tv/api/list/gettitlegetdata?*").assertValid() 78 | }, { 79 | matcher: matchPattern("https://*.yfsp.tv/api/home/gethotsearch?*").assertValid(), 80 | onResponseHook: function (response, handler) { 81 | document.querySelector(".search-log span").dispatchEvent(new Event("click")); 82 | } 83 | }], 84 | }; 85 | const GmSpider = (function () { 86 | const categoryFilterCachePrefix = "category."; 87 | return { 88 | homeContent: function (filter) { 89 | let result = { 90 | class: [], 91 | filters: {}, 92 | list: [] 93 | }; 94 | let categoryIds = []; 95 | hookResult.navigationbar.data.list.forEach((item) => { 96 | if (item.type === 1) { 97 | result.class.push({ 98 | type_id: item.routeName, 99 | type_name: item.name 100 | }); 101 | categoryIds.push(item.categoryId); 102 | // const cacheFilter = GM_getValue(item.routeName); 103 | // console.log("cacheFilter", item.routeName, cacheFilter); 104 | const cacheFilter = localStorage.getItem(categoryFilterCachePrefix + item.routeName); 105 | console.log("localStorage", item.routeName, localStorage.getItem(item.routeName)); 106 | if (typeof cacheFilter !== "undefined" && cacheFilter !== null) { 107 | result.filters[item.routeName] = JSON.parse(cacheFilter); 108 | } 109 | } 110 | 111 | }) 112 | hookResult.index.data.list.forEach((item) => { 113 | if (categoryIds.includes(item.type)) { 114 | item.list.forEach((media) => { 115 | if (!media.isRecommend) { 116 | result.list.push({ 117 | vod_id: media.mediaKey, 118 | vod_name: media.title, 119 | vod_pic: media.coverImgUrl, 120 | vod_remarks: media.updateStatus, 121 | vod_year: media.mediaType 122 | }) 123 | } 124 | }) 125 | } 126 | }) 127 | return result; 128 | }, 129 | categoryContent: function (tid, pg, filter, extend) { 130 | let result = { 131 | list: [], 132 | pagecount: 1000 133 | }; 134 | let cacheFilters = []; 135 | hookResult.filtertagsdata.data.list.forEach(classify => { 136 | let cacheFilter = { 137 | key: "index-" + classify.list[0].index, 138 | name: classify.name, 139 | value: [] 140 | } 141 | classify.list.forEach((item) => { 142 | cacheFilter.value.push({ 143 | n: item.classifyName, 144 | v: (item.index > 0 ? "," : "") + item.classifyId 145 | }); 146 | }) 147 | cacheFilters.push(cacheFilter); 148 | }) 149 | // GM_setValue(tid, JSON.stringify(cacheFilters)); 150 | localStorage.setItem(categoryFilterCachePrefix + tid, JSON.stringify(cacheFilters)); 151 | console.log("cacheFilter", tid, cacheFilters); 152 | hookResult.conditionfilterdata.data.list.forEach((media) => { 153 | result.list.push({ 154 | vod_id: media.mediaKey, 155 | vod_name: media.title, 156 | vod_pic: media.coverImgUrl, 157 | vod_remarks: media.updateStatus, 158 | vod_year: media.regional 159 | }) 160 | }) 161 | return result; 162 | }, 163 | detailContent: function (ids) { 164 | const videodetails = hookResult.videodetails.data.detailInfo; 165 | let mediaUrl = ""; 166 | let episodeKey = ""; 167 | hookResult.playdata.data.list.forEach((item) => { 168 | if (mediaUrl === "" && item.mediaUrl !== "") { 169 | mediaUrl = item.mediaUrl; 170 | episodeKey = item.episodeKey; 171 | } 172 | }) 173 | let media = []; 174 | if (videodetails.videoType !== 0) { 175 | if (typeof hookResult.videochoosegather !== "undefined") { 176 | hookResult.videochoosegather.data.list.forEach((item) => { 177 | if (videodetails.episodeTitle === item.episodeTitle) { 178 | media.push({ 179 | name: item.episodeTitle, 180 | type: "finalUrl", 181 | ext: { 182 | "header": { 183 | "User-Agent": window.navigator.userAgent, 184 | "Referer": window.location.href 185 | }, 186 | "url": mediaUrl 187 | } 188 | }); 189 | } else { 190 | media.push({ 191 | name: item.episodeTitle, 192 | type: "webview", 193 | ext: { 194 | replace: { 195 | mediaKey: item.mediaKey, 196 | episodeKey: item.episodeKey 197 | } 198 | } 199 | }) 200 | } 201 | }) 202 | } else { 203 | spiderExecuted = false; 204 | return; 205 | } 206 | } else { 207 | media.push({ 208 | name: videodetails.episodeTitle, 209 | type: "finalUrl", 210 | ext: { 211 | "header": { 212 | "User-Agent": window.navigator.userAgent, 213 | "Referer": window.location.href 214 | }, 215 | "url": mediaUrl 216 | } 217 | }) 218 | } 219 | return { 220 | vod_id: videodetails.mediaKey, 221 | vod_name: videodetails.title, 222 | vod_pic: videodetails.coverImgUrl, 223 | vod_actor: videodetails.actor, 224 | vod_director: videodetails.director, 225 | vod_tag: videodetails.cidMapper, 226 | vod_area: videodetails.regional, 227 | vod_content: videodetails.introduce, 228 | vod_play_data: [{ 229 | from: "爱壹帆", 230 | media: media 231 | }] 232 | }; 233 | }, 234 | playerContent: function (flag, id, vipFlags) { 235 | let mediaUrl = ""; 236 | hookResult.playdata.data.list.forEach((item) => { 237 | if (mediaUrl === "" && item.mediaUrl !== "") { 238 | mediaUrl = item.mediaUrl; 239 | } 240 | }) 241 | return { 242 | type: "finalUrl", 243 | ext: { 244 | "header": { 245 | "User-Agent": window.navigator.userAgent, 246 | "Referer": window.location.href 247 | }, 248 | "url": mediaUrl 249 | } 250 | }; 251 | }, 252 | searchContent: function (key, quick, pg) { 253 | console.log(hookResult); 254 | let result = { 255 | list: [], 256 | pagecount: 1 257 | }; 258 | if (pg == 1) { 259 | hookResult.titlegetdata.data.list.forEach((media) => { 260 | result.list.push({ 261 | vod_id: media.mediaKey, 262 | vod_name: media.title, 263 | vod_pic: media.coverImgUrl, 264 | vod_remarks: media.updateStatus, 265 | vod_year: media.regional 266 | }) 267 | }) 268 | } 269 | return result; 270 | } 271 | }; 272 | })(); 273 | let spiderExecuted = false; 274 | let dataReadyCount = 0; 275 | let hookResult = {}; 276 | const {unProxy, originXhr} = proxy({ 277 | onRequest: (config, handler) => { 278 | hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => { 279 | if (typeof hookConfig.onRequestHook === "function" && hookConfig.matcher.match(config.url)) { 280 | hookConfig.onRequestHook(config, handler); 281 | } 282 | }); 283 | handler.next(config); 284 | }, 285 | onResponse: (response, handler) => { 286 | if (!spiderExecuted) { 287 | let dataTodoCount = 0; 288 | hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => { 289 | if (typeof hookConfig.dataKey !== "undefined") { 290 | if (hookConfig?.require !== false) { 291 | dataTodoCount++; 292 | } 293 | if (hookConfig.matcher.match(response.config.url)) { 294 | if (hookConfig?.require !== false) { 295 | dataReadyCount++; 296 | } 297 | try { 298 | let data = JSON.parse(response.response); 299 | if (typeof data === 'object' && data) { 300 | hookResult[hookConfig.dataKey] = data; 301 | } else { 302 | hookResult[hookConfig.dataKey] = response.response; 303 | } 304 | } catch (e) { 305 | } 306 | } 307 | } 308 | if (typeof hookConfig.onResponseHook === "function" && hookConfig.matcher.match(response.config.url)) { 309 | hookConfig.onResponseHook(response, handler); 310 | } 311 | }); 312 | if (dataTodoCount === dataReadyCount) { 313 | spiderExecuted = true; 314 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 315 | console.log(result); 316 | if (typeof GmSpiderInject !== 'undefined' && spiderExecuted) { 317 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 318 | } 319 | } 320 | } 321 | handler.next(response); 322 | } 323 | }, unsafeWindow) 324 | })(); -------------------------------------------------------------------------------- /userScripts/zxzjhd.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name maccms-mxonepro 3 | // @namespace gmspider 4 | // @version 2025.1.11 5 | // @description maccms GMSpider 6 | // @author Luomo 7 | // @match *://*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/SFW-Spiders@main/Spiders-Lib/maccms-1.0.2.js 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "detailContent"; 21 | GMSpiderArgs.fArgs = [1, 109]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = MacCmsGMSpider({ 25 | configPicUserAgent: false, 26 | pageCountStyle: ".stui-page__item li.hidden-xs:last:not(.active)", 27 | homeContent: { 28 | category: { 29 | select: ".stui-header__menu li", 30 | slice: [1, 7] 31 | } 32 | }, 33 | detailContent: { 34 | customFunction: function (ids) { 35 | let items = {}; 36 | $(".stui-content__detail .data").each(function () { 37 | const item = $(this).text().trim().split(":"); 38 | items[item[0]] = item[1]; 39 | }); 40 | let vodPlayData = []; 41 | $(".stui-content__playlist:first").each(function (i) { 42 | let media = []; 43 | $(".stui-content__playlist:first a").each(function () { 44 | media.push({ 45 | name: $(this).text().trim(), 46 | type: "webview", 47 | ext: { 48 | replace: { 49 | playUrl: $(this).attr("href"), 50 | } 51 | } 52 | }); 53 | }) 54 | vodPlayData.push({ 55 | from: "在线之家", 56 | media: media 57 | }) 58 | }) 59 | 60 | return vod = { 61 | vod_id: ids[0], 62 | vod_name: $(".stui-content__detail .title").text().trim(), 63 | vod_pic: $(".stui-content__thumb img").data("original"), 64 | vod_remarks: items?.["更新"] || "", 65 | vod_director: items?.["导演"] || "", 66 | vod_actor: items?.["主演"] || "", 67 | vod_content: $(".stui-content__thumb .detail-content").text().trim(), 68 | vod_play_data: vodPlayData 69 | }; 70 | } 71 | }, 72 | getVodList: function () { 73 | let vodList = []; 74 | $("a.stui-vodlist__thumb").each(function () { 75 | vodList.push({ 76 | vod_id: $(this).attr("href"), 77 | vod_name: $(this).attr("title"), 78 | vod_pic: $(this).data("original"), 79 | vod_remarks: $(this).find(".pic-text").text().trim() 80 | }) 81 | }); 82 | return vodList; 83 | }, 84 | getCategoryFilter: function () { 85 | const filters = []; 86 | $("#screenbox .clearfix:gt(0)").each(function () { 87 | const filter = { 88 | key: "", 89 | name: $(this).find("li:first").text().trim(), 90 | value: [] 91 | } 92 | $(this).find("a").each(function () { 93 | const params = $(this).attr("href").split(/[/.]/).at(2).split("-").slice(1); 94 | filter.key = "index" + params.findIndex((element) => element.length > 0) 95 | filter.value.push({ 96 | n: $(this).text().trim(), 97 | v: params.find((element) => element.length > 0) || "" 98 | }) 99 | }) 100 | filters.push(filter); 101 | }) 102 | return filters; 103 | } 104 | }); 105 | $(document).ready(function () { 106 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 107 | console.log(JSON.stringify(result)); 108 | if (typeof GmSpiderInject !== 'undefined') { 109 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 110 | } 111 | }); 112 | })(); 113 | 114 | --------------------------------------------------------------------------------