您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Watch theYNC Underground videos without needing an account
当前为
// ==UserScript== // @name theYNC.com Underground bypass // @description Watch theYNC Underground videos without needing an account // @require https://cdn.jsdelivr.net/npm/@trim21/[email protected]/dist/gm_fetch.js // @namespace Violentmonkey Scripts // @match *://*.theync.com/* // @match *://theync.com/* // @match *://*.theync.net/* // @match *://theync.net/* // @match *://*.theync.org/* // @match *://theync.org/* // @grant GM.xmlHttpRequest // @connect media.theync.com // @connect archive.org // @grant GM_addStyle // @grant GM_log // @version 3.7 // @license MIT // @author - // ==/UserScript== 'use strict' function waitForElement (selector) { return new Promise(resolve => { { const element = document.querySelector(selector) if (element) { return resolve(element) } } const observer = new MutationObserver(() => { const element = document.querySelector(selector) if (element) { observer.disconnect() resolve(element) } }) // If you get 'parameter 1 is not of type 'Node'' error, see https://stackoverflow.com/a/77855838/492336 observer.observe(document.body, { childList: true, subtree: true }) }) } function fetchArchive (url) { return GM_fetch(`https://archive.org/wayback/available?url=${url}`, { method: 'GET' }) } function queryArchive (url) { return fetchArchive(url) .then(archiveResponse => { if (!archiveResponse.ok) { if (archiveResponse.status === 429) { //Too many requests GM_log('Too many request, delaying fetching') return new Promise(resolve => { setTimeout(resolve, 2000) }).then(() => fetchArchive(url)) } console.error(archiveResponse) return Promise.reject(archiveResponse) } return archiveResponse }) .then(archiveResponse => archiveResponse.json()) .then(({ archived_snapshots }) => { if (archived_snapshots.closest) { return archived_snapshots.closest.url } return Promise.reject(archived_snapshots.closest.url) }) } GM_addStyle(` .loader { border: 0.25em solid #f3f3f3; border-top-width: 0.25em; border-top-style: solid; border-top-color: rgb(243, 243, 243); border-top: 0.25em solid rgb(0, 0, 0); border-radius: 50%; width: 1em; height: 1em; animation: spin 2s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .border-gold { display: flex !important; align-items: center; justify-content: center; gap: 1em; } `) function isValidURL (address) { try { const url = new URL(address) return GM_fetch(url, { method: 'HEAD' }).then(response => { if (response.ok) { return address } return Promise.reject(address) }) } catch (e) { return Promise.reject(address) } } function getTheYNCVideoURL (element) { const thumbnailURL = element.querySelector('.image > img').src if (!thumbnailURL) return for (const [, group_url] of thumbnailURL.matchAll( /^https?:\/\/theync\.(?:com|org|net)\/media\/thumbs\/(.*?)\.[a-zA-Z0-9_.-]*/gim )) { if (group_url) { return `https://media.theync.com/videos/${group_url}.mp4` } } } waitForElement('.content-block').then(contentBlock => { for (const element of contentBlock.querySelectorAll( '.inner-block > a:has(> .item-info > .border-gold)' )) { const undergroundLogo = element.querySelector('.item-info > .border-gold') const loadingElement = document.createElement('div') loadingElement.classList.add('loader') undergroundLogo.appendChild(loadingElement) isValidURL(getTheYNCVideoURL(element)) .then( url => { undergroundLogo.textContent = 'BYPASSED' undergroundLogo.style.backgroundColor = 'green' element.href = url }, _url => ['com', 'org', 'net'] .map(currentTLD => element.href.replace( /(^https?:\/\/theync\.)(com|org|net)(\/.*$)/gim, `$1${currentTLD}$3` ) ) .reduce( (accumulator, currentTLD) => accumulator.catch(() => queryArchive(currentTLD).then(url => { undergroundLogo.textContent = 'ARCHIVED' undergroundLogo.style.backgroundColor = 'blue' element.href = url }) ), Promise.reject() ) .catch(() => GM_log(`No bypass or archive found for ${element.href}`) ) ) .finally(() => loadingElement.remove()) } })