Github Enhancement - High Speed Download (Kentxxq Dynamic Mirror Version)

Dynamically fetches mirror URLs from mirror.kentxxq.com for high-speed downloads on Github.

当前为 2025-08-28 提交的版本,查看 最新版本

// ==UserScript==
// @name         Github Enhancement - High Speed Download (Kentxxq Dynamic Mirror Version)
// @name:zh-CN   Github 增强 - 高速下载 (Kentxxq 动态镜像版)
// @version      3.0.0
// @author       X.I.U (Modified for dynamic fetching)
// @description  Dynamically fetches mirror URLs from mirror.kentxxq.com for high-speed downloads on Github.
// @description:zh-CN  从 mirror.kentxxq.com 动态获取镜像地址,实现 Github 文件高速下载、Clone 加速等功能。
// @match        *://github.com/*
// @match        *://hub.whtrys.space/*
// @match        *://dgithub.xyz/*
// @match        *://kkgithub.com/*
// @match        *://github.site/*
// @match        *://github.store/*
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAACEUExURUxpcRgWFhsYGBgWFhcWFh8WFhoYGBgWFiUlJRcVFRkWFhgVFRgWFhgVFRsWFhgWFigeHhkWFv////////////r6+h4eHv///xcVFfLx8SMhIUNCQpSTk/r6+jY0NCknJ97e3ru7u+fn51BOTsPCwqGgoISDg6empmpoaK2srNDQ0FhXV3eXcCcAAAAXdFJOUwCBIZXMGP70BuRH2Ze/LpIMUunHkpQR34sfygAAAVpJREFUOMt1U+magjAMDAVb5BDU3W25b9T1/d9vaYpQKDs/rF9nSNJkArDA9ezQZ8wPbc8FE6eAiQUsOO1o19JolFibKCdHGHC0IJezOMD5snx/yE+KOYYr42fPSufSZyazqDoseTPw4lGJNOu6LBXVUPBG3lqYAOv/5ZwnNUfUifzBt8gkgfgINmjxOpgqUA147QWNaocLniqq3QsSVbQHNp45N/BAwoYQz9oUJEiE4GMGfoBSMj5gjeWRIMMqleD/CAzUHFqTLyjOA5zjNnwa4UCEZ2YK3khEcBXHjVBtEFeIZ6+NxYbPqWp1DLKV42t6Ujn2ydyiPi9nX0TTNAkVVZ/gozsl6FbrktkwaVvL2TRK0C8Ca7Hck7f5OBT6FFbLATkL2ugV0tm0RLM9fedDvhWstl8Wp9AFDjFX7yOY/lJrv8AkYuz7fuP8dv9izCYH+x3/LBnj9fYPBTpJDNzX+7cAAAAASUVORKCYII=
// @grant        GM_xmlhttpRequest
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_openInTab
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_notification
// @grant        GM_setClipboard
// @grant        window.onurlchange
// @connect      mirror.kentxxq.com
// @sandbox      JavaScript
// @license      GPL-3.0 License
// @run-at       document-end
// @namespace    https://gf.qytechs.cn/scripts/412245
// @supportURL   https://github.com/XIU2/UserScript
// @homepageURL  https://github.com/XIU2/UserScript
// ==/UserScript==

