Greasy Fork

(改)123 云盘下载助手

一个基于 JavaScript 的 123 网盘文件下载工具 | 基于【123云盘下载辅助】修改自0.3版本 | 不保证可用性

目前为 2024-10-22 提交的版本。查看 最新版本

// ==UserScript==
// @name         (改)123 云盘下载助手
// @namespace    github.com/hmjz100
// @version      1.0.0
// @description  一个基于 JavaScript 的 123 网盘文件下载工具 | 基于【123云盘下载辅助】修改自0.3版本 | 不保证可用性
// @license      MIT
// @match        https://www.123pan.com/*
// @match        https://www.123pan.cn/*
// @match        https://www.123865.com/*
// @match        https://www.123684.com/*
// @grant        none
// @author       hmjz100、Qing
// @run-at       document-start
// ==/UserScript==

(function () {
    // 各操作系统和各版本号
    const android = { os: "Android", versions: ["6.0", "7.1.2", "8.1.0", "9.0", "10.0"] };
    const ios = { os: "iOS", versions: ["12.0", "13.4", "14.0", "15.0"] };

    // 各品牌对应的操作系统
    const devices = {
        "Apple": ios,
        "Xiaomi": android,
        "Samsung": android,
        "Huawei": {
            ...android,
            hmos: () => (Math.random() < 0.5 ? "HarmonyOS;" : ""),
            hmsCore: () => `HMSCore ${Math.floor(Math.random() * 7) + 1}.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 1000)};`
        },
        "Google": android,
        "OnePlus": android
    };

    // 123云盘版本号列表
    const appVersionList = ["2.1.4", "2.3.1", "2.3.4", "2.3.5", "2.3.7", "2.3.8", "2.3.9", "2.3.12", "2.4.0"];
    const appVersion = appVersionList[Math.floor(Math.random() * appVersionList.length)];

    // 随机选择品牌及对应操作系统
    const brands = Object.keys(devices);
    const brand = brands[Math.floor(Math.random() * brands.length)];
    const { os, versions } = devices[brand];

    // 随机选择系统版本
    const version = `${versions[Math.floor(Math.random() * versions.length)]};`;

    // 生成 UA 字符串
    let uaString = `123pan/v${appVersion} (${os}_${version}${brand})`;

    // 如果是华为设备,添加 HarmonyOS 和 HMSCore 信息
    /*if (brand === "Huawei") {
        uaString = `123pan/v${appVersion} (${os}_${version}${devices.Huawei.hmos()}${devices.Huawei.hmsCore()}${brand})`;
    }*/

    // 重写 XMLHttpRequest
    const originalXHR = window.XMLHttpRequest;

    function newXHR() {
        const realXHR = new originalXHR();

        realXHR.open = function (method, url, async, user, password) {
            this._url = url;  // 记录请求的 URL
            return originalXHR.prototype.open.apply(this, arguments);
        };

        realXHR.setRequestHeader = function (header, value) {
            let headers = {
                "user-agent": uaString,
                "platform": os.toLowerCase(),
                "app-version": "61",
                "x-app-version": version
            }
            // 如果header在列表中,则修改
            if (header.toLowerCase() in headers) {
                value = headers[header.toLowerCase()];
            } else {
                console.log('header:', header);
            }

            return originalXHR.prototype.setRequestHeader.apply(this, arguments);
        };

        // 拦截响应内容,修改 DownloadUrl 以适应网页端下载
        realXHR.send = function () {
            const xhrInstance = this;
            this.addEventListener('readystatechange', function () {
                let origin_url;
                let new_url_no_redirect;
                let base64data;
                if (xhrInstance.readyState === 4 && xhrInstance.status === 200) {
                    // 解析响应的 JSON
                    let responseText = xhrInstance.responseText;
                    let responseJSON = JSON.parse(responseText);

                    // 修改 DownloadUrl
                    if (responseJSON.data && responseJSON.data.DownloadUrl) {
                        origin_url = responseJSON.data.DownloadUrl;
                        new_url_no_redirect = origin_url + "&auto_redirect=0";
                        base64data = btoa(new_url_no_redirect);
                        responseJSON.data.DownloadUrl = "https://web-pro2.123952.com/download-v2/?params=" + base64data + "&is_s3=0";
                    }

                    // 将修改后的 JSON 转为字符串
                    let modifiedResponseText = JSON.stringify(responseJSON);

                    // 使用 defineProperty 重写 responseText
                    Object.defineProperty(xhrInstance, 'responseText', {
                        get: function () {
                            return modifiedResponseText;
                        }
                    });
                }
            });

            return originalXHR.prototype.send.apply(this, arguments);
        };

        return realXHR;
    }

    window.XMLHttpRequest = newXHR;
})();