theYNC.com Underground bypass

Watch theYNC Underground videos without needing an account

Per 26-12-2024. Zie de nieuwste versie.

// ==UserScript==
// @name        theYNC.com Underground bypass
// @description Watch theYNC Underground videos without needing an account
// @require     https://cdn.jsdelivr.net/npm/@trim21/[email protected]
// @namespace   Violentmonkey Scripts
// @match       *://*.theync.com/*
// @match       *://theync.com/*
// @match       *://*.theync.net/*
// @match       *://theync.net/*
// @match       *://*.theync.com/*
// @match       *://theync.com/*
// @grant       GM.xmlHttpRequest
// @connect     media.theync.com
// @connect     archive.org
// @grant       GM_addStyle
// @version     3.0
// @license     MIT
// @author      -
// ==/UserScript==

function getTheYNCVideoURLFromThumbnail (url) {
  for (const [, group_url] of url.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`
    }
  }
}

function isValidURL (url) {
  return new Promise((resolve, reject) =>
    GM_fetch(url, { method: 'HEAD' }).then(response => {
      if (response.ok) {
        return resolve(response.status)
      }
      return reject(response.status)
    })
  )
}

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
    })
  })
}

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;
}
`)

waitForElement('.content-block').then(contentBlock => {
  for (const element of contentBlock.querySelectorAll(
    '.upgrade-profile > .upgrade-info-block'
  )) {
    const thumbnailURL = element.querySelector(
      '.image-block > .image > img'
    ).src

    if (!thumbnailURL) continue

    const videoURL = getTheYNCVideoURLFromThumbnail(thumbnailURL)

    if (!videoURL) continue

    isValidURL(videoURL).then(_status => {
      location.href = videoURL
    })

    return
  }
  for (const element of contentBlock.querySelectorAll('.inner-block > a')) {
    const undergroundLogo = element.querySelector('.item-info > .border-gold')

    if (!undergroundLogo) continue

    const thumbnailURL = element.querySelector('.image > img').src

    if (!thumbnailURL) continue

    const videoURL = getTheYNCVideoURLFromThumbnail(thumbnailURL)

    if (!videoURL) continue

    const loadingElement = document.createElement("div");
    loadingElement.classList.add('loader')
    undergroundLogo.appendChild(loadingElement);
    

    isValidURL(videoURL).then(
      _status => {
        undergroundLogo.textContent = 'BYPASSED'
        undergroundLogo.style.backgroundColor = 'green'
        element.href = videoURL
      },
      _status =>
        GM_fetch(`https://archive.org/wayback/available?url=${element.href}`, {
          method: 'GET'
        })
          .then(archiveResponse => archiveResponse.json())
          .then(({ archived_snapshots }) => {
            if (archived_snapshots.closest) {
              undergroundLogo.textContent = 'ARCHIVED'
              undergroundLogo.style.backgroundColor = 'blue'
              element.href = archived_snapshots.closest.url
            }
          })
    ).finally(() => {
        loadingElement.remove()
    })
  }
})