// ==UserScript== // @name M3u8 // @description 在线播放器 和 野鸡网站 通用过滤 采集资源 插播广告 // @version 20240628 // @author 江小白 // @match *://nnyy.in/*/*.html // @include /(?:lay|ideo).*?\.html/ // @include /^https?:\/\/(?:movie\.douban\.com\/subject|m\.douban\.com\/movie)\// // @include /^https?:\/\/.+?(?typeof arg === 'string' ? arg : arg instanceof Request ? arg.url : String(arg); const matchM3u = url=>itemsHandle.find(item=>item.reUrl.test(url) && !mp4wz.test(url) && !flvwz.test(url) && !tswz.test(url) && !playsharewz.test(url) && !ggbmd.test(url)); const deleteAbnormalTs = (text,jxbgza,jxbgzb,jxbgzc,jxbgzd)=>{ try { if (!/^\s*#EXTM3U/i.test(text)) { return text; } else { if (ggljbmd.test(text)) { return text; } else { if (ggljdmb.test(text)) { if (!jxbgzd) { jxbgzd = /^\s*?(?:[a-z]+?\s*?-\s*?)?\d+?\s*?$/i; } else if (jxbgzd == '空') { jxbgzd = /^\s*?空\s*?$/; } try { const rgtya = '#EXTINF:\\d+?(?:\\.\\d+?)?,' + hhzz + '+?' , rgtyb = jxbgza + '\\.(?:' + ggzlhx + ')' + hhzz + '+' , regex = '(?<=' + rgtya + ')(' + jxbgzb + ')(?=' + rgtyb + ')' , regexx = new RegExp(regex,'gi') , matches = text.match(regexx) , paths = {}; for (let i = 0; i < matches.length; i++) { const path = matches[i]; if (!paths[path]) { paths[path] = []; } paths[path].push(path); } let maxCount = 0 , maxPath = ''; for (const path in paths) { if (paths[path].length > maxCount) { maxCount = paths[path].length; maxPath = path; } } for (const path in paths) { if (path !== maxPath) { paths[path].forEach(p=>{ if (!jxbgzd.test(p)) { text = text.replace(new RegExp(rgtya + p + rgtyb,'gi'), (match)=>{ if (!dypd.test(打印)) { try { console.log("%c[江小白-广告资源-已经发现] ✂\n%c对比" + jxbgzc + "的广告正则:\n%c" + regexx + "\n%c已经删除的广告内容:\n%c" + match.replace(new RegExp('(?<=' + hhzz + '+)' + bhhzz + '+?\\.(?:' + ggzlhx + ')','g'), tsLink=>{ if (!tsLink.startsWith('http')) { if (m3u8gglj) { return new URL(tsLink,m3u8gglj).href; } else { return tsLink; } } else { return tsLink; } } ), "border-left:5px solid #A0B;color:#A0B;padding:3px", "color:blue;", "color:red;", "color:blue;", "color:black;"); } catch (e) { try { console.log("%c[江小白-广告资源-已经发现] ✂\n%c对比" + jxbgzc + "的广告正则:\n%c" + regexx + "\n%c已经删除的广告内容:\n%c" + match, "border-left:5px solid #A0B;color:#A0B;padding:3px", "color:blue;", "color:red;", "color:blue;", "color:black;"); } catch (e) {} } } try { if (!ggtspd) { ggtspd = true; } } catch (e) {} return ''; } ); } } ); } } } catch (e) {} return text; } else { return text; } } } } catch (e) { return text; } } ; const pruner = (text,item)=>{ try { if (!/^\s*#EXTM3U/i.test(text)) { return text; } else { if (ggljbmd.test(text)) { return text; } else { if (ggljdmb.test(text)) { try { if (!gggzpd) { gggzpd = true; if (!/^\s*[0关]?\s*?$/.test(打印)) { console.table(itemsHandle); } } } catch (e) {} let modifiedText; try { modifiedText = deleteAbnormalTs(text, '[^\\.]+?', '(?:' + bhhzz + '+\\\/|\\b)', '路径'); try { modifiedText = deleteAbnormalTs(modifiedText, '\\d+?', '\\w+?(?:[^\\d]\\d{2})?', '名称'); } catch (e) {} try { modifiedText = deleteAbnormalTs(modifiedText, '\\d+?', '\\w+(?=\\d{4})', '名称', '空'); } catch (e) {} try { modifiedText = deleteAbnormalTs(modifiedText, '\\d+?', '[^0]\\d+[^0]0{2,}\\d0', '名称', /(?<=[^0]0{3,})\d+$/); } catch (e) {} } catch (e) { modifiedText = text; } for (const reAd of item.reAds) { const matches = modifiedText.match(reAd); if (matches) { matches.forEach(match=>{ if (!dypd.test(打印)) { try { console.log("%c[江小白-资源广告-已经发现] ✂\n%c已经生效的广告正则:\n%c" + reAd + "\n%c已经删除的广告内容:\n%c" + match.replace(new RegExp('(?<=' + hhzz + '+)' + bhhzz + '+?\\.(?:' + ggzlhx + ')','g'), tsLink=>{ if (!tsLink.startsWith('http')) { if (m3u8gglj) { return new URL(tsLink,m3u8gglj).href; } else { return tsLink; } } else { return tsLink; } } ), "border-left:5px solid #A0B;color:#A0B;padding:3px", "color:blue;", "color:red;", "color:blue;", "color:black;"); } catch (e) { try { console.log("%c[江小白-资源广告-已经发现] ✂\n%c已经生效的广告正则:\n%c" + reAd + "\n%c已经删除的广告内容:\n%c" + match, "border-left:5px solid #A0B;color:#A0B;padding:3px", "color:blue;", "color:red;", "color:blue;", "color:black;"); } catch (e) {} } } } ); try { if (!ggtspd) { ggtspd = true; } } catch (e) {} } modifiedText = modifiedText.replace(reAd, ""); } if (modifiedText.length < text.length) { return modifiedText; } return text; } else { return text; } } } } catch (e) { return text; } } ; const realFetch = self.fetch; self.fetch = new Proxy(self.fetch,{ apply(target, thisArg, args) { const item = matchM3u(urlFromArg(args[0])); if (!item) { return Reflect.apply(target, thisArg, args); } return realFetch(...args).then(realResponse=>realResponse.text().then(text=>{ const modifiedText = pruner(text, item); return new Response(modifiedText,{ status: realResponse.status, statusText: realResponse.statusText, headers: realResponse.headers }); } )); } }); self.XMLHttpRequest.prototype.open = new Proxy(self.XMLHttpRequest.prototype.open,{ apply: async(target,thisArg,args)=>{ try { if (!shouldStopExecution) { const urlFromArgBy = urlFromArg(args[1]) , item = matchM3u(urlFromArgBy); if (ggljbmd.test(urlFromArgBy)) { shouldStopExecution = true; } else { m3u8gglj = urlFromArgBy; try { if (wzm3u8.test(m3u8gglj) && !mp4wz.test(m3u8gglj) && !flvwz.test(m3u8gglj) && !tswz.test(m3u8gglj) && !playsharewz.test(m3u8gglj)) { m3u8bflj = m3u8gglj; } } catch (e) {} } if (item) { thisArg.addEventListener('readystatechange', async function() { if (thisArg.readyState !== 4) { return; } const type = thisArg.responseType; if (type !== '' && type !== 'text') { return; } const textin = thisArg.responseText; const textout = pruner(textin, item); if (textout !== textin) { Reflect.defineProperty(thisArg, 'response', { value: textout }); Reflect.defineProperty(thisArg, 'responseText', { value: textout }); } }); } return Reflect.apply(target, thisArg, args); } else { return Reflect.apply(target, thisArg, args); } } catch (e) { return Reflect.apply(target, thisArg, args); } } }); } } catch (e) {} } } catch (e) {} } )();