t66y助手

优化t66y网页使用体验

Устаревшая версия за 29.11.2023. Перейдите к последней версии.

  1. // ==UserScript==
  2. // @name t66y助手
  3. // @namespace com.t66y.jujufatu
  4. // @author jujufatu
  5. // @version 0.0.8
  6. // @description 优化t66y网页使用体验
  7. // @match http*://*t66y.com/*
  8. // @grant GM_setClipboard
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_deleteValue
  12. // @grant GM_registerMenuCommand
  13. // @grant unsafeWindow
  14. // @run-at document-start
  15. // @license CC BY-NC-ND 4.0
  16. // @homepage https://sleazyfork.org/zh-CN/scripts/480811-t66y%E5%8A%A9%E6%89%8B
  17. // @supportURL https://t66y.com/thread0806.php?fid=7
  18. // ==/UserScript==
  19.  
  20. (function() {
  21. "use strict";
  22. var pageWindow = unsafeWindow;
  23. const BAD_IMG_SVG = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMjAwcHgiIGhlaWdodD0iMjAwcHgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICAgICAgICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjMTBiMDE4IiAvPgogICAgICAgICAgPHRleHQgeD0iNTAlIiB5PSI3MS40IiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmaWxsPSIjZjdjNTAwIiBmb250LXNpemU9IjUyIiBmb250LWZhbWlseT0iQXJpYWwiPjx0c3BhbiB4PSI1MCUiIGR5PSIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7ov4fmnJ88L3RzcGFuPjx0c3BhbiB4PSI1MCUiIGR5PSI1Ny4yIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7lm77luoo8L3RzcGFuPjwvdGV4dD48L3N2Zz4=";
  24. const ERROR_FORMAT_BBCODE_TIP_IMG = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMjAwcHgiIGhlaWdodD0iMjAwcHgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICAgICAgICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiIC8+CiAgICAgICAgICA8dGV4dCB4PSI1MCUiIHk9IjYwLjM5OTk5OTk5OTk5OTk5IiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmaWxsPSIjZjdjNTAwIiBmb250LXNpemU9IjM2IiBmb250LWZhbWlseT0iQXJpYWwiPjx0c3BhbiB4PSI1MCUiIGR5PSIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7otLTlm748L3RzcGFuPjx0c3BhbiB4PSI1MCUiIGR5PSIzOS42IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7moLzlvI88L3RzcGFuPjx0c3BhbiB4PSI1MCUiIGR5PSIzOS42IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7plJnor688L3RzcGFuPjwvdGV4dD48L3N2Zz4=";
  25. const originalWindowOpen = pageWindow.open;
  26. pageWindow.open = function(url) {
  27. let nextUrl = url;
  28. if (/^https:\/\/2023\.redircdn\.com/.test(url)) {
  29. const queryParams = new URLSearchParams(new URL(url).search);
  30. const queryObj = {};
  31. for (const [ key, value ] of queryParams) {
  32. queryObj[key] = value === "undefined" ? undefined : value;
  33. }
  34. nextUrl = queryObj.src || url;
  35. }
  36. return originalWindowOpen.call(this, nextUrl);
  37. };
  38. document.addEventListener("click", handleLinkClick);
  39. window.addEventListener("error", function(event) {
  40. if (event.target.tagName === "IMG") {
  41. event.target.src = event.target.src.startsWith(location.origin) ? ERROR_FORMAT_BBCODE_TIP_IMG : BAD_IMG_SVG;
  42. }
  43. }, true);
  44. document.addEventListener("DOMContentLoaded", function() {
  45. let floors = [ ...document.querySelectorAll(".tpc_content") ];
  46. floors.forEach(floor => {
  47. floor.innerHTML = createMagnetLink(floor.innerHTML);
  48. });
  49. let initComments = [ ...document.querySelectorAll(".post_cont") ];
  50. initComments.forEach(c => {
  51. c.innerHTML = createMagnetLink(c.innerHTML);
  52. });
  53. if (typeof pageWindow.loadComment === "function") {
  54. const originalLoadComment = pageWindow.loadComment;
  55. pageWindow.loadComment = function() {
  56. var data = pageWindow["comm" + arguments[0]];
  57. for (var key in data) {
  58. data[key].c = createMagnetLink(data[key].c);
  59. }
  60. originalLoadComment.apply(this, arguments);
  61. };
  62. }
  63. });
  64. window.addEventListener("load", function() {
  65. if (document.body.innerHTML.includes("警告 / WARNING ")) {
  66. location.href = location.origin + "/index.php";
  67. }
  68. });
  69. function handleLinkClick(event) {
  70. const target = event.target;
  71. if (target.tagName === "A" && target.href) {
  72. let url = target.href;
  73. if (/^https:\/\/2023\.redircdn\.com\/\?http/.test(url)) {
  74. url = url.split("https://2023.redircdn.com/?")[1].replace(/______/g, ".").replace(/&z$/, "");
  75. event.preventDefault();
  76. window.open(url);
  77. }
  78. }
  79. }
  80. function createMagnetLink(str) {
  81. try {
  82. str = decodeURIComponent(str);
  83. str = decodeHtmlEntities(str);
  84. } catch (e) {
  85. console.log("createMagnetLink: format str error");
  86. }
  87. const magnetRegex = /(?<!<[^>]*)(?:magnet:\?xt=urn:btih:)?([A-Z2-7]{32}|[a-fA-F0-9]{40})(?:&dn=([^&\s]+))?(?:&tr=([^&\s]+))?/gi;
  88. function replaceFunc(match, hash, dn, tr) {
  89. const magnetPrefix = "magnet:?xt=urn:btih:";
  90. const decodedDn = dn ? `磁力链接-${decodeURIComponent(dn)}` : `磁力链接-${hash}`;
  91. const trParam = tr ? `&tr=${encodeURIComponent(tr)}` : "";
  92. let href = match.startsWith(magnetPrefix) ? match : `${magnetPrefix}${hash}${dn ? `&dn=${encodeURIComponent(dn)}` : ""}${trParam}`;
  93. href = href.replace(/\s+/g, "");
  94. return `<a href="${href}">${decodedDn}</a>&nbsp;|&nbsp;<a style="cursor: pointer;" onclick="t66ycopy('${href}')">复制</a>`;
  95. }
  96. return str.replace(magnetRegex, replaceFunc);
  97. }
  98. function decodeHtmlEntities(str) {
  99. return str.replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&nbsp;/g, " ").replace(/&iexcl;/g, "¡").replace(/&cent;/g, "¢").replace(/&pound;/g, "£").replace(/&curren;/g, "¤").replace(/&yen;/g, "¥").replace(/&brvbar;/g, "¦").replace(/&sect;/g, "§").replace(/&uml;/g, "¨").replace(/&copy;/g, "©").replace(/&ordf;/g, "ª").replace(/&laquo;/g, "«").replace(/&not;/g, "¬").replace(/&shy;/g, "­").replace(/&reg;/g, "®").replace(/&macr;/g, "¯").replace(/&deg;/g, "°").replace(/&plusmn;/g, "±").replace(/&sup2;/g, "²").replace(/&sup3;/g, "³").replace(/&acute;/g, "´").replace(/&micro;/g, "µ").replace(/&para;/g, "¶").replace(/&middot;/g, "·").replace(/&cedil;/g, "¸").replace(/&sup1;/g, "¹").replace(/&ordm;/g, "º").replace(/&raquo;/g, "»").replace(/&frac14;/g, "¼").replace(/&frac12;/g, "½").replace(/&frac34;/g, "¾").replace(/&iquest;/g, "¿").replace(/&amp;/g, "&");
  100. }
  101. pageWindow.t66ycopy = function(str) {
  102. GM_setClipboard(str);
  103. Message({
  104. msg: "复制成功",
  105. duration: 666
  106. });
  107. };
  108. function Message({
  109. msg,
  110. duration = 1024
  111. } = {}) {
  112. const messageElement = document.createElement("div");
  113. messageElement.textContent = msg;
  114. messageElement.style.position = "fixed";
  115. messageElement.style.top = "66px";
  116. messageElement.style.left = "50%";
  117. messageElement.style.transform = "translate(-50%, -50%)";
  118. messageElement.style.backgroundColor = "#10b018";
  119. messageElement.style.color = "#f7c500";
  120. messageElement.style.fontSize = "3rem";
  121. messageElement.style.padding = "20px";
  122. messageElement.style.boxShadow = "0 4px 8px rgba(0,0,0,0.1)";
  123. messageElement.style.borderRadius = "10px";
  124. messageElement.style.zIndex = "1000";
  125. messageElement.style.transition = "opacity 0.5s, transform 0.5s";
  126. messageElement.style.opacity = "0";
  127. document.body.appendChild(messageElement);
  128. setTimeout(() => {
  129. messageElement.style.opacity = "1";
  130. messageElement.style.transform = "translate(-50%, -50%) scale(1)";
  131. }, 10);
  132. setTimeout(() => {
  133. messageElement.style.opacity = "0";
  134. messageElement.style.transform = "translate(-50%, -50%) scale(0.9)";
  135. setTimeout(() => {
  136. document.body.removeChild(messageElement);
  137. }, 500);
  138. }, duration);
  139. }
  140. let style = document.createElement("style");
  141. document.head.appendChild(style);
  142. style.sheet.insertRule(`.bad_bg { background-image: url("${BAD_IMG_SVG}") !important; }`, 0);
  143. })();