ZeroAd: GameDistribution

Production-grade GameDistribution SDK bypass with comprehensive hooks

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

Advertisement:

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

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

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

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

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

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

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

Advertisement:

// ==UserScript==
// @name         ZeroAd: GameDistribution
// @namespace    https://greasyfork.org/users/zeroadv4
// @version      4.0.0
// @description  Production-grade GameDistribution SDK bypass with comprehensive hooks
// @author       ZeroAd Team
// @match        *://*.gamedistribution.com/*
// @match        *://gamedistribution.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // ═══════════════════════════════════════════════════════════════
    // CONFIGURATION
    // ═══════════════════════════════════════════════════════════════
    const CONFIG = {
        DEBUG: true,
        REWARD_DELAY_MIN_MS: 10,
        REWARD_DELAY_MAX_MS: 350,
        MAX_RETRIES: 3,
        RETRY_DELAYS: [50, 150, 450]
    };

    const METRICS = {
        hooksInstalled: 0,
        interceptedCalls: 0,
        failedHooks: 0,
        rewardsGranted: 0
    };

    // ═══════════════════════════════════════════════════════════════
    // UTILITY LAYER
    // ═══════════════════════════════════════════════════════════════
    const log = (...args) => CONFIG.DEBUG && console.log('[ZeroAd:GameDist]', ...args);
    const warn = (...args) => CONFIG.DEBUG && console.warn('[ZeroAd:GameDist]', ...args);
    const error = (...args) => console.error('[ZeroAd:GameDist]', ...args);

    function randomDelay(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }

    function safeDispatchEvent(target, eventName) {
        try {
            target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));
        } catch (e) {
            warn('Event dispatch failed:', eventName, e);
        }
    }

    function safeCallback(fn, ...args) {
        if (typeof fn === 'function') {
            try {
                fn(...args);
            } catch (e) {
                warn('Callback execution failed:', e);
            }
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // HOOK LAYER
    // ═══════════════════════════════════════════════════════════════
    let hookState = {
        GDSdk: false,
        gdsdk: false,
        gdApi: false
    };

    /**
     * Hook GameDistribution SDK
     * Targets: GDSdk, gdsdk, gdApi (all variants observed)
     */
    function hookGDSdk(sdkName) {
        const sdk = window[sdkName];

        if (!sdk || sdk.__zaWrapped) {
            return false;
        }

        try {
            sdk.__zaWrapped = true;

            // Hook showAd method
            if (typeof sdk.showAd === 'function') {
                const originalShowAd = sdk.showAd;

                sdk.showAd = function(type, ...args) {
                    log(`${sdkName}.showAd("${type}") intercepted`);
                    METRICS.interceptedCalls++;

                    const isRewarded = type === 'rewarded' ||
                                     type === 'reward' ||
                                     type === 'rewardedVideo';

                    if (isRewarded) {
                        const delay = randomDelay(
                            CONFIG.REWARD_DELAY_MIN_MS,
                            CONFIG.REWARD_DELAY_MAX_MS
                        );

                        setTimeout(() => {
                            METRICS.rewardsGranted++;
                            safeDispatchEvent(window, 'rewardedComplete');
                            safeDispatchEvent(window, 'rewardGranted');
                            safeDispatchEvent(window, 'adComplete');
                            log(`✅ Reward granted (${delay}ms delay)`);
                        }, delay);
                    }

                    // Always resolve immediately
                    return Promise.resolve(true);
                };

                log(`✓ ${sdkName}.showAd hooked`);
            }

            // Hook requestAd (if exists)
            if (typeof sdk.requestAd === 'function') {
                const originalRequestAd = sdk.requestAd;

                sdk.requestAd = function(type, ...args) {
                    log(`${sdkName}.requestAd("${type}") intercepted`);
                    METRICS.interceptedCalls++;

                    // Extract callbacks from various argument patterns
                    let callbacks = null;
                    for (const arg of args) {
                        if (arg && typeof arg === 'object') {
                            callbacks = arg;
                            break;
                        }
                    }

                    // Trigger callbacks immediately
                    if (callbacks) {
                        if (typeof callbacks.onStart === 'function') {
                            safeCallback(callbacks.onStart);
                        }

                        setTimeout(() => {
                            if (typeof callbacks.onComplete === 'function') {
                                safeCallback(callbacks.onComplete, true);
                            }
                            if (typeof callbacks.onReward === 'function') {
                                safeCallback(callbacks.onReward);
                            }

                            METRICS.rewardsGranted++;
                            safeDispatchEvent(window, 'rewardedComplete');
                        }, randomDelay(CONFIG.REWARD_DELAY_MIN_MS, CONFIG.REWARD_DELAY_MAX_MS));
                    }

                    return Promise.resolve({ success: true });
                };

                log(`✓ ${sdkName}.requestAd hooked`);
            }

            // Hook displayAd (if exists)
            if (typeof sdk.displayAd === 'function') {
                sdk.displayAd = function(type, ...args) {
                    log(`${sdkName}.displayAd("${type}") intercepted`);
                    METRICS.interceptedCalls++;
                    return Promise.resolve(true);
                };
            }

            // Hook hasAdblock to always return false
            if (typeof sdk.hasAdblock === 'function') {
                sdk.hasAdblock = async function() {
                    log(`${sdkName}.hasAdblock() → false`);
                    return false;
                };
            }

            // Hook play method (some games use this)
            if (typeof sdk.play === 'function') {
                const originalPlay = sdk.play;
                sdk.play = function() {
                    log(`${sdkName}.play() called`);
                    try {
                        return originalPlay.apply(this, arguments);
                    } catch (e) {
                        return Promise.resolve();
                    }
                };
            }

            hookState[sdkName] = true;
            METRICS.hooksInstalled++;
            return true;

        } catch (e) {
            error(`Failed to hook ${sdkName}:`, e);
            METRICS.failedHooks++;
            return false;
        }
    }

    /**
     * Attempt to hook all SDK variants
     */
    function hookAllVariants() {
        const variants = ['GDSdk', 'gdsdk', 'gdApi'];
        let anyHooked = false;

        variants.forEach(variant => {
            if (window[variant] && !hookState[variant]) {
                if (hookGDSdk(variant)) {
                    anyHooked = true;
                }
            }
        });

        return anyHooked;
    }

    /**
     * Install property traps for late SDK initialization
     */
    function installTraps() {
        const variants = ['GDSdk', 'gdsdk', 'gdApi'];

        variants.forEach(sdkName => {
            let _sdk = window[sdkName];

            Object.defineProperty(window, sdkName, {
                configurable: true,
                enumerable: true,
                get() {
                    return _sdk;
                },
                set(newValue) {
                    log(`${sdkName} assigned`);
                    _sdk = newValue;

                    if (newValue && !hookState[sdkName]) {
                        hookGDSdk(sdkName);
                    }
                }
            });
        });

        log('✓ Property traps installed for all variants');
    }

    // ═══════════════════════════════════════════════════════════════
    // ORCHESTRATION LAYER
    // ═══════════════════════════════════════════════════════════════
    let retryCount = 0;

    function attemptHooks() {
        const hooked = hookAllVariants();

        if (hooked) {
            log('✅ SDK hooked successfully');
            return true;
        }

        if (retryCount < CONFIG.MAX_RETRIES) {
            const delay = CONFIG.RETRY_DELAYS[retryCount];
            retryCount++;

            log(`Retry ${retryCount}/${CONFIG.MAX_RETRIES} in ${delay}ms`);
            setTimeout(attemptHooks, delay);
        } else {
            log('⚠ Max retries reached. Traps remain active.');
        }

        return false;
    }

    /**
     * Setup mutation observer for SDK script detection
     */
    function setupMutationObserver() {
        const observer = new MutationObserver((mutations) => {
            for (const mutation of mutations) {
                for (const node of mutation.addedNodes) {
                    if (node.tagName === 'SCRIPT') {
                        const src = node.src || '';
                        if (src.includes('gamedistribution') || src.includes('gdsdk')) {
                            log('GD SDK script detected:', src.substring(0, 80));

                            node.addEventListener('load', () => {
                                log('SDK loaded, re-attempting hooks');
                                setTimeout(attemptHooks, 50);
                            });
                        }
                    }
                }
            }
        });

        if (document.documentElement) {
            observer.observe(document.documentElement, {
                childList: true,
                subtree: true
            });
        }

        log('✓ MutationObserver active');
    }

    // ═══════════════════════════════════════════════════════════════
    // INITIALIZATION
    // ═══════════════════════════════════════════════════════════════
    function initialize() {
        log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        log('ZeroAd: GameDistribution v4.0.0');
        log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');

        installTraps();
        attemptHooks();
        setupMutationObserver();

        // Expose metrics
        window._zaMetrics = window._zaMetrics || {};
        window._zaMetrics.gamedistribution = METRICS;

        // Status report
        setTimeout(() => {
            log('━━━ Status Report ━━━');
            log('Hook state:', hookState);
            log('Metrics:', METRICS);
            log('━━━━━━━━━━━━━━━━━━━━━');
        }, 5000);
    }

    // Run immediately
    initialize();

    // Defensive: re-run on DOM ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', attemptHooks);
    }

})();