Auto Reload on Stake.com - CodeStats edition

Automatically claims 10 minute reloads on Stake.com by sequentially clicking VIP Reward → Claim Reload → Return to Rewards. The script starts after a short page-load delay, mimics human behavior with user customizable random delays, occasional skipped cycles, and subtle mouse/scroll movements. WANT MORE STAKE BONUS CODE AUTO-CLAIM TOOLS? GO TO https://codestats.gg

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Auto Reload on Stake.com - CodeStats edition
// @description  Automatically claims 10 minute reloads on Stake.com by sequentially clicking VIP Reward → Claim Reload → Return to Rewards. The script starts after a short page-load delay, mimics human behavior with user customizable random delays, occasional skipped cycles, and subtle mouse/scroll movements. WANT MORE STAKE BONUS CODE AUTO-CLAIM TOOLS? GO TO https://codestats.gg
// @author       CHUBB
// @namespace    https://codestats.gg
// @version      1.0.0
// @match        https://stake.com/*
// @match        https://stake.us/*
// @match        https://stake.ac/*
// @match        https://stake.games/*
// @match        https://stake.bet/*
// @match        https://stake.pet/*
// @match        https://stake.mba/*
// @match        https://stake.jp/*
// @match        https://stake.bz/*
// @match        https://stake.ceo/*
// @match        https://stake.krd/*
// @match        https://staketr.com/*
// @match        https://stake1001.com/*
// @match        https://stake1002.com/*
// @match        https://stake1003.com/*
// @match        https://stake1004.com/*
// @match        https://stake1005.com/*
// @match        https://stake1021.com/*
// @match        https://stake1022.com/*
// @match        https://stake.br/*
// @run-at       document-idle
// @license      MIT
// @connect      stake.com
// @connect      stake.us
// @connect      stake.ac
// @connect      stake.games
// @connect      stake.bet
// @connect      stake.pet
// @connect      stake.mba
// @connect      stake.jp
// @connect      stake.bz
// @connect      stake.ceo
// @connect      stake.krd
// @connect      staketr.com
// @connect      stake1001.com
// @connect      stake1002.com
// @connect      stake1003.com
// @connect      stake1004.com
// @connect      stake1005.com
// @connect      stake1021.com
// @connect      stake1022.com
// @connect      stake.br
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

// ===== CONFIGURATION SYSTEM =====
const defaultConfig = {
    minMinutes: 10,
    maxMinutes: 12,
    enabled: true,
};

let config = { ...defaultConfig };
let currentTimeout = null;
let currentTimer = null;

function loadConfig() {
    try {
        const saved = GM_getValue("autoReloadConfig", null);
        if (saved) {
            config = { ...defaultConfig, ...saved };
        }
    } catch (e) {
        console.log("Could not load config, using defaults");
    }
}

// Update input fields when config is loaded
function updateInputFieldsFromConfig() {
    const minHours = Math.floor(config.minMinutes / 60);
    const minMins = config.minMinutes % 60;
    const maxHours = Math.floor(config.maxMinutes / 60);
    const maxMins = config.maxMinutes % 60;

    const minHoursInput = document.getElementById("minHours");
    const minMinutesInput = document.getElementById("minMinutes");
    const maxHoursInput = document.getElementById("maxHours");
    const maxMinutesInput = document.getElementById("maxMinutes");

    if (minHoursInput) minHoursInput.value = minHours;
    if (minMinutesInput) minMinutesInput.value = minMins;
    if (maxHoursInput) maxHoursInput.value = maxHours;
    if (maxMinutesInput) maxMinutesInput.value = maxMins;
}

function saveConfig() {
    try {
        GM_setValue("autoReloadConfig", config);
    } catch (e) {
        console.log("Could not save config");
    }
}

// ===== HUD SETUP =====

