您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
跳过下载时的 5 秒等待,适用于新旧 Curseforge。
// ==UserScript== // @name Curseforge 直接下载 // @namespace su226 // @include https://www.curseforge.com/* // @include https://legacy.curseforge.com/* // @grant none // @version 1.1 // @author su226 // @description 跳过下载时的 5 秒等待,适用于新旧 Curseforge。 // @license MIT // ==/UserScript== function observeSelector(selector, callback) { for (const el of document.querySelectorAll(selector)) { callback(el); } new MutationObserver((mutations, observer) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeType != Node.ELEMENT_NODE) { continue; } if (node.matches(selector)) { callback(node); } for (const el of node.querySelectorAll(selector)) { callback(el); } } } }).observe(document, { childList: true, subtree: true }); } async function downloadOld(href) { if (href.match(/\/\d+$/)) { location.href = href + "/file"; return; } try { const response = await fetch(href); const content = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(content, "text/html"); const downloadLink = doc.querySelector(".alink").href; location.href = downloadLink; } catch (e) { // 下载一段时间内下载过的文件会直接跳转 edge.forgecdn.net,导致触发 CORS 拦截 console.exception(e); location.href = href; } } async function downloadNew(href) { try { const response = await fetch(href); const content = await response.text(); const projectId = content.match(/\\"project\\":{\\"id\\":(\d+)/)[1]; const fileId = href.match(/\d+$/); location.href = `https://www.curseforge.com/api/v1/mods/${projectId}/files/${fileId}/download`; } catch (e) { // 这个纯粹是兜底 console.exception(e); location.href = href; } } if (location.host.indexOf("legacy") !== -1) { observeSelector("a", el => { if (!el.href.match(/\/download($|\/)/) || el.href.indexOf("?client=y") !== -1) { return; } console.log(el); el.addEventListener("click", e => { e.preventDefault(); downloadOld(el.href); }); }); } else { observeSelector(".download-cta", el => { console.log(el); el.addEventListener("click", e => { e.preventDefault(); downloadNew(el.href); }) }); observeSelector(".kebab-menu a", el => { if (el.href.indexOf("/download/") === -1) { return; } console.log(el); el.addEventListener("click", e => { e.preventDefault(); downloadNew(el.href); }) }); observeSelector(".project-download-modal .download-btn", el => { console.log(el); el.addEventListener("click", e => { e.preventDefault(); downloadNew(el.href); }); }); observeSelector(".download-button", el => { console.log(el); el.addEventListener("click", e => { e.preventDefault(); downloadNew(el.href); }); }); }