动画疯自动同意年龄确认,移除广告跳转,广告静音,自动点击跳过广告

能够动画疯自动同意年龄确认,移除广告跳转,广告静音,自动点击跳过广告……安装即可,自动执行

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         动画疯自动同意年龄确认,移除广告跳转,广告静音,自动点击跳过广告
// @namespace    http://tampermonkey.net/
// @version      2.0
// @license MIT
// @description  能够动画疯自动同意年龄确认,移除广告跳转,广告静音,自动点击跳过广告……安装即可,自动执行
// @author       XLXZ
// @match        https://ani.gamer.com.tw/animeVideo.php?sn=*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gamer.com.tw
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
    //-配置项
    // 是否需要移除广告跳转链接?
    let ifRemoveAdsJump = true;
    // 广告期间是否静音?
    let ifMuteDuringAd = true;
    // 广告持续时间?
    let adDuringTime = 30;


    //-函数调用
    function removeAdsJump() {
        const vastBlocker = document.querySelector('.vast-blocker');
        if (vastBlocker) {
            vastBlocker.remove();
            console.log('移除广告跳转');
            return true;
        } else {
            console.log('没有广告跳转');
            return false;
        }
    }

    function skipAds() {
        const skipButton = document.querySelector('#adSkipButton');
        if (skipButton && skipButton.classList.contains('enable')) {
            skipButton.click();
            console.log('跳过广告');
            return true;
        } else {
            return false;
        }
    }

    function checkAds() {
        const skipButton = document.querySelector('#adSkipButton');
        if (!skipButton) {
            console.log('没有广告');
            return false;
        }
        return true;
    }

    function muteAds() {
        const muteButton = document.querySelector('.vjs-mute-control.vjs-control.vjs-button');
        if (muteButton) {
            if (!muteButton.classList.contains('vjs-vol-0')) {
                muteButton.click();
            }
            else {
                console.log('已经静音了');
                return true;
            }
            console.log('广告静音');
            return true;
        } else {
            console.log('没有静音按钮');
            return false;
        }
    }

    function unmuteAds() {
        const muteButton = document.querySelector('.vjs-mute-control.vjs-control.vjs-button');
        if (muteButton) {
            if (muteButton.classList.contains('vjs-vol-0')) {
                muteButton.click();
            }
            else {
                console.log('已经取消静音了');
                return true;
            }
            console.log('取消静音');
            return true;
        } else {
            console.log('没有静音按钮');
            return false;
        }
    }

    function agreeAge() {
        const adultButton = document.querySelector('#adult');
        if (adultButton) {
            adultButton.click();
            console.log('同意年龄确认');
            return true;
        } else {
            console.log('没有年龄确认按钮');
            return false;
        }
    }

    let timers = [];
    function tryUntillSuccess(func, timeout, functionName = "未知函数", interval = 20) {
        let successFunc;
        let failFunc;
        const timer = setInterval(() => {
            if (func()) {
                clearInterval(timer);
                // 同时也要清除超时计时器
                clearTimeout(timeOut);
                console.log('成功执行' + functionName);
                if (successFunc) successFunc();
            }
        }, interval);
        timers.push(timer);

        const timeOut = setTimeout(() => {
            clearInterval(timer);
            console.log(functionName + '执行超时,停止尝试');
            if (failFunc) failFunc();
        }, timeout);
        timers.push(timeOut);

        return {
            onSuccess: (func) =>{
                successFunc = func;
            },
            onFail:(func)=>{
                failFunc = func;
            }
        }
    }

    function clearAllTimers() {
        timers.forEach(timer => {
            clearInterval(timer);
            clearTimeout(timer); // 对于setTimeout和setInterval都有效
        });
        timers = [];
        console.log('所有计时器已清除');
    }


    //- 程序核心入口
    const handleChange = (mutationsList, observer) => {
        console.log(`类属性变化了,应该是剧集发生变化,重新加载脚本……`);
        clearAllTimers();

        // 开启新的监控
        tryUntillSuccess(startObserve,2000,"监控剧集变化")


        tryUntillSuccess(agreeAge, 2000, "同意年龄确认");

        if (ifRemoveAdsJump) {
            tryUntillSuccess(removeAdsJump, 2000, "移除广告跳转");
        }
        if (ifMuteDuringAd) {
            tryUntillSuccess(checkAds, 2000, "检查是否有广告并且静音").onSuccess(()=>{tryUntillSuccess(muteAds, 2000, "广告静音")});
        }

        // 防止被错误判定这里在1s后再做一个补充判定
        const reCheckAds = setTimeout(() => {
            if (!checkAds()) {
                tryUntillSuccess(unmuteAds, 1000, "取消静音");
            }
        }, 1000);
        timers.push(reCheckAds);

        // XXs后尝试跳过广告
        const skipAdsTimer = setTimeout(() => {
            console.log(adDuringTime + '秒到了,尝试跳过广告');
            tryUntillSuccess(skipAds, 5000, "跳过广告", 100).onSuccess(()=>{tryUntillSuccess(unmuteAds, 2000, "跳过广告后取消静音")});
        }, adDuringTime * 1000)
        timers.push(skipAdsTimer);
    };


    // 创建一个观察者实例并传入回调函数
    const observer = new MutationObserver(handleChange);

    // 指定要监控的配置选项(这里是属性变化)
    const config = { attributes: true, attributeFilter: ['class'] };

    // 选择目标节点
    let targetNode = document.querySelector('.playing');
    console.log(targetNode ? '找到剧集元素' : '未找到剧集元素');

    // 开始监控目标节点
    function startObserve() {
        //停止之前的观察
        observer?.disconnect();
        // 选择目标节点
        targetNode = document.querySelector('.playing');
        if (targetNode) {
            observer.observe(targetNode, config);
            console.log('找到剧集元素')
            return true;
        } else {
            console.log('未找到剧集元素');
            return false;
        }
    }

    // 如果失败就直接运行主程序
    // 失败是因为找不到监控节点,这可能是因为单个剧集造成的
    // 如果失败 -> 单个剧集 -> 不存在剧集切换 -> 无需监控,只跑一次
    tryUntillSuccess(startObserve,2000,"监控剧集变化").onFail(handleChange);
})();