theYNC.com Underground bypass

Watch theYNC Underground videos without needing an account

目前為 2024-12-23 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name theYNC.com Underground bypass
  3. // @description Watch theYNC Underground videos without needing an account
  4. // @require https://update.greasyfork.org/scripts/421384/1134973/GM_fetch.js
  5. // @grant GM_xmlhttpRequest
  6. // @connect media.theync.com
  7. // @namespace Violentmonkey Scripts
  8. // @match https://*.theync.com/*
  9. // @match https://*.theync.net/*
  10. // @match https://*.theync.com/*
  11. // @match https://theync.com/*
  12. // @match https://theync.net/*
  13. // @match https://theync.com/*
  14. // @grant none
  15. // @version 2.0
  16. // @license MIT
  17. // @author -
  18. // ==/UserScript==
  19. function getTheYNCVideoURL(url) {
  20. for (const [, group_url] of url.matchAll(
  21. /\/media\/thumbs\/(.*?)\.[a-zA-Z0-9_.-]*\//gm
  22. )) {
  23. return `https://media.theync.com/videos/${group_url}.mp4`;
  24. }
  25. }
  26. function waitForElement(selector) {
  27. return new Promise((resolve) => {
  28. {
  29. const element = document.querySelector(selector)
  30. if (element) {
  31. return resolve(element);
  32. }
  33. }
  34.  
  35. const observer = new MutationObserver(() => {
  36. const element = document.querySelector(selector)
  37. if (element) {
  38. observer.disconnect();
  39. resolve(element);
  40. }
  41. });
  42.  
  43. // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
  44. observer.observe(document.body, {
  45. childList: true,
  46. subtree: true,
  47. });
  48. });
  49. }
  50.  
  51. waitForElement(".content-block").then((contentBlock) => {
  52. for (const element of contentBlock.querySelectorAll(
  53. ".upgrade-profile > .upgrade-info-block"
  54. )) {
  55. const thumbnailURL = element.querySelector(
  56. ".image-block > .image > img"
  57. ).src;
  58. if (!thumbnailURL) continue;
  59. const videoURL = getTheYNCVideoURL(thumbnailURL);
  60. if (!videoURL) continue;
  61. location.href = videoURL;
  62. return;
  63. }
  64. for (const element of contentBlock.querySelectorAll(
  65. ".inner-block > a"
  66. )) {
  67. const undergroundLogo = element.querySelector(".item-info > .border-gold");
  68. if (!undergroundLogo) continue;
  69.  
  70. const thumbnailURL = element.querySelector(".image > img").src;
  71. if (!thumbnailURL) continue;
  72. const videoURL = getTheYNCVideoURL(thumbnailURL);
  73. if (!videoURL) continue;
  74. GM_fetch(videoURL, { method: 'head' }).then(response => {
  75. if (response.status !== 200) {
  76. return;
  77. }
  78. undergroundLogo.textContent = "BYPASSED"
  79. undergroundLogo.style.backgroundColor = "green"
  80. element.href = videoURL;
  81. })
  82.  
  83.  
  84.  
  85. }
  86. });