下载链接信息查询助手

检测页面中的 DDL/Torrent/Ed2k 链接并查询其信息显示在弹窗中

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         下载链接信息查询助手
// @namespace    https://whatslink.info/
// @version      1.0
// @description  检测页面中的 DDL/Torrent/Ed2k 链接并查询其信息显示在弹窗中
// @match        *://*/*
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function () {
  "use strict";

  // 1. 添加样式
  GM_addStyle(`
    .wl-btn {
      display: inline-block;
      margin-left: 6px;
      padding: 2px 6px;
      font-size: 12px;
      background: #007bff;
      color: white;
      border: none;
      border-radius: 3px;
      cursor: pointer;
    }
    .wl-btn:hover {
      background: #0056b3;
    }
    .wl-dialog {
      background: white;
      border: 1px solid #ccc;
      border-radius: 6px;
      padding: 16px;
      width: 50vw;
      max-height: 80vh;
      overflow-y: auto;
      box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    }
    .wl-dialog h3 {
      margin-top: 0;
      font-size: 16px;
    }
    .wl-dialog img {
      max-width: 100%;
      margin-top: 8px;
      border-radius: 4px;
    }
    .wl-close {
      float: right;
      cursor: pointer;
      color: #888;
    }
    .wl-close:hover {
      color: #000;
    }
  `);

  // 2. 匹配常见下载协议
  const downloadLinkRegex = /(magnet:\?|ed2k:\/\/|\.torrent($|\?)|ddl:\/\/)/i;

  // 3. 扫描所有链接
  const links = Array.from(document.querySelectorAll("a[href],input")).filter((a) =>
    downloadLinkRegex.test(a.href)
  );

  if (!links.length) return;

  links.forEach((link) => {
    const btn = document.createElement("button");
    btn.textContent = "🔍 查看信息";
    btn.className = "wl-btn";
    btn.addEventListener("click", () => showLinkInfo(link.href));
    link.insertAdjacentElement("afterend", btn);
  });

  // 4. 显示信息弹窗
  async function showLinkInfo(url) {
    const dialog = document.createElement("div");
    dialog.id = "mypopover";
    dialog.popover = "auto";
    dialog.className = "wl-dialog";
    dialog.innerHTML = `<span class="wl-close">✖</span><h3>链接信息加载中...</h3>`;
    const closeBtn = `<button popovertarget="mypopover" class="wl-close">✖</button>`
    document.body.appendChild(dialog);
    dialog.showPopover();
    try {
      const api = `https://whatslink.info/api/v1/link?url=${encodeURIComponent(url)}`;
      const res = await fetch(api);
      const data = await res.json();

      let html = `
        ${closeBtn}
        <h3>🔗 链接信息</h3>
        <p><b>类型:</b> ${data.type || "未知"}</p>
        <p><b>文件类型:</b> ${data.file_type || "未知"}</p>
        <p><b>名称:</b> ${data.name || "未提供"}</p>
        <p><b>大小:</b> ${data.size ? formatSize(data.size) : "未知"}</p>
        <p><b>文件数量:</b> ${data.count ?? "未知"}</p>
      `;

      if (Array.isArray(data.screenshots) && data.screenshots.length > 0) {
        html += `<h4>截图:</h4>`;
        data.screenshots.forEach((sc) => {
          html += `<div><img src="${sc.screenshot}" alt="screenshot: ${sc.screenshot}"></div>`;
        });
      }

      dialog.innerHTML = html;
    } catch (err) {
      dialog.innerHTML = `
        ${closeBtn}
        <h3>❌ 查询失败</h3>
        <p>${err.message}</p>
      `;
    }
  }

  // 5. 辅助函数:格式化文件大小
  function formatSize(bytes) {
    if (bytes < 1024) return bytes + " B";
    const units = ["KB", "MB", "GB", "TB"];
    let i = -1;
    do {
      bytes = bytes / 1024;
      i++;
    } while (bytes >= 1024 && i < units.length - 1);
    return bytes.toFixed(1) + " " + units[i];
  }
})();