ZeroAd: GameDistribution

Production-grade GameDistribution SDK bypass with comprehensive hooks

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey, Greasemonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

You will need to install an extension such as Tampermonkey to install this script.

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

Advertisement:

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

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);
    }

})();