模拟苹果设备特性

模拟iOS,iPad OS,Mac OS

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         模拟苹果设备特性
// @namespace    https://mzyxsl.cn/
// @version      1.1
// @description  模拟iOS,iPad OS,Mac OS
// @author       mzyxsl
// @match        https://*hcf2023.top/*
// @grant        none
// @license      GPL-3.0
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // 保存原始属性
    const originalPlatform = navigator.platform;
    const originalVendor = navigator.vendor;
    const originalScreenWidth = screen.width;
    const originalScreenHeight = screen.height;
    const originalDevicePixelRatio = window.devicePixelRatio;
    const originalUserAgentData = navigator.userAgentData;
    const originalCSSSupports = CSS.supports;

    // 设备类型检测函数
    function detectDeviceType() {
        const screenWidth = screen.width;
        const screenHeight = screen.height;
        const maxTouchPoints = navigator.maxTouchPoints || 0;
        const hasTouch = 'ontouchstart' in window;

        // 检测指针类型
        const hasFinePointer = window.matchMedia('(pointer: fine)').matches;
        const hasCoarsePointer = window.matchMedia('(pointer: coarse)').matches;
        const hasHover = window.matchMedia('(hover: hover)').matches;

        // 屏幕尺寸判断
        const minScreenSize = Math.min(screenWidth, screenHeight);
        const maxScreenSize = Math.max(screenWidth, screen.height);
        const aspectRatio = maxScreenSize / minScreenSize;

        console.log('设备检测参数:', {
            screen: `${screenWidth}x${screenHeight} (min: ${minScreenSize})`,
            touchPoints: maxTouchPoints,
            hasTouch: hasTouch,
            finePointer: hasFinePointer,
            coarsePointer: hasCoarsePointer,
            hasHover: hasHover,
            aspectRatio: aspectRatio.toFixed(2)
        });

        // 移动设备特征判断
        const hasMobileFeatures = hasCoarsePointer || !hasHover || hasTouch;

        // 屏幕尺寸和比例判断
        const isPhoneSize = minScreenSize < 768 && aspectRatio >= 1.5;
        const isTabletSize = minScreenSize >= 768 && minScreenSize < 1200;
        const isDesktopSize = minScreenSize >= 1200 || !hasMobileFeatures;

        // 综合判断逻辑
        if (hasMobileFeatures && isPhoneSize) {
            return 'iphone';
        } else if (hasMobileFeatures && isTabletSize) {
            return 'ipad';
        } else if (isDesktopSize || !hasMobileFeatures) {
            return 'mac';
        }

        return 'mac';
    }

    // 苹果设备配置
    const appleProfiles = {
        // iPhone配置
        iphone: {
            name: 'iPhone',
            platform: 'iPhone',
            vendor: 'Apple Inc.',
            webgl: { vendor: 'Apple GPU', renderer: 'Apple Inc.' },
            screen: { width: 390, height: 844 },
            hasSafariPush: false,
            hasTouch: true,
            maxTouchPoints: 5,
            devicePixelRatio: 3,
            userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
            clientHints: {
                platform: 'iOS',
                mobile: true,
                architecture: 'arm',
                model: 'iPhone15,3',
                platformVersion: '17.0'
            }
        },

        // iPad配置
        ipad: {
            name: 'iPad',
            platform: 'iPad',
            vendor: 'Apple Inc.',
            webgl: { vendor: 'Apple GPU', renderer: 'Apple Inc.' },
            screen: { width: 1024, height: 1366 },
            hasSafariPush: false,
            hasTouch: true,
            maxTouchPoints: 5,
            devicePixelRatio: 2,
            userAgent: 'Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
            clientHints: {
                platform: 'iOS',
                mobile: true,
                architecture: 'arm',
                model: 'iPad13,8',
                platformVersion: '17.0'
            }
        },

        // Mac配置
        mac: {
            name: 'Mac',
            platform: 'MacIntel',
            vendor: 'Apple Inc.',
            webgl: { vendor: 'Apple GPU', renderer: 'Apple Inc.' },
            screen: { width: originalScreenWidth, height: originalScreenHeight },
            hasSafariPush: true,
            hasTouch: false,
            maxTouchPoints: 0,
            devicePixelRatio: originalDevicePixelRatio,
            userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15',
            clientHints: {
                platform: 'macOS',
                mobile: false,
                architecture: 'x86',
                model: 'MacBookPro18,3',
                platformVersion: '14.0'
            }
        }
    };

    // 自动检测设备类型
    const detectedDevice = detectDeviceType();
    let currentProfile = appleProfiles[detectedDevice];

    console.log(`🔍 检测结果: ${detectedDevice} -> 伪装成: ${currentProfile.name}`);
    console.log(`📺 屏幕分辨率: ${currentProfile.screen.width}x${currentProfile.screen.height}`);

    // 只伪装必要的属性
    Object.defineProperty(navigator, 'platform', {
        get: () => currentProfile.platform,
        configurable: false
    });

    Object.defineProperty(navigator, 'vendor', {
        get: () => currentProfile.vendor,
        configurable: false
    });

    // 伪装UserAgent
    Object.defineProperty(navigator, 'userAgent', {
        get: () => currentProfile.userAgent,
        configurable: false
    });

    // Client Hints伪装
    function spoofClientHints() {
        if (navigator.userAgentData) {
            Object.defineProperty(navigator, 'userAgentData', {
                get: () => {
                    const original = originalUserAgentData;
                    return {
                        ...original,
                        brands: [
                            {brand: 'Google Chrome', version: '120'},
                            {brand: 'Chromium', version: '120'},
                            {brand: 'Not=A?Brand', version: '24'}
                        ],
                        mobile: currentProfile.clientHints.mobile,
                        platform: currentProfile.clientHints.platform,
                        getHighEntropyValues: function(hints) {
                            return Promise.resolve({
                                architecture: currentProfile.clientHints.architecture,
                                model: currentProfile.clientHints.model,
                                platformVersion: currentProfile.clientHints.platformVersion,
                                fullVersionList: [
                                    {brand: 'Google Chrome', version: '120.0.0.0'},
                                    {brand: 'Chromium', version: '120.0.0.0'},
                                    {brand: 'Not=A?Brand', version: '24.0.0.0'}
                                ]
                            });
                        }
                    };
                },
                configurable: false
            });
        }
    }

    // 拦截Client Hints API请求
    function interceptClientHintsRequests() {
        const originalFetch = window.fetch;
        window.fetch = function(...args) {
            // 如果是Client Hints相关的请求,返回伪造的数据
            if (args[0] && typeof args[0] === 'string' && args[0].includes('/api/client-hints')) {
                return Promise.resolve({
                    ok: true,
                    json: () => Promise.resolve({
                        success: true,
                        serverSupport: {
                            acceptCH: 'Sec-CH-UA-Platform, Sec-CH-UA-Mobile, Sec-CH-UA-Model',
                            acceptCHLifetime: 86400
                        },
                        detectedOS: currentProfile.clientHints.platform,
                        isMobile: currentProfile.clientHints.mobile,
                        hasHighEntropyData: true,
                        clientHints: {
                            platform: currentProfile.clientHints.platform,
                            mobile: currentProfile.clientHints.mobile,
                            architecture: currentProfile.clientHints.architecture,
                            model: currentProfile.clientHints.model,
                            platformVersion: currentProfile.clientHints.platformVersion
                        }
                    })
                });
            }
            return originalFetch.apply(this, args);
        };
    }

   // WebGL渲染器伪装
    function spoofWebGL() {
        try {
            const originalGetParameter = WebGLRenderingContext.prototype.getParameter;

            WebGLRenderingContext.prototype.getParameter = function(parameter) {
                switch(parameter) {
                    case 37446: return currentProfile.webgl.vendor;
                    case 37445: return currentProfile.webgl.renderer;
                    case this.VENDOR: return 'WebKit';
                    case this.RENDERER: return 'WebKit WebGL';
                    default: return originalGetParameter.call(this, parameter);
                }
            };
        } catch (error) {
            console.warn('WebGL伪装失败:', error);
        }
    }

    // 屏幕尺寸和DPI适配
    function spoofScreen() {
        Object.defineProperty(screen, 'width', {
            get: () => currentProfile.screen.width,
            configurable: false
        });

        Object.defineProperty(screen, 'height', {
            get: () => currentProfile.screen.height,
            configurable: false
        });

        // 设备像素比
        Object.defineProperty(window, 'devicePixelRatio', {
            get: () => currentProfile.devicePixelRatio,
            configurable: false
        });
    }

    // 触控特性伪装
    function spoofTouchFeatures() {
        Object.defineProperty(navigator, 'maxTouchPoints', {
            get: () => currentProfile.maxTouchPoints,
            configurable: false
        });

        if (currentProfile.hasTouch) {
            if (!('ontouchstart' in window)) {
                Object.defineProperty(window, 'ontouchstart', {
                    value: null,
                    configurable: false
                });
            }
        } else {
            if ('ontouchstart' in window) {
                delete window.ontouchstart;
            }
        }
    }

    // CSS特性伪装 - iOS/iPadOS WebKit特性检测
    function spoofCSSFeatures() {
        CSS.supports = function(property, value) {
            const isTouchDevice = currentProfile.hasTouch;

            // 处理 iOS/iPadOS 特定的 CSS 特性
            if (property === '-webkit-touch-callout' && value === 'none') {
                return isTouchDevice;
            }

            if (property === '-webkit-overflow-scrolling' && value === 'touch') {
                return isTouchDevice;
            }

            // 处理字符串形式的查询
            if (arguments.length === 1) {
                const condition = property;
                if (condition === '(-webkit-touch-callout: none)') {
                    return isTouchDevice;
                }
                if (condition === '(-webkit-overflow-scrolling: touch)') {
                    return isTouchDevice;
                }
            }

            // 其他情况调用原始方法
            return originalCSSSupports.apply(this, arguments);
        };

        // 确保 CSS.supports 的绑定正确
        Object.defineProperty(CSS, 'supports', {
            value: CSS.supports,
            writable: false,
            configurable: false
        });
    }

    // 媒体查询伪装
    function spoofMediaQueries() {
        const originalMatchMedia = window.matchMedia;

        window.matchMedia = function(query) {
            const isTouchDevice = currentProfile.hasTouch;

            const mediaResults = {
                '(pointer: fine)': !isTouchDevice,
                '(pointer: coarse)': isTouchDevice,
                '(hover: hover)': !isTouchDevice,
                '(hover: none)': isTouchDevice,
                '(-webkit-touch-callout: none)': isTouchDevice,
                '(-webkit-overflow-scrolling: touch)': isTouchDevice,
                '(display-mode: standalone)': false,
                '(orientation: portrait)': currentProfile.screen.height > currentProfile.screen.width,
                '(orientation: landscape)': currentProfile.screen.width > currentProfile.screen.height
            };

            if (mediaResults.hasOwnProperty(query)) {
                return {
                    matches: mediaResults[query],
                    media: query,
                    addListener: () => {},
                    removeListener: () => {},
                    addEventListener: () => {},
                    removeEventListener: () => {}
                };
            }

            return originalMatchMedia.call(this, query);
        };
    }

    // 苹果设备API模拟
    function spoofAppleAPIs() {
        // Apple Pay - 所有苹果设备都支持
        if (!window.ApplePaySession) {
            window.ApplePaySession = {
                canMakePayments: () => true,
                supportsVersion: () => true
            };
        }

        // Safari Push - 仅限macOS
        if (currentProfile.hasSafariPush) {
            if (!window.safari) window.safari = {};
            window.safari.pushNotification = {
                permission: () => ({ permission: 'default' })
            };
        }

        // iOS权限API - 仅限移动设备
        if (currentProfile.hasTouch) {
            if (typeof DeviceMotionEvent !== 'undefined') {
                DeviceMotionEvent.requestPermission = () => Promise.resolve('granted');
            }
            if (typeof DeviceOrientationEvent !== 'undefined') {
                DeviceOrientationEvent.requestPermission = () => Promise.resolve('granted');
            }

            Object.defineProperty(navigator, 'standalone', {
                get: () => false,
                configurable: false
            });
        }
    }

    // 硬件信息伪装
    function spoofHardwareInfo() {
        // 硬件并发数(苹果设备通常有特定核心数)
        Object.defineProperty(navigator, 'hardwareConcurrency', {
            get: () => currentProfile.name === 'iPhone' ? 6 :
                     currentProfile.name === 'iPad' ? 8 : 10,
            configurable: false
        });

        // 设备内存
        if ('deviceMemory' in navigator) {
            Object.defineProperty(navigator, 'deviceMemory', {
                get: () => currentProfile.name === 'iPhone' ? 4 :
                         currentProfile.name === 'iPad' ? 6 : 8,
                configurable: false
            });
        }
    }

    // 初始化伪装
    function initSpoofing() {
        spoofScreen();
        spoofTouchFeatures();
        spoofCSSFeatures();
        spoofMediaQueries();
        spoofClientHints();
        spoofHardwareInfo();
        interceptClientHintsRequests();
        spoofWebGL();
        spoofAppleAPIs();

        console.log(`ℹ️ 户先生说: 这是${currentProfile.name}`);
    }

    // 立即执行
    initSpoofing();

    // 简化控制接口
    window.appleSpoof = {
        getStatus: function() {
            return {
                originalDevice: detectedDevice,
                spoofingAs: currentProfile.name,
                platform: navigator.platform,
                vendor: navigator.vendor,
                screen: `${screen.width}x${screen.height}`,
                maxTouchPoints: navigator.maxTouchPoints,
                hasTouch: 'ontouchstart' in window,
                clientHints: currentProfile.clientHints,
                cssFeatures: {
                    webkitTouchCallout: CSS.supports('-webkit-touch-callout', 'none'),
                    webkitOverflowScrolling: CSS.supports('-webkit-overflow-scrolling', 'touch')
                }
            };
        },

        switchTo: function(deviceType) {
            if (appleProfiles[deviceType]) {
                currentProfile = appleProfiles[deviceType];

                // 如果是Mac,使用真实分辨率
                if (deviceType === 'mac') {
                    currentProfile.screen.width = originalScreenWidth;
                    currentProfile.screen.height = originalScreenHeight;
                    currentProfile.devicePixelRatio = originalDevicePixelRatio;
                }

                initSpoofing();
                return `已切换到: ${currentProfile.name}`;
            }
            return '无效的设备类型';
        },

        redetect: function() {
            const newDevice = detectDeviceType();
            currentProfile = appleProfiles[newDevice];

            if (newDevice === 'mac') {
                currentProfile.screen.width = originalScreenWidth;
                currentProfile.screen.height = originalScreenHeight;
                currentProfile.devicePixelRatio = originalDevicePixelRatio;
            }

            initSpoofing();
            return `重新检测完成: ${newDevice}`;
        },

        restore: function() {
            Object.defineProperty(navigator, 'platform', { get: () => originalPlatform });
            Object.defineProperty(navigator, 'vendor', { get: () => originalVendor });
            Object.defineProperty(navigator, 'userAgent', { get: () => navigator.userAgent });

            try {
                delete screen.width;
                delete screen.height;
                delete window.devicePixelRatio;
                delete navigator.maxTouchPoints;
                delete navigator.hardwareConcurrency;
                if ('deviceMemory' in navigator) delete navigator.deviceMemory;
            } catch (e) {}

            console.log('已恢复原始设备设置');
        }
    };

})();