Get back missing CN

在 services.sheerid.com 页面的国家列表中找回消失的 CN 选项。

目前为 2025-05-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         Get back missing CN
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  在 services.sheerid.com 页面的国家列表中找回消失的 CN 选项。
// @match        https://services.sheerid.com/verify/681044b7729fba7beccd3565/*
// @grant        none
// @run-at       document-start
// @all-frames   true
// @license      AGPL License
// @author       candy
// ==/UserScript==

(function () {
    'use strict';

    const targetPath = '/rest/v2/program/681044b7729fba7beccd3565/theme';

    // --- Fetch 拦截 ---
    const originalFetch = window.fetch;
    window.fetch = function (...args) {
        const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || '';
        if (url.includes(targetPath)) {
            console.log('[Tampermonkey][fetch] 捕获请求:', url);
        }

        return originalFetch.apply(this, args).then(async response => {
            if (url.includes(targetPath)) {
                try {
                    const clone = response.clone();
                    const json = await clone.json();
                    const countries = json?.config?.countries;

                    if (Array.isArray(countries)) {
                        console.log('[Tampermonkey][fetch] 原始国家列表:', countries);
                        const index = countries.indexOf("PR");
                        if (index !== -1 && !countries.includes("CN")) {
                            countries.splice(index, 0, "CN");
                            console.log('[Tampermonkey][fetch] 插入 CN 成功:', countries);
                        }
                        return new Response(JSON.stringify(json), {
                            status: response.status,
                            statusText: response.statusText,
                            headers: response.headers
                        });
                    }
                } catch (err) {
                    console.error('[Tampermonkey][fetch] 修改失败:', err);
                }
            }
            return response;
        });
    };

    // --- XHR 拦截 ---
    const originalOpen = XMLHttpRequest.prototype.open;
    const originalSend = XMLHttpRequest.prototype.send;

    XMLHttpRequest.prototype.open = function (method, url, ...rest) {
        this._intercept = url.includes(targetPath);
        if (this._intercept) {
            console.log('[Tampermonkey][XHR] 捕获请求:', url);
        }
        return originalOpen.call(this, method, url, ...rest);
    };

    XMLHttpRequest.prototype.send = function (...args) {
        this.addEventListener('readystatechange', function () {
            if (this.readyState === 4 && this._intercept) {
                try {
                    const raw = this.responseText;
                    const json = JSON.parse(raw);
                    const countries = json?.config?.countries;

                    if (Array.isArray(countries)) {
                        console.log('[Tampermonkey][XHR] 原始国家列表:', countries);
                        const index = countries.indexOf("PR");
                        if (index !== -1 && !countries.includes("CN")) {
                            countries.splice(index, 0, "CN");
                            this.__modifiedResponse = JSON.stringify(json);
                            console.log('[Tampermonkey][XHR] 插入 CN 成功:', countries);
                        }
                    }
                } catch (err) {
                    console.error('[Tampermonkey][XHR] 修改失败:', err);
                }
            }
        });

        return originalSend.apply(this, args);
    };

    // Proxy 代理 responseText(部分浏览器支持)
    const originalXHR = window.XMLHttpRequest;
    window.XMLHttpRequest = function () {
        const xhr = new originalXHR();

        return new Proxy(xhr, {
            get(target, prop, receiver) {
                if ((prop === 'responseText' || prop === 'response') && target.__modifiedResponse) {
                    return target.__modifiedResponse;
                }
                const value = target[prop];
                return typeof value === 'function' ? value.bind(target) : value;
            },
            set(target, prop, value) {
                target[prop] = value;
                return true;
            }
        });
    };
})();