(function() {
    'use strict';

    // 当动态抓取失败时,使用的备用静态地址列表
    const fallbackMirrors = [
        ['https://cors.isteed.cc/https://github.com', 'cors.isteed.cc', '备用镜像'],
        ['https://gh.aptv.app/https://github.com', 'gh.aptv.app', '备用镜像'],
        ['https://ghfast.top/https://github.com', 'ghfast.top', '备用镜像'],
        ['https://ghproxy.cn/https://github.com', 'ghproxy.cn', '备用镜像'],
        ['https://gh-proxy.com/https://github.com', 'gh-proxy.com', '备用镜像'],
        ['https://ghproxy.net/https://github.com', 'ghproxy.net', '备用镜像'],
        ['https://wget.la/https://github.com', 'wget.la', '备用镜像']
    ];

    /**
     * 初始化脚本的主函数
     * @param {Array} mirrors - 从镜像站抓取或备用的镜像地址列表
     */
    function initializeScript(mirrors) {
        // 将传入的镜像列表赋值给脚本的核心变量
        const download_url_us = mirrors;

        // --- 以下是原脚本的核心逻辑 ---
        var menu_rawFast = GM_getValue('xiu2_menu_raw_fast'), menu_rawFast_ID, menu_rawDownLink_ID, menu_gitClone_ID, menu_customUrl_ID, menu_feedBack_ID;
        const download_url = []; // 保持为空,优先使用动态列表
        const clone_url = [
            ['https://gitclone.com', '国内', '[中国 国内] - 该公益加速源由 [GitClone] 提供

 - 缓存:有
 - 首次比较慢,缓存后较快'],
            ['https://kkgithub.com', '香港', '[中国香港、日本、新加坡等] - 该公益加速源由 [help.kkgithub.com] 提供'],
        ];
        const clone_ssh_url = [
            ['ssh://[email protected]:443/', 'Github 原生', '[日本、新加坡等] - Github 官方提供的 443 端口的 SSH(依然是 SSH 协议),适用于限制访问 22 端口的网络环境'],
        ];
        const raw_url = [
            ['https://raw.githubusercontent.com', 'Github 原生', '[日本 东京]

 - 缓存:无(或很短)'],
            ['https://raw.kkgithub.com', '香港 1', '[中国香港、日本、新加坡等] - 该公益加速源由 [help.kkgithub.com] 提供

 - 缓存:有'],
            ['https://wget.la/https://raw.githubusercontent.com', '香港 2', '[中国香港、中国台湾、日本、美国等](CDN 不固定) - 该公益加速源由 [ucdn.me] 提供

 - 缓存:无(或很短)'],
            ['https://ghfast.top/https://raw.githubusercontent.com', '韩国', '[日本、韩国、新加坡、美国、德国等](CDN 不固定) - 该公益加速源由 [ghproxy.link] 提供

 - 缓存:无(或很短)'],
            ['https://ghproxy.net/https://raw.githubusercontent.com', '日本 1', '[日本 大阪] - 该公益加速源由 [ghproxy.net] 提供

 - 缓存:有(约 10 分钟)'],
        ];
        const svg = [
            '<svg class="octicon octicon-cloud-download" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M9 12h2l-3 3-3-3h2V7h2v5zm3-8c0-.44-.91-3-4.5-3C5.08 1 3 2.92 3 5 1.02 5 0 6.52 0 8c0 1.53 1 3 3 3h3V9.7H3C1.38 9.7 1.3 8.28 1.3 8c0-.17.05-1.7 1.7-1.7h1.3V5c0-1.39 1.56-2.7 3.2-2.7 2.55 0 3.13 1.55 3.2 1.8v1.2H12c.81 0 2.7.22 2.7 2.2 0 2.09-2.25 2.2-2.7 2.2h-2V11h2c2.08 0 4-1.16 4-3.5C16 5.06 14.08 4 12 4z"></path></svg>'
        ];
        const style = ['padding:0 6px; margin-right: -1px; border-radius: 2px; background-color: var(--XIU2-background-color); border-color: var(--borderColor-default); font-size: 11px; color: var(--XIU2-font-color);'];

        if (menu_rawFast == null){menu_rawFast = 1; GM_setValue('xiu2_menu_raw_fast', 1)};
        if (GM_getValue('menu_rawDownLink') == null){GM_setValue('menu_rawDownLink', true)};
        if (GM_getValue('menu_gitClone') == null){GM_setValue('menu_gitClone', true)};
        if (GM_getValue('custom_raw_url')) {raw_url.splice(1, 0, [GM_getValue('custom_raw_url'), '自定义', '[由你自定义的 Raw 加速源]...'])};
        if (GM_getValue('custom_clone_url')) {clone_url.unshift([GM_getValue('custom_clone_url'), '自定义', '[由你自定义的 Git Clone 加速源]...'])};
        registerMenuCommand();
        function registerMenuCommand() {
            if (menu_feedBack_ID) {GM_unregisterMenuCommand(menu_rawFast_ID); GM_unregisterMenuCommand(menu_rawDownLink_ID); GM_unregisterMenuCommand(menu_gitClone_ID); GM_unregisterMenuCommand(menu_customUrl_ID); GM_unregisterMenuCommand(menu_feedBack_ID); menu_rawFast = GM_getValue('xiu2_menu_raw_fast');}
            if (menu_rawFast > raw_url.length - 1) menu_rawFast = 0
            if (GM_getValue('menu_rawDownLink')) menu_rawFast_ID = GM_registerMenuCommand(`${['0️⃣','1️⃣','2️⃣','3️⃣','4️⃣','5️⃣','6️⃣','7️⃣','8️⃣','9️⃣','🔟'][menu_rawFast]} [ ${raw_url[menu_rawFast][1]} ] 加速源 (☁) - 点击切换`, menu_toggle_raw_fast);
            menu_rawDownLink_ID = GM_registerMenuCommand(`${GM_getValue('menu_rawDownLink')?'✅':'❌'} 项目列表单文件快捷下载 (☁)`, function(){if (GM_getValue('menu_rawDownLink') == true) {GM_setValue('menu_rawDownLink', false);} else {GM_setValue('menu_rawDownLink', true);} location.reload();});
            menu_gitClone_ID = GM_registerMenuCommand(`${GM_getValue('menu_gitClone')?'✅':'❌'} 添加 git clone 命令`, function(){if (GM_getValue('menu_gitClone') == true) {GM_setValue('menu_gitClone', false);} else {GM_setValue('menu_gitClone', true);} location.reload();});
            menu_customUrl_ID = GM_registerMenuCommand(`#️⃣ 自定义加速源`, function () {
                const customKeys = [
                    { key: 'custom_raw_url', desc: 'Raw 加速源', placeholder: 'https://e.g./https://raw.githubusercontent.com' },
                    { key: 'custom_clone_url', desc: 'Git Clone 加速源', placeholder: 'https://e.g./https://github.com' },
                    { key: 'custom_download_url', desc: 'Release/Code(ZIP) 加速源', placeholder: 'https://e.g./https://github.com' }
                ];
                function promptCustomUrl(index = 0) {
                    if (index >= customKeys.length) {location.reload(); return;}
                    const { key, desc, placeholder } = customKeys[index];
                    let current = GM_getValue(key, '');
                    let input = prompt(`请输入自定义${desc}地址:\n- 当前:${current || '(未设置)'}\n- 示例:${placeholder}\n- 留空为不设置`,current);
                    if (input !== null) {GM_setValue(key, input.trim()); promptCustomUrl(index + 1);}
                }
                promptCustomUrl();
            });
            menu_feedBack_ID = GM_registerMenuCommand('💬 反馈 & 建议', function () {window.GM_openInTab('https://github.com/XIU2/UserScript/issues');});
        }
        function menu_toggle_raw_fast() {
            if (menu_rawFast >= raw_url.length - 1) {menu_rawFast = 0;} else {menu_rawFast += 1;}
            GM_setValue('xiu2_menu_raw_fast', menu_rawFast);
            delRawDownLink(); addRawDownLink();
            GM_notification({text: "已切换加速源为:" + raw_url[menu_rawFast][1], timeout: 3000});
            registerMenuCommand();
        };
        colorMode();
        setTimeout(addRawFile, 1000);
        setTimeout(addRawDownLink, 2000);
        if (window.onurlchange === undefined) addUrlChangeEvent();
        window.addEventListener('urlchange', function() {
            colorMode();
            if (location.pathname.indexOf('/releases')) addRelease();
            setTimeout(addRawFile, 1000);
            setTimeout(addRawDownLink, 2000);
            setTimeout(addRawDownLink_, 1000);
        });
        const callback = (mutationsList, observer) => {
             // ... [MutationObserver logic remains the same as original script] ...
        };
        const observer = new MutationObserver(callback);
        observer.observe(document, { childList: true, subtree: true });

        function get_New_download_url() {
            let shuffled = download_url_us.slice(0), i = download_url_us.length, temp, index;
            while (i--) { index = Math.floor((i + 1) * Math.random()); temp = shuffled[index]; shuffled[index] = shuffled[i]; shuffled[i] = temp; }
            if (GM_getValue('custom_download_url')) {return [[GM_getValue('custom_download_url'), '自定义', '...']].concat(shuffled);}
            return shuffled;
        }

        function addRelease() {
            let html = document.querySelectorAll('.Box-footer'); if (html.length == 0 || location.pathname.indexOf('/releases') == -1) return
            let divDisplay = 'margin-left: -90px;', new_download_url = get_New_download_url();
            if (document.documentElement.clientWidth > 755) {divDisplay = 'margin-top: -3px;margin-left: 8px;display: inherit;';};
            for (const current of html) {
                if (current.querySelector('.XIU2-RS')) continue
                current.querySelectorAll('li.Box-row a').forEach(function (_this) {
                    let href = _this.href.split(location.host), url = '', _html = `<div class="XIU2-RS" style="${divDisplay}">`;
                    for (let i=0;i<new_download_url.length;i++) {
                        url = new_download_url[i][0] + href[1]
                        _html += `<a style="${style[0]}" class="btn" href="${url}" target="_blank" title="${new_download_url[i][2]}" rel="noreferrer noopener nofollow">${new_download_url[i][1]}</a>`
                    }
                    _this.parentElement.nextElementSibling.insertAdjacentHTML('beforeend', _html + '</div>');
                });
            }
        }
        // ... [The rest of the script functions: addDownloadZIP, addGitClone, etc. remain the same] ...
        // Note: For brevity, the rest of the original script's functions are not repeated here.
        // They would be included in a complete script.
        function addDownloadZIP(target) { /* ... original code ... */ }
        function addGitCloneClear(css) { /* ... original code ... */ }
        function addGitClone(target) { /* ... original code ... */ }
        function addGitCloneSSH(target) { /* ... original code ... */ }
        function addRawFile() { /* ... original code ... */ }
        function addRawDownLink() { /* ... original code ... */ }
        function delRawDownLink() { /* ... original code ... */ }
        function addRawDownLink_() { /* ... original code ... */ }
        function colorMode() { /* ... original code ... */ }
        function addUrlChangeEvent() { /* ... original code ... */ }
    }


    /**
     * 抓取、解析镜像地址并启动脚本
     */
    function fetchMirrorsAndRun() {
        GM_xmlhttpRequest({
            method: "GET",
            url: "https://mirror.kentxxq.com/github",
            onload: function(response) {
                try {
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(response.responseText, "text/html");

                    // !!! 关键选择器 !!!
                    // 这个选择器用于在镜像站点的HTML中找到包含镜像域名的元素。
                    // 根据您截图的页面结构推测,域名可能是 <h2> 标题。
                    // 如果页面结构改变,您需要更新这个选择器。
                    const selector = 'div[class*="rounded-md"] h2';
                    const mirrorElements = doc.querySelectorAll(selector);

                    if (mirrorElements.length === 0) {
                        console.error("Github 加速脚本: 未能从镜像站找到任何地址 (选择器可能已失效),将使用内置的备用地址。");
                        initializeScript(fallbackMirrors);
                        return;
                    }

                    // 提取域名文本,并只取前7个
                    const extractedDomains = Array.from(mirrorElements)
                        .map(el => el.textContent.trim())
                        .slice(0, 7);

                    // 格式化为脚本需要的数组结构
                    const formattedMirrors = extractedDomains.map(domain => ([
                        `https://${domain}/https://github.com`,
                        domain,
                        `镜像由 kentxxq.com 提供`
                    ]));

                    console.log("Github 加速脚本: 成功抓取并加载了最新的镜像地址。");
                    initializeScript(formattedMirrors);

                } catch (e) {
                    console.error("Github 加速脚本: 解析镜像页面时出错,将使用内置的备用地址。", e);
                    initializeScript(fallbackMirrors);
                }
            },
            onerror: function(error) {
                console.error("Github 加速脚本: 无法访问镜像站点,将使用内置的备用地址。", error);
                initializeScript(fallbackMirrors);
            },
            ontimeout: function() {
                console.error("Github 加速脚本: 访问镜像站点超时,将使用内置的备用地址。");
                initializeScript(fallbackMirrors);
            }
        });
    }

    // 启动脚本
    fetchMirrorsAndRun();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址