ZodGame 一键签到/赚分

在 Zod 首页添加一键签到/赚分按钮

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

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

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

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!)

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!)

// ==UserScript==
// @name         ZodGame 一键签到/赚分
// @namespace    https://greasyfork.org/zh-CN/users/309232-3989364
// @version      2025-08-31
// @description  在 Zod 首页添加一键签到/赚分按钮
// @author       ctrn43062
// @match        https://zodgame.xyz/
// @match        https://zodgame.xyz/index.php
// @icon         https://www.google.com/s2/favicons?sz=64&domain=zodgame.xyz
// @grant        none
// @license      MIT
// ==/UserScript==

const parseDOMFromString = (text) => {
    const parser = new DOMParser()
    return parser.parseFromString(text, 'text/html')
}

const getPageDOM = async (url, params) => {
    const resp = await fetch(url, params)
    const text = await resp.text()

    return parseDOMFromString(text)
}

/**
* 执行签到,返回签到结果
*/
const doSign = async () => {
    const dom = await getPageDOM('plugin.php?id=dsu_paulsign:sign')
    const formhash = document.querySelector('#scbar_form input[name="formhash"]').value

    const formData = new FormData()
    formData.append('formhash', formhash)
    formData.append('qdxq', 'fd')

    const api = `plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1`

    const resp = await fetch(api, {
        method: 'POST',
        body: formData,
    })

    const text = await resp.text()

    return parseDOMFromString(text).querySelector('.c').textContent.trim()
}

const sleep = (ms) => {
    return new Promise(resolve => {
        setTimeout( () => resolve(), ms)
    }
                      )
}

/**
* 点击赚分
*/
const getAdUrlList = async () => {
    const dom = await getPageDOM('plugin.php?id=jnbux')
    // 获取任务列表
    const taskElementList = Array.from(dom.querySelectorAll("#wp tr > td:last-child > a") || [])

    if (!taskElementList.length) {
        return []
    }

    const openWindowFnNameList = taskElementList.map(el => el.getAttribute('onclick').toString().match(/(open\w+)/)).filter(s => s).map(s => s[1])

    if (!openWindowFnNameList.length) {
        throw '无法获取打开新窗口函数名'
    }

    // 获取脚本中打开新窗口的代码文本
    const openWindowFnCodeList = [...dom.querySelectorAll('script')].map(el => el.textContent).filter(text => openWindowFnNameList.some(name => text.match(new RegExp(`function ${name}`))))

    // 获取广告 url
    const adUrlList = openWindowFnCodeList.map(s => s.match(/window\.open\("(.+?)"\)?/)[1])

    return adUrlList
}

const watchAD = async (adUrl) => {
    return new Promise( (resolve, reject) => {
        const iframe = document.createElement('iframe')
        iframe.src = adUrl

        iframe.sandbox.add('allow-same-origin')
        iframe.sandbox.add('allow-scripts')

        Object.assign(iframe.style, {
            display: 'none'
        })

        iframe.addEventListener('load', async () => {
            for (let cnt = 0; cnt < 200; cnt++) {
                const selector = (iframe.contentDocument || iframe.contentWindow.document)

                if (selector) {
                    const status = selector.querySelector('.jnbux_hd')

                    if (status && status.textContent.includes('成功')) {
                        iframe.remove()
                        // 执行成功回调
                        return resolve()
                    }
                }

                await sleep(500)
            }

            reject('任务超时')
        }
                               )

        document.documentElement.appendChild(iframe)
    }
                      )
}

const messages = []

function writeLog(message, logEl, append=true) {
    console.info(message)
    if (logEl) {
        if (append) {
            logEl.textContent += message + '\n\n'
        } else {
            logEl.textContent = message
        }
    }
}

async function main() {
    const initLogger = () => {
        if (typeof showDialog == 'function') {
            window.showDialog('', 'notice')
            const dialogContentEl = document.querySelector('#fwin_dialog .alert_info')

            Object.assign(dialogContentEl.style, {
                'white-space': 'break-spaces',
                'word-break': 'break-all'
            })

            return (message) => writeLog(message, dialogContentEl, true)
        } else {
            alert('点击确认按钮开始执行任务,F12 打开控制台查看执行结果')
            return writeLog
        }
    }

    const writeLogDefault = initLogger()
    writeLogDefault('* 此窗口关闭后可在控制台查看执行过程;观看广告任务开始后请勿刷新页面导致无法获取奖励')

    writeLogDefault('开始签到:')
    writeLogDefault(await doSign())

    writeLogDefault('开始获取点击赚分任务列表:')
    debugger
    const adUrlList = await getAdUrlList()

    if (adUrlList.length) {
        let no = 1
        for (const url of adUrlList) {
            writeLogDefault('观看广告: ' + no)
            await watchAD(url)
            no++
        }
    } else {
        writeLogDefault('未找到可观看广告/所有任务已完成')
    }

    writeLogDefault('任务完成,请关闭该窗口')
}

function createOperationButton() {
    const qmenu = document.querySelector('#qmenu')
    const btn = document.createElement('a')
    btn.id = 'qmenu'
    btn.innerText = `一键签到/赚分`
    btn.href = '#'

    qmenu.parentElement.insertBefore(btn, qmenu)

    btn.addEventListener('click', async (e) => {
        e.preventDefault()
        await main()
    })
}


(function() {
    'use strict';
    createOperationButton()
})();