在 Zod 首页添加一键签到/赚分按钮
// ==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()
})();