function setupHUD() {
    let hud = document.createElement("div");
    hud.id = "autoReloadHUD";
    hud.style.cssText = `
        position: fixed;
        bottom: 10px;
        right: 10px;
        width: 600px;
        max-height: 300px;
        overflow-y: auto;
        font-size: 12px;
        background: rgba(0,0,0,0.8);
        color: #0f0;
        padding: 10px;
        border-radius: 8px;
        font-family: monospace;
        z-index: 999999;
        border: 1px solid #0f0;
    `;

    hud.innerHTML = `
        <b><a href="https://codestats.gg" target="_blank" rel="noopener noreferrer" style="color: #0f0; text-decoration: underline;">CodeStats.gg</a> Stake Reload Bot v1.0.0</b>
        <div style="margin: 8px 0; padding: 8px; background: rgba(0,255,0,0.1); border-radius: 4px;">
            <div style="display: flex; align-items: center; gap: 5px; margin-bottom: 8px;">
                <button id="goToVip" style="padding: 4px 8px; background: #0f0; color: #000; border: none; border-radius: 4px; cursor: pointer; font-weight: bold;">🏆 VIP</button>
                <button id="toggleBtn" style="padding: 4px 8px; background: #0f0; color: #000; border: none; border-radius: 4px; cursor: pointer; font-weight: bold;">${config.enabled ? "PAUSE" : "START"}</button>
                <span>Status: <span id="statusText">${config.enabled ? "RUNNING" : "PAUSED"}</span></span>
            </div>
            <div style="margin-bottom: 8px;">
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
                    <div>
                        <label style="display: block; margin-bottom: 2px;">Min Time:</label>
                        <div style="display: flex; gap: 5px; align-items: center;">
                            <input type="number" id="minHours" value="${Math.floor(config.minMinutes / 60)}" min="0" max="23" style="width: 50px; padding: 2px; background: #000; color: #0f0; border: 1px solid #0f0; border-radius: 2px;">
                            <span style="color: #0f0;">h</span>
                            <input type="number" id="minMinutes" value="${config.minMinutes % 60}" min="0" max="59" style="width: 50px; padding: 2px; background: #000; color: #0f0; border: 1px solid #0f0; border-radius: 2px;">
                            <span style="color: #0f0;">m</span>
                        </div>
                    </div>
                    <div>
                        <label style="display: block; margin-bottom: 2px;">Max Time:</label>
                        <div style="display: flex; gap: 5px; align-items: center;">
                            <input type="number" id="maxHours" value="${Math.floor(config.maxMinutes / 60)}" min="0" max="23" style="width: 50px; padding: 2px; background: #000; color: #0f0; border: 1px solid #0f0; border-radius: 2px;">
                            <span style="color: #0f0;">h</span>
                            <input type="number" id="maxMinutes" value="${config.maxMinutes % 60}" min="0" max="59" style="width: 50px; padding: 2px; background: #000; color: #0f0; border: 1px solid #0f0; border-radius: 2px;">
                            <span style="color: #0f0;">m</span>
                        </div>
                    </div>
                </div>
            </div>
            <button id="applySettings" style="padding: 4px 8px; background: #0f0; color: #000; border: none; border-radius: 3px; cursor: pointer; font-weight: bold;">Apply Settings</button>
        </div>
        <div id="hudLog" style="max-height: 80px; overflow-y: auto;"></div>
        <div id="hudTimer" style="font-weight: bold; color: #ff0;"></div>
    `;

    document.body.appendChild(hud);

    // Setup event listeners
    document.getElementById("toggleBtn").addEventListener("click", toggleBot);
    document
        .getElementById("applySettings")
        .addEventListener("click", applySettings);

    document.getElementById("goToVip").addEventListener("click", function () {
        window.location.href = `${window.location.origin}/?tab=rewards&modal=vip`;
    });

    // Update input fields with loaded config values
    updateInputFieldsFromConfig();
}

function toggleBot() {
    config.enabled = !config.enabled;
    const btn = document.getElementById("toggleBtn");
    const status = document.getElementById("statusText");

    btn.textContent = config.enabled ? "PAUSE" : "START";
    status.textContent = config.enabled ? "RUNNING" : "PAUSED";

    saveConfig();

    if (config.enabled) {
        logHUD("Bot resumed");
        startCycle();
    } else {
        logHUD("Bot paused");
        if (currentTimeout) {
            clearTimeout(currentTimeout);
            currentTimeout = null;
        }
        if (currentTimer) {
            clearInterval(currentTimer);
            currentTimer = null;
        }
        document.getElementById("hudTimer").textContent = "Bot paused";
    }
}

function applySettings() {
    const minHours = parseInt(document.getElementById("minHours").value);
    const minMins = parseInt(document.getElementById("minMinutes").value);
    const maxHours = parseInt(document.getElementById("maxHours").value);
    const maxMins = parseInt(document.getElementById("maxMinutes").value);

    const newMin = minHours * 60 + minMins;
    const newMax = maxHours * 60 + maxMins;

    // Always save the current input values to make them persistent
    config.minMinutes = newMin;
    config.maxMinutes = newMax;
    saveConfig();

    // Update input fields with saved values
    updateInputFieldsFromConfig();

    if (
        newMin >= 1 &&
        newMax >= 1 &&
        newMin <= 1440 &&
        newMax <= 1440 &&
        newMin <= newMax
    ) {
        const minText =
            minHours > 0 ? `${minHours}h ${minMins}m` : `${minMins}m`;
        const maxText =
            maxHours > 0 ? `${maxHours}h ${maxMins}m` : `${maxMins}m`;
        logHUD(`Settings updated: ${minText}-${maxText}`);

        // Restart cycle if enabled to apply new settings immediately
        if (config.enabled) {
            if (currentTimeout) {
                clearTimeout(currentTimeout);
                currentTimeout = null;
            }
            if (currentTimer) {
                clearInterval(currentTimer);
                currentTimer = null;
            }
            startCycle();
        }
    } else {
        logHUD(
            "Invalid settings: min must be ≤ max, both between 1 minute and 24 hours",
        );
    }
}
setupHUD();

