Greasy Fork is available in English.

朱雀自动转盘抽奖及统计

实现朱雀的抽奖功能,自动获取CSRF Token与Cookie,并显示抽奖结果,支持进度显示和停止功能

// ==UserScript==
// @name         朱雀自动转盘抽奖及统计
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  实现朱雀的抽奖功能,自动获取CSRF Token与Cookie,并显示抽奖结果,支持进度显示和停止功能
// @author       banner
// @match        https://zhuque.in/*
// @grant        none
// @run-at       document-end
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 定义奖品信息和对应价值
    const prizeMap = {
        "1": { "Name": "一等奖: 改名卡", "Value": 240000 },
        "2": { "Name": "二等奖: 神佑(VIP) 7 天卡", "Value": 80000 },
        "3": { "Name": "三等奖: 邀请卡", "Value": 64000 },
        "4": { "Name": "四等奖: 自动释放技能道具卡 7 天卡", "Value": 24000 },
        "5": { "Name": "五等奖: 上传 20 GiB", "Value": 2280 },
        "6": { "Name": "六等奖: 上传 10 GiB", "Value": 1140 },
        "7": { "Name": "未中奖", "Value": 0 }
    };

    // 全局状态变量
    let isRunning = false;
    let stopRequested = false;
    let totalCost = 0;
    let totalValue = 0;
    let prizeSummary = {};

    // 初始化奖品统计
    function resetStats() {
        totalCost = 0;
        totalValue = 0;
        prizeSummary = {};
        Object.keys(prizeMap).forEach(prizeId => {
            prizeSummary[prizeId] = { "Count": 0, "TotalValue": 0 };
        });
    }

    // 创建UI界面
    function createUI() {
        setTimeout(() => {
            const container = document.createElement('div');
            container.style.position = 'fixed';
            container.style.top = '10px';
            container.style.right = '10px';
            container.style.backgroundColor = '#fff';
            container.style.padding = '20px';
            container.style.border = '1px solid #ccc';
            container.style.boxShadow = '0px 4px 8px rgba(0,0,0,0.1)';
            container.style.zIndex = '9999';

            const title = document.createElement('h3');
            title.textContent = '抽奖统计';
            container.appendChild(title);

            // 输入区域
            const inputContainer = document.createElement('div');
            inputContainer.style.margin = '10px 0';

            // 抽奖次数输入
            const timesDiv = document.createElement('div');
            timesDiv.style.marginBottom = '10px';
            timesDiv.innerHTML = '<label>抽奖次数: </label><input type="number" value="60" min="1" style="width: 80px;">';
            inputContainer.appendChild(timesDiv);

            // 间隔时间输入
            const intervalDiv = document.createElement('div');
            intervalDiv.style.marginBottom = '10px';
            intervalDiv.innerHTML = '<label>间隔(ms): </label><input type="number" value="300" min="0" style="width: 80px;">';
            inputContainer.appendChild(intervalDiv);

            container.appendChild(inputContainer);

            // 控制按钮
            const button = document.createElement('button');
            button.textContent = '开始抽奖';
            button.style.margin = '10px 0';
            container.appendChild(button);

            // 结果显示区域
            const resultContainer = document.createElement('div');
            resultContainer.style.marginTop = '20px';
            resultContainer.style.borderTop = '1px solid #ccc';
            resultContainer.style.paddingTop = '10px';
            container.appendChild(resultContainer);

            document.body.appendChild(container);

            // 事件监听
            button.addEventListener('click', async () => {
                if (isRunning) {
                    stopRequested = true;
                    return;
                }

                const timesInput = timesDiv.querySelector('input');
                const intervalInput = intervalDiv.querySelector('input');

                const requestTimes = parseInt(timesInput.value) || 10;
                const interval = parseInt(intervalInput.value) || 1000;

                if (requestTimes < 1) {
                    alert('抽奖次数至少为1次');
                    return;
                }

                if (interval < 300) {
                    alert('为了避免给站点服务器带来较大负荷,不建议300ms一下的间隔,建议将间隔时长调制500ms以上');
                    return;
                }

                isRunning = true;
                stopRequested = false;
                button.textContent = '停止抽奖';
                resetStats();

                resultContainer.innerHTML = `
                    <div class="status">准备中...</div>
                    <div class="progress">当前进度: 0/${requestTimes}</div>
                    <div class="results"></div>
                `;

                try {
                    for (let i = 1; i <= requestTimes; i++) {
                        if (stopRequested) break;

                        await sendRequest();
                        await new Promise(r => setTimeout(r, interval));

                        // 更新进度显示
                        resultContainer.querySelector('.progress').textContent =
                            `当前进度: ${i}/${requestTimes}`;
                    }
                } finally {
                    isRunning = false;
                    button.textContent = '开始抽奖';
                    updateResults(resultContainer);
                }
            });
        }, 1000);  // 延迟1秒执行UI创建
    }

    // 发送抽奖请求
    async function sendRequest() {
        try {
            const response = await fetch("https://zhuque.in/api/gaming/spinThePrizeWheel", {
                method: "POST",
                headers: {
                    "X-Csrf-Token": document.querySelector('meta[name="x-csrf-token"]').content,
                    "Cookie": document.cookie
                }
            });

            if (response.ok) {
                const data = await response.json();
                const prizeId = String(data.data.prize);

                if (prizeMap[prizeId]) {
                    prizeSummary[prizeId].Count++;
                    prizeSummary[prizeId].TotalValue += prizeMap[prizeId].Value;
                    totalCost += 1500;
                    totalValue += prizeMap[prizeId].Value;
                }
            }
        } catch (error) {
            console.error('请求失败:', error);
        }
    }

    // 更新结果展示
    function updateResults(container) {
        let html = '<h4>抽奖结果:</h4>';

        // 按价值降序排列
        const sorted = Object.entries(prizeMap)
        .sort((a, b) => b[1].Value - a[1].Value)
        .forEach(([id, prize]) => {
            const count = prizeSummary[id].Count;
            html += `${prize.Name}: ${count}次 (价值 ${prizeSummary[id].TotalValue}灵石)<br>`;
        });

        html += `<br>总消耗: ${totalCost}灵石<br>`;
        html += `总价值: ${totalValue}灵石<br>`;
        html += `<b>净${totalValue >= totalCost ? '盈利' : '亏损'}: ${Math.abs(totalValue - totalCost)}灵石</b>`;

        container.querySelector('.results').innerHTML = html;

        if (stopRequested) {
            container.querySelector('.status').textContent = '抽奖已停止';
        } else {
            container.querySelector('.status').textContent = '抽奖已完成';
        }
    }

    // 初始化
    resetStats();
    createUI();
})();