🏠 返回首頁 

Greasy Fork is available in English.

YouTube Anti-RickRoll

Give a warning alert if video is suspected RickRoll.


安装此脚本?
  1. // ==UserScript==
  2. // @name YouTube Anti-RickRoll
  3. // @match *://*.youtube.com/watch*
  4. // @grant none
  5. // @version 1.1.0
  6. // @author yodaluca23
  7. // @license GNU GPLv3
  8. // @description Give a warning alert if video is suspected RickRoll.
  9. // @namespace https://greasyfork.org/users/1315976
  10. // ==/UserScript==
  11. const larssieboy18 = 'https://raw.githubusercontent.com/larssieboy18/rickroll-list/refs/heads/main/rickrolls.json';
  12. const dnorhojBlockedIds = 'https://raw.githubusercontent.com/dnorhoj/AntiRickRoll/refs/heads/main/src/background/blockedIds.js';
  13. // Function to fetch RickRoll IDs from both sources
  14. async function extractYouTubeIDs() {
  15. try {
  16. const [rickrollResponse, blockedIdsResponse] = await Promise.all([
  17. fetch(larssieboy18),
  18. fetch(dnorhojBlockedIds)
  19. ]);
  20. const rickrollData = await rickrollResponse.json();
  21. const blockedIdsData = await blockedIdsResponse.text();
  22. const youtubeRegex = /(?:youtube\.com\/watch\?v=|youtu\.be\/|video_id=)([\w-]+)/g;
  23. const links = rickrollData.rickrolls || [];
  24. const youtubeIDs = [];
  25. for (const link of links) {
  26. let match;
  27. while ((match = youtubeRegex.exec(link)) !== null) {
  28. youtubeIDs.push(match[1]);
  29. }
  30. }
  31. const blockedIdsMatch = blockedIdsData.replace('export default ', '').replace(';', '');
  32. const blockedIds = JSON.parse(blockedIdsMatch);
  33. const allVideoIDs = [...new Set([...youtubeIDs, ...blockedIds])];
  34. return allVideoIDs;
  35. } catch (error) {
  36. console.error('Error fetching or processing data:', error);
  37. return [];
  38. }
  39. }
  40. function extractSong() {
  41. if (unsafeWindow.ytInitialData.engagementPanels) {
  42. for (const panel of unsafeWindow.ytInitialData.engagementPanels) {
  43. const section = panel.engagementPanelSectionListRenderer;
  44. if (section && section.content && section.content.structuredDescriptionContentRenderer) {
  45. const items = section.content.structuredDescriptionContentRenderer.items;
  46. for (const item of items) {
  47. if (item.horizontalCardListRenderer && item.horizontalCardListRenderer.cards) {
  48. for (const card of item.horizontalCardListRenderer.cards) {
  49. if (card.videoAttributeViewModel && card.videoAttributeViewModel.title) {
  50. // Return the found title
  51. return card.videoAttributeViewModel.title;
  52. }
  53. }
  54. }
  55. }
  56. }
  57. }
  58. }
  59. // return a value that will not be matched with regex
  60. return "not";
  61. }
  62. // Function to check if the video is a RickRoll
  63. function isRickRoll() {
  64. try {
  65. const videoDetails = unsafeWindow.ytInitialPlayerResponse.videoDetails;
  66. const videoTitle = videoDetails?.title?.toLowerCase().replace(/\s+/g, '');
  67. const videoKeywords = videoDetails?.keywords?.map(keyword => keyword.toLowerCase().replace(/\s+/g, ''));
  68. const song = extractSong().toLowerCase().replace(/\s+/g, '');
  69. const rickrollPattern = /(rickroll|rickastley|nevergoingtogiveyouup|nevergonnagiveyouup)/;
  70. // Check if videoTitle or videoKeywords exist and match the pattern
  71. if ((videoTitle && videoTitle.match(rickrollPattern)) || (song.match(rickrollPattern)) || (videoKeywords && videoKeywords.some(keyword => keyword.match(rickrollPattern)))) {
  72. return true;
  73. }
  74. } catch (e) {
  75. console.error('Error while checking video details:', e);
  76. }
  77. return false;
  78. }
  79. // Function to display warning
  80. function warning(message) {
  81. document.querySelector('video').pause();
  82. var userResponse = confirm(message);
  83. if (!userResponse) {
  84. if (document.querySelector('button[title="Mute (m)"]')) {
  85. document.querySelector('button[title="Mute (m)"]').click();
  86. }
  87. }
  88. }
  89. // Main logic
  90. extractYouTubeIDs().then((ids) => {
  91. const currentVideoID = window.location.href.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]+)/);
  92. if (currentVideoID && ids.includes(currentVideoID[1])) {
  93. warning("This is a RickRoll! Do you want to continue? (Cancel to mute)");
  94. } else if (isRickRoll()) {
  95. warning("This is likely a RickRoll! Do you want to continue? (Cancel to mute)");
  96. }
  97. });