function logHUD(msg) {
    let log = document.getElementById("hudLog");
    if (log) {
        let line = document.createElement("div");
        line.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
        log.appendChild(line); // add new line at the bottom
        while (log.childNodes.length > 3) log.removeChild(log.firstChild); // trim from top
        log.scrollTop = log.scrollHeight; // auto-scroll to bottom
    }
    console.log(msg);
}

function updateTimer(ms) {
    let el = document.getElementById("hudTimer");
    if (!el) return;
    let sec = Math.floor(ms / 1000);
    let m = Math.floor(sec / 60);
    let s = sec % 60;
    el.textContent = `Next attempt in ${m}m ${s}s`;
}

// ===== CLICK FUNCTION =====
async function orderedClick(selector, retries = 5, interval = 3000) {
    for (let i = 0; i < retries; i++) {
        const el = document.querySelector(selector);
        if (el) {
            const delay = Math.floor(Math.random() * 2000) + 1000;
            await wait(delay);
            el.click();
            logHUD(`Clicked: ${selector} (after ${delay}ms)`);
            return true;
        }
        await wait(interval);
    }
    logHUD(`FAILED: ${selector}`);
    return false;
}

// Update input fields when config changes
updateInputFieldsFromConfig();

// ===== CLAIM FUNCTION =====
async function claimReload() {
    simulateMouseMove();

    await orderedClick('button[data-testid="progress-tab"]');
    await orderedClick('button[data-testid="rewards-tab"]');
    await orderedClick('button[data-testid="vip-reward-claim-reload"]');

    // The MONEY button
    const claimSuccess = await orderedClick(
        'button[data-testid="claim-reload"]',
    );

    if (claimSuccess) {
        // If we successfully clicked claim, we *must* try to wrap up
        const finalStep = await orderedClick(
            'button[data-testid="return-to-rewards"]',
        );
        if (!finalStep) {
            logHUD("Claimed reload but couldn't return → reloading page...");
            window.location.href = `${window.location.origin}/?tab=progress&modal=vip`;
            return;
        }
    }

    simulateMouseMove();
    logHUD("Finished reload attempt.");
}

// ===== CYCLE FUNCTION =====
function startCycle() {
    if (!config.enabled) {
        return;
    }

    const min = config.minMinutes * 60 * 1000;
    const max = config.maxMinutes * 60 * 1000;
    const delay = Math.floor(Math.random() * (max - min + 1)) + min;

    let endTime = Date.now() + delay;
    currentTimer = setInterval(() => {
        let remaining = endTime - Date.now();
        if (remaining <= 0) {
            clearInterval(currentTimer);
            currentTimer = null;
            return;
        }
        updateTimer(remaining);
    }, 1000);

    const minHours = Math.floor(config.minMinutes / 60);
    const minMins = config.minMinutes % 60;
    const maxHours = Math.floor(config.maxMinutes / 60);
    const maxMins = config.maxMinutes % 60;

    const minText = minHours > 0 ? `${minHours}h ${minMins}m` : `${minMins}m`;
    const maxText = maxHours > 0 ? `${maxHours}h ${maxMins}m` : `${maxMins}m`;

    logHUD(
        `Next attempt scheduled in ${(delay / 60000).toFixed(2)} minutes (${minText}-${maxText})`,
    );

    currentTimeout = setTimeout(async () => {
        currentTimeout = null;
        await claimReload();
        startCycle();
    }, delay);
}

// ===== UTILITIES =====
function simulateMouseMove() {
    const simElm = document.documentElement;
    const simMouseMove = new Event("mousemove", { bubbles: true });
    simElm.dispatchEvent(simMouseMove);
}

function wait(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

// ===== INITIAL RUN =====
(function firstRun() {
    loadConfig();

    // Small delay to ensure DOM is ready before updating input fields
    setTimeout(() => {
        updateInputFieldsFromConfig();
    }, 100);

    const firstDelay = Math.floor(Math.random() * 5000) + 5000;
    const minHours = Math.floor(config.minMinutes / 60);
    const minMins = config.minMinutes % 60;
    const maxHours = Math.floor(config.maxMinutes / 60);
    const maxMins = config.maxMinutes % 60;

    const minText = minHours > 0 ? `${minHours}h ${minMins}m` : `${minMins}m`;
    const maxText = maxHours > 0 ? `${maxHours}h ${maxMins}m` : `${maxMins}m`;

    logHUD(`Bot loaded - Settings: ${minText}-${maxText}`);
    logHUD(`First attempt in ${(firstDelay / 1000).toFixed(1)}s`);

    setTimeout(async () => {
        await claimReload();
        startCycle();
    }, firstDelay);
})();