ZeroAd: Loader

Event‑driven loader for ZeroAd platform scripts (now with Yandex Games)

2026/08/22のページです。最新版はこちら

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         ZeroAd: Loader
// @namespace    https://greasyfork.org/en/users/1483567-vujohn123
// @version      4.2.0
// @description  Event‑driven loader for ZeroAd platform scripts (now with Yandex Games)
// @author       ZeroAd Team
// @match        *://*/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

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

    const SCRIPT_MAP = {
        'poki': 579407,
        'crazygames': 579404,
        'adinplay': 579403,
        'gamevui': 579405,
        'unity': 583938,
        'gamedistribution': 583939,
        'playgama': 592446,
        'yandex': 592456   // ← ZeroAd: Yandex Games
    };

    const FALLBACK_PLATFORM = 'adinplay';
    const loaded = new Set();
    const pending = new Set();

    function loadScriptWithRetry(platformKey, retries = 5, delay = 100) {
        const platform = SCRIPT_MAP[platformKey];
        if (!platform || loaded.has(platformKey) || pending.has(platformKey)) return;
        pending.add(platformKey);

        const url = `https://greasyfork.org/scripts/${platform}/code/${platform}.user.js`;
        const script = document.createElement('script');

        const tryLoad = (attempt) => {
            script.onload = () => {
                loaded.add(platformKey);
                pending.delete(platformKey);
                console.log(`[ZeroAd] ✅ Loaded ${platformKey}`);
            };
            script.onerror = () => {
                if (attempt < retries) {
                    const nextDelay = delay * Math.pow(2, attempt);
                    console.warn(`[ZeroAd] ⚠️ Retry ${platformKey} in ${nextDelay}ms (attempt ${attempt+1}/${retries})`);
                    setTimeout(() => tryLoad(attempt + 1), nextDelay);
                } else {
                    pending.delete(platformKey);
                    console.error(`[ZeroAd] ❌ Failed to load ${platformKey} after ${retries} attempts`);
                }
            };
            script.src = url;
            (document.head || document.documentElement).appendChild(script);
        };
        tryLoad(0);
    }

    function detectPlatforms() {
        const detected = new Set();
        const host = window.location.hostname.toLowerCase();
        if (host.includes('poki.com')) detected.add('poki');
        if (host.includes('crazygames.com')) detected.add('crazygames');
        if (host.includes('gamevui.vn')) detected.add('gamevui');
        if (host.includes('gamedistribution.com')) detected.add('gamedistribution');
        if (host.includes('playgama.com')) detected.add('playgama');
        if (host.includes('yandex') || host.includes('games.yandex')) detected.add('yandex');
        if (window.unityInstance || window.gameInstance || window.UnityLoader || document.querySelector('canvas.unity-canvas')) detected.add('unity');
        if (detected.size === 0) detected.add(FALLBACK_PLATFORM);
        return detected;
    }

    function installGlobalTrap() {
        const sdkNames = [
            'PokiSDK', 'CrazyGames', 'CrazygamesAds', 'GVAdBreak',
            'GDSdk', 'gdApi', 'unityInstance', 'gameInstance',
            'PlayGama', 'playgama', 'pg', 'PG',
            'ysdk', 'YaGames'   // ← Yandex Games SDK
        ];
        sdkNames.forEach(name => {
            let _value = window[name];
            Object.defineProperty(window, name, {
                configurable: true, enumerable: true,
                get() { return _value; },
                set(newVal) {
                    _value = newVal;
                    const detected = detectPlatforms();
                    detected.forEach(key => {
                        if (!loaded.has(key) && !pending.has(key)) loadScriptWithRetry(key);
                    });
                }
            });
        });
    }

    function setupObserver() {
        const observer = new MutationObserver(mutations => {
            let shouldCheck = false;
            for (const m of mutations) {
                for (const node of m.addedNodes) {
                    if (node.tagName === 'SCRIPT') { shouldCheck = true; break; }
                }
            }
            if (shouldCheck) {
                const detected = detectPlatforms();
                detected.forEach(key => {
                    if (!loaded.has(key) && !pending.has(key)) loadScriptWithRetry(key);
                });
            }
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });
    }

    function init() {
        installGlobalTrap();
        setupObserver();
        const initial = detectPlatforms();
        initial.forEach(key => {
            if (!loaded.has(key) && !pending.has(key)) loadScriptWithRetry(key);
        });
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => {
                const later = detectPlatforms();
                later.forEach(key => loadScriptWithRetry(key));
            });
        }
    }

    if (document.head) init();
    else {
        const obs = new MutationObserver(() => {
            if (document.head) { obs.disconnect(); init(); }
        });
        obs.observe(document.documentElement, { childList: true, subtree: true });
    }
})();