Greasy Fork

Greasy Fork is available in English.

🔥任何网页下完成🔥ZNDS智能电视论坛全后台自动签到

优化错误提示的跨论坛自动签到

当前为 2025-03-30 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         🔥任何网页下完成🔥ZNDS智能电视论坛全后台自动签到
// @namespace    http://greasyfork.icu/zh-CN/users/690532-xht1810
// @version      1.2.2
// @description  优化错误提示的跨论坛自动签到
// @require      https://cdn.jsdelivr.net/npm/sweetalert2@11
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_openInTab
// @grant        GM_notification
// @connect      www.znds.com
// @match        *://*/*
// @license      MIT
// @noframes
// ==/UserScript==

/* global Swal */
const ZNDS = {
    name: '智能电视论坛',
    domain: 'www.znds.com',
    signURL: 'https://www.znds.com/plugin.php?id=ljdaka:daka&action=msg',
    homeURL: 'https://www.znds.com',
    lastSignKey: 'ZNDS_LAST_SIGN',
    ignoreKey: 'ZNDS_IGNORE',
    cookieKey: 'ZNDS_COOKIE',

    // 核心方法:执行签到(带完整错误恢复)
    async sign() {
        // 1. 检查忽略状态
        if (this.isIgnored()) {
            console.log('[ZNDS] 今日已忽略签到');
            return;
        }

        // 2. 获取formhash(自动重试机制)
        let retry = 0;
        while (retry < 3) {
            const formhash = await this.getFormhash();
            if (!formhash) {
                retry++;
                await new Promise(r => setTimeout(r, 2000));
                continue;
            }

            // 3. 发送签到请求
            const result = await this.sendSignRequest(formhash);
            if (result.success) return this.onSuccess();

            // 4. 处理特定失败情况
            if (result.reason === 'already') {
                this.onAlreadySigned();
                return;
            }

            retry++;
        }

        // 5. 最终失败处理
        this.onFail();
    },

    // 获取formhash(带缓存和自动刷新)
    async getFormhash() {
        // 尝试从缓存获取
        const cachedHash = GM_getValue('ZNDS_FORMHASH');
        if (cachedHash) return cachedHash;

        // 后台获取最新formhash
        const html = await this.fetchPage(this.homeURL);
        const hashMatch = html.match(/formhash=([a-f0-9]{8})/);
        if (hashMatch) {
            GM_setValue('ZNDS_FORMHASH', hashMatch[1]);
            return hashMatch[1];
        }
        return null;
    },

    // 发送签到请求
    async sendSignRequest(formhash) {
        try {
            const url = `${this.signURL}&formhash=${formhash}&inajax=1`;
            const response = await this.fetchPage(url);

            if (response.includes("签到成功")) {
                return { success: true };
            } else if (response.includes("已签到")) {
                return { success: false, reason: 'already' };
            } else {
                return { success: false, reason: 'unknown' };
            }
        } catch (e) {
            return { success: false, reason: 'error' };
        }
    },

    // 通用页面获取
    fetchPage(url) {
        return new Promise(resolve => {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                timeout: 10000,
                onload: (res) => resolve(res.responseText),
                onerror: () => resolve('')
            });
        });
    },

    // 状态检查方法
    isIgnored() {
        const lastIgnore = GM_getValue(this.ignoreKey, 0);
        return new Date().setHours(0,0,0,0) === new Date(lastIgnore).setHours(0,0,0,0);
    },

    // 结果处理方法
    onSuccess() {
        GM_setValue(this.lastSignKey, Date.now());
        GM_notification({
            title: `${this.name}签到成功`,
            text: '积分已到账',
            timeout: 2000
        });
    },

    onAlreadySigned() {
        GM_setValue(this.lastSignKey, Date.now());
        console.log('[ZNDS] 今日已签到');
    },

    onFail() {
        Swal.fire({
            icon: 'error',
            title: `${this.name}签到失败`,
            html: `
                <div style="text-align:left">
                    <b>可能原因:</b>
                    <ul style="padding-left:20px;margin:5px 0">
                        <li>未登录或登录过期</li>
                        <li>网络连接问题</li>
                        <li>网站改版导致脚本失效</li>
                    </ul>
                </div>
            `,
            confirmButtonText: '手动签到',
            cancelButtonText: '今日忽略',
            showCancelButton: true
        }).then(res => {
            if (res.isConfirmed) {
                GM_openInTab(this.homeURL, { active: true });
            } else {
                GM_setValue(this.ignoreKey, Date.now());
            }
        });
    }
};

// ================== 执行逻辑 ==================
(function() {
    'use strict';

    // 1. 每日自动执行
    const lastSign = GM_getValue(ZNDS.lastSignKey, 0);
    const today = new Date().setHours(0,0,0,0);

    if (today > new Date(lastSign).setHours(0,0,0,0)) {
        ZNDS.sign();
    }

    // 2. 定时检查(每6小时)
    setInterval(() => {
        if (today > new Date(lastSign).setHours(0,0,0,0)) {
            ZNDS.sign();
        }
    }, 6 * 1200 * 1000);
})();