ZeroAd: Poki

Instant, zero-delay Poki SDK bypass with bulletproof hook

Version au 21/08/2026. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

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

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         ZeroAd: Poki
// @namespace    https://greasyfork.org/en/users/1483567-vujohn123
// @version      4.0.4
// @description  Instant, zero-delay Poki SDK bypass with bulletproof hook
// @author       ZeroAd Team
// @match        *://*.poki.com/*
// @match        *://poki.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    if (window.__zaPokiLoaded) return;
    window.__zaPokiLoaded = true;

    const CONFIG = { DEBUG: true };  // Set false to disable logs
    const METRICS = {
        hooksInstalled: 0,
        interceptedCalls: 0,
        failedHooks: 0,
        rewardsGranted: 0
    };

    const log = (...args) => CONFIG.DEBUG && console.log('[ZeroAd:Poki]', ...args);
    const warn = (...args) => CONFIG.DEBUG && console.warn('[ZeroAd:Poki]', ...args);
    const error = (...args) => console.error('[ZeroAd:Poki]', ...args);

    // --- Hook functions (same as before) ---
    function safeDispatchEvent(target, eventName) {
        try { target.dispatchEvent(new CustomEvent(eventName, { bubbles: true })); } catch (e) {}
    }
    function safeCallback(fn, ...args) {
        if (typeof fn === 'function') {
            try { fn(...args); } catch (e) { warn('Callback error:', e); }
        }
    }

    function hookPokiSDK(sdk) {
        if (!sdk || sdk.__zaHooked) return false;
        log('Hooking PokiSDK...');

        try {
            sdk.__zaHooked = true;

            // commercialBreak
            if (typeof sdk.commercialBreak === 'function') {
                sdk.commercialBreak = function(...args) {
                    log('🚫 commercialBreak skipped');
                    METRICS.interceptedCalls++;
                    if (args.length && typeof args[0] === 'function') try { args[0](); } catch(e) {}
                    return Promise.resolve();
                };
                log('✅ commercialBreak hooked');
            }

            // rewardedBreak
            if (typeof sdk.rewardedBreak === 'function') {
                sdk.rewardedBreak = function(callbacks) {
                    log('🎁 rewardedBreak → instant reward');
                    METRICS.interceptedCalls++;
                    let onStart = null, onReward = null, onError = null;
                    if (typeof callbacks === 'function') {
                        onReward = callbacks;
                    } else if (callbacks && typeof callbacks === 'object') {
                        onStart = callbacks.onStart || callbacks.start;
                        onReward = callbacks.adFinished || callbacks.onComplete || callbacks.onReward || callbacks.complete;
                        onError = callbacks.onError || callbacks.error;
                    }
                    safeCallback(onStart);
                    safeCallback(onReward);
                    safeCallback(onError, null);
                    METRICS.rewardsGranted++;
                    safeDispatchEvent(window, 'rewardedComplete');
                    safeDispatchEvent(window, 'rewardGranted');
                    safeDispatchEvent(window, 'adComplete');
                    log('✅ Reward granted instantly');
                    return Promise.resolve(true);
                };
                log('✅ rewardedBreak hooked');
            }

            // display ads
            if (typeof sdk.hoistDisplayAd === 'function') {
                sdk.hoistDisplayAd = () => { METRICS.interceptedCalls++; return false; };
            }
            if (typeof sdk.destroyDisplayAd === 'function') {
                sdk.destroyDisplayAd = () => { METRICS.interceptedCalls++; };
            }
            if (typeof sdk.displayAd === 'function') {
                sdk.displayAd = (e, t, o, i) => {
                    METRICS.interceptedCalls++;
                    if (i) safeCallback(i, true);
                    if (o) safeCallback(o);
                    return false;
                };
            }
            if (typeof sdk.destroyAd === 'function') {
                sdk.destroyAd = () => { METRICS.interceptedCalls++; };
            }

            // playground/platform breaks
            ['playgroundCommercialBreak', 'platformCommercialBreak'].forEach(m => {
                if (typeof sdk[m] === 'function') {
                    sdk[m] = () => { log(m + ' skipped'); METRICS.interceptedCalls++; return Promise.resolve(); };
                }
            });

            // monetization internals
            if (sdk.__monetization) {
                if (typeof sdk.__monetization.requestAd === 'function') sdk.__monetization.requestAd = () => Promise.resolve();
                if (typeof sdk.__monetization.displayAd === 'function') sdk.__monetization.displayAd = () => false;
                if (typeof sdk.__monetization.init === 'function') sdk.__monetization.init = () => Promise.resolve();
            }

            // no-op tracking
            ['happyTime','gameLoading','gameplayStart','gameplayStop','captureError','sendEvent','track','setDebug','measure','gameLoadingFinished','gameLoadingProgress','gameInteractive','logError','muteAd','roundEnd','roundStart','sendHighscore','setLogging','setPlayerAge','enableEventTracking','openExternalLink'].forEach(m => {
                if (typeof sdk[m] === 'function') {
                    sdk[m] = (...args) => {
                        if (m === 'gameplayStart' || m === 'gameplayStop') log(m + ' tracked (no-op)');
                        else log(m + ' no-op');
                    };
                }
            });

            METRICS.hooksInstalled++;
            log('✅ PokiSDK hooked successfully!');
            return true;
        } catch (e) {
            error('Hook failed:', e);
            METRICS.failedHooks++;
            return false;
        }
    }

    // --- BULLETPROOF TRAP: non-configurable property descriptor ---
    function installBulletproofTrap() {
        let _pokiSDK = window.PokiSDK;

        // If the SDK already exists, hook it and use it as the stored value.
        if (_pokiSDK && !_pokiSDK.__zaHooked) {
            hookPokiSDK(_pokiSDK);
        }

        // Define a non-configurable property that can't be overwritten.
        Object.defineProperty(window, 'PokiSDK', {
            configurable: false,   // Prevents any redefinition
            enumerable: true,
            get: function() {
                log('PokiSDK GET');
                return _pokiSDK;
            },
            set: function(newValue) {
                log('PokiSDK SET (new SDK)');
                _pokiSDK = newValue;
                if (newValue && !newValue.__zaHooked) {
                    hookPokiSDK(newValue);
                }
            }
        });

        log('✅ Bulletproof trap installed (non-configurable)');
    }

    // --- Fallback observers (just in case) ---
    function setupObserver() {
        const observer = new MutationObserver(mutations => {
            for (const mutation of mutations) {
                for (const node of mutation.addedNodes) {
                    if (node.tagName === 'SCRIPT') {
                        const src = (node.src || '').toLowerCase();
                        if (src.includes('poki') && (src.includes('sdk') || src.includes('hoist') || src.includes('playground') || src.includes('v2'))) {
                            log('SDK script detected:', src.substring(0, 80));
                            if (node.readyState === 'complete' || node.readyState === 'loaded') {
                                setTimeout(() => {
                                    if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                                        hookPokiSDK(window.PokiSDK);
                                    }
                                }, 0);
                            } else {
                                node.addEventListener('load', () => {
                                    setTimeout(() => {
                                        if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                                            hookPokiSDK(window.PokiSDK);
                                        }
                                    }, 0);
                                });
                            }
                        }
                    }
                }
            }
        });
        if (document.documentElement) {
            observer.observe(document.documentElement, { childList: true, subtree: true });
        }
        log('✅ MutationObserver active');
    }

    function startRetry() {
        let attempts = 0;
        const maxAttempts = 100;
        const interval = setInterval(() => {
            attempts++;
            if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                log('Retry attempt ' + attempts + ' - hooking SDK');
                hookPokiSDK(window.PokiSDK);
            }
            if (attempts >= maxAttempts || (window.PokiSDK && window.PokiSDK.__zaHooked)) {
                clearInterval(interval);
                if (window.PokiSDK && window.PokiSDK.__zaHooked) {
                    log('✅ SDK hooked via retry');
                } else {
                    warn('⚠️ SDK not found after retries');
                }
            }
        }, 50);
    }

    // --- Global reference cleanup (scans for cached SDK references) ---
    function scanAndReplaceCachedReferences() {
        // This is a sledgehammer approach: look at all properties of `window`
        // and if any of them point to the original SDK object, replace them with our hooked version.
        // We only do this once, after the SDK is known to be hooked.
        setTimeout(() => {
            if (!window.PokiSDK || !window.PokiSDK.__zaHooked) return;
            const hooked = window.PokiSDK;
            // We need a way to detect the original object. We'll check if a property has the same methods as the hooked one, but it's tricky.
            // Instead, we can look for properties that are objects and have a `rewardedBreak` function that is not our hooked one.
            for (let key in window) {
                try {
                    const val = window[key];
                    if (val && typeof val === 'object' && val !== hooked && typeof val.rewardedBreak === 'function' && val !== window.PokiSDK) {
                        // Check if it's the original by seeing if its `rewardedBreak` is the same as the original?
                        // We can't easily compare, but we can check if it has `__zaHooked` flag – if not, it's likely the original.
                        if (!val.__zaHooked) {
                            log('Found cached reference: window.' + key + ' – replacing with hooked version');
                            try {
                                window[key] = hooked;
                            } catch(e) {}
                        }
                    }
                } catch(e) {}
            }
        }, 1000);
    }

    // --- Initialization ---
    function initialize() {
        log('🚀 ZeroAd: Poki SDK v4.0.4 – Bulletproof');
        installBulletproofTrap();
        setupObserver();
        startRetry();
        scanAndReplaceCachedReferences();

        window._zaMetrics = window._zaMetrics || {};
        window._zaMetrics.poki = METRICS;

        setTimeout(() => {
            log('📊 Status:', {
                hookState: !!(window.PokiSDK && window.PokiSDK.__zaHooked),
                metrics: METRICS
            });
        }, 5000);
    }

    initialize();

    // Additional safety: on DOMContentLoaded, re-scan and hook if not yet.
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                hookPokiSDK(window.PokiSDK);
            }
            scanAndReplaceCachedReferences();
        });
    }
})();