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.1
  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(".inner-block > a")) {
  65. const undergroundLogo = element.querySelector(".item-info > .border-gold");
  66. if (!undergroundLogo) continue;
  67.  
  68. const thumbnailURL = element.querySelector(".image > img").src;
  69. if (!thumbnailURL) continue;
  70. const videoURL = getTheYNCVideoURL(thumbnailURL);
  71. if (!videoURL) continue;
  72.  
  73. GM_fetch(videoURL, { method: "head" }).then((response) => {
  74. if (response.status === 200) {
  75. undergroundLogo.textContent = "BYPASSED";
  76. undergroundLogo.style.backgroundColor = "green";
  77. element.href = videoURL;
  78. return;
  79. }
  80. GM_fetch(`https://archive.org/wayback/available?url=${element.href}`, {
  81. method: "GET",
  82. })
  83. .then((response) => response.json())
  84. .then(({ archived_snapshots }) => {
  85. if (!archived_snapshots.closest) {
  86. return;
  87. }
  88. undergroundLogo.textContent = "ARCHIVED";
  89. undergroundLogo.style.backgroundColor = "blue";
  90. element.href = archived_snapshots.closest.url;
  91. });
  92. });
  93. }
  94. });