EarnFreeLite Auto Claimer

Automatically claims LTC rewards on EarnFreeLite mining page

Size

10.1 KB

Version

1.1.2

Created

Nov 2, 2025

Updated

12 days ago

1// ==UserScript==
2// @name		EarnFreeLite Auto Claimer
3// @description		Automatically claims LTC rewards on EarnFreeLite mining page
4// @version		1.1.2
5// @match		https://*.earnfreelite.com/*
6// @icon		https://earnfreelite.com/diamond.png
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    console.log('EarnFreeLite Auto Claimer initialized');
12
13    // Configuration
14    const CONFIG = {
15        checkInterval: 5000, // Check every 5 seconds
16        buttonSelector: 'button#mineButton.btn-claim',
17        claimsSelector: '#clicks_today',
18        balanceSelector: '#balance',
19        slotNumberSelector: '#slot-number',
20        captchaSelector: '.cf-turnstile'
21    };
22
23    // State management
24    let isProcessing = false;
25    let lastBalance = 0;
26    let totalClaims = 0;
27    let totalEarned = 0;
28
29    // Initialize stats from storage
30    async function initStats() {
31        totalClaims = await GM.getValue('totalClaims', 0);
32        totalEarned = await GM.getValue('totalEarned', 0);
33        console.log(`Loaded stats - Total Claims: ${totalClaims}, Total Earned: ${totalEarned} LTC`);
34    }
35
36    // Save stats to storage
37    async function saveStats() {
38        await GM.setValue('totalClaims', totalClaims);
39        await GM.setValue('totalEarned', totalEarned);
40    }
41
42    // Parse balance from text
43    function parseBalance(text) {
44        const match = text.match(/Balance:\s*([\d.]+)\s*LTC/);
45        return match ? parseFloat(match[1]) : 0;
46    }
47
48    // Parse claims from text
49    function parseClaims(text) {
50        const match = text.match(/Claims:\s*(\d+)\/(\d+)/);
51        return match ? { current: parseInt(match[1]), max: parseInt(match[2]) } : null;
52    }
53
54    // Check if captcha is present and solved
55    function isCaptchaSolved() {
56        const captchaElement = document.querySelector(CONFIG.captchaSelector);
57        if (!captchaElement) {
58            console.log('No captcha element found');
59            return true; // No captcha, proceed
60        }
61        
62        // Check if Turnstile has been solved (usually adds a response token)
63        const turnstileResponse = captchaElement.querySelector('input[name="cf-turnstile-response"]');
64        const isSolved = turnstileResponse && turnstileResponse.value.length > 0;
65        console.log(`Captcha solved: ${isSolved}`);
66        return isSolved;
67    }
68
69    // Check if button is clickable
70    function isButtonClickable() {
71        const button = document.querySelector(CONFIG.buttonSelector);
72        if (!button) {
73            console.log('Roll button not found');
74            return false;
75        }
76
77        const isDisabled = button.disabled || button.classList.contains('disabled');
78        const isVisible = button.offsetParent !== null;
79        
80        console.log(`Button state - Disabled: ${isDisabled}, Visible: ${isVisible}`);
81        return !isDisabled && isVisible;
82    }
83
84    // Get current claims info
85    function getClaimsInfo() {
86        const claimsElement = document.querySelector(CONFIG.claimsSelector);
87        if (!claimsElement) return null;
88        
89        return parseClaims(claimsElement.textContent);
90    }
91
92    // Show notification
93    function showNotification(message, type = 'info') {
94        const notification = document.createElement('div');
95        notification.style.cssText = `
96            position: fixed;
97            top: 20px;
98            right: 20px;
99            background: ${type === 'success' ? '#28a745' : type === 'error' ? '#dc3545' : '#17a2b8'};
100            color: white;
101            padding: 15px 20px;
102            border-radius: 8px;
103            box-shadow: 0 4px 6px rgba(0,0,0,0.3);
104            z-index: 999999;
105            font-family: Arial, sans-serif;
106            font-size: 14px;
107            max-width: 300px;
108            animation: slideIn 0.3s ease-out;
109        `;
110        notification.textContent = message;
111        document.body.appendChild(notification);
112
113        setTimeout(() => {
114            notification.style.animation = 'slideOut 0.3s ease-out';
115            setTimeout(() => notification.remove(), 300);
116        }, 4000);
117    }
118
119    // Add CSS animations
120    TM_addStyle(`
121        @keyframes slideIn {
122            from {
123                transform: translateX(400px);
124                opacity: 0;
125            }
126            to {
127                transform: translateX(0);
128                opacity: 1;
129            }
130        }
131        @keyframes slideOut {
132            from {
133                transform: translateX(0);
134                opacity: 1;
135            }
136            to {
137                transform: translateX(400px);
138                opacity: 0;
139            }
140        }
141    `);
142
143    // Click the roll button
144    async function clickRollButton() {
145        if (isProcessing) {
146            console.log('Already processing a claim, skipping...');
147            return;
148        }
149
150        const button = document.querySelector(CONFIG.buttonSelector);
151        if (!button) {
152            console.log('Roll button not found');
153            return;
154        }
155
156        isProcessing = true;
157        console.log('Attempting to click Roll button...');
158
159        // Get balance before claim
160        const balanceElement = document.querySelector(CONFIG.balanceSelector);
161        if (balanceElement) {
162            lastBalance = parseBalance(balanceElement.textContent);
163            console.log(`Balance before claim: ${lastBalance} LTC`);
164        }
165
166        // Click the button
167        button.click();
168        console.log('Roll button clicked!');
169
170        // Wait for result
171        setTimeout(async () => {
172            await checkClaimResult();
173            isProcessing = false;
174        }, 3000);
175    }
176
177    // Check claim result
178    async function checkClaimResult() {
179        const balanceElement = document.querySelector(CONFIG.balanceSelector);
180        const slotElement = document.querySelector(CONFIG.slotNumberSelector);
181        
182        if (balanceElement) {
183            const newBalance = parseBalance(balanceElement.textContent);
184            const earned = newBalance - lastBalance;
185            
186            if (earned > 0) {
187                totalClaims++;
188                totalEarned += earned;
189                await saveStats();
190                
191                const slotNumber = slotElement ? slotElement.textContent : 'Unknown';
192                console.log(`Claim successful! Roll: ${slotNumber}, Earned: ${earned} LTC`);
193                showNotification(`✅ Claimed ${earned} LTC! Roll: ${slotNumber}\nTotal: ${totalClaims} claims, ${totalEarned.toFixed(6)} LTC`, 'success');
194            } else {
195                console.log('Claim processed but no balance change detected');
196            }
197        }
198    }
199
200    // Main auto-claim loop
201    async function autoClaim() {
202        console.log('Checking if claim is available...');
203
204        // Check if we're on the mine page
205        if (!window.location.href.includes('mine.php')) {
206            console.log('Not on mine page, skipping...');
207            return;
208        }
209
210        // Check claims info
211        const claimsInfo = getClaimsInfo();
212        if (claimsInfo) {
213            console.log(`Claims: ${claimsInfo.current}/${claimsInfo.max}`);
214            
215            if (claimsInfo.current >= claimsInfo.max) {
216                console.log('Daily claim limit reached');
217                showNotification(`Daily limit reached (${claimsInfo.max}/${claimsInfo.max}). Waiting for reset...`, 'info');
218                return;
219            }
220        }
221
222        // Check if captcha is solved
223        if (!isCaptchaSolved()) {
224            console.log('Captcha not solved yet, waiting...');
225            return;
226        }
227
228        // Check if button is clickable
229        if (!isButtonClickable()) {
230            console.log('Button not clickable yet');
231            return;
232        }
233
234        // All checks passed, click the button
235        await clickRollButton();
236    }
237
238    // Create stats display
239    function createStatsDisplay() {
240        const statsDiv = document.createElement('div');
241        statsDiv.id = 'auto-claimer-stats';
242        statsDiv.style.cssText = `
243            position: fixed;
244            bottom: 20px;
245            right: 20px;
246            background: rgba(0, 0, 0, 0.85);
247            color: #00ff00;
248            padding: 15px;
249            border-radius: 8px;
250            border: 2px solid #00ff00;
251            font-family: 'Courier New', monospace;
252            font-size: 12px;
253            z-index: 999998;
254            min-width: 200px;
255            box-shadow: 0 0 20px rgba(0, 255, 0, 0.3);
256        `;
257        
258        statsDiv.innerHTML = `
259            <div style="font-weight: bold; margin-bottom: 8px; text-align: center; font-size: 14px;">🤖 Auto Claimer</div>
260            <div>Total Claims: <span id="stat-claims">${totalClaims}</span></div>
261            <div>Total Earned: <span id="stat-earned">${totalEarned.toFixed(6)}</span> LTC</div>
262            <div style="margin-top: 8px; padding-top: 8px; border-top: 1px solid #00ff00;">
263                <span style="color: #ffff00;">● Active</span>
264            </div>
265        `;
266        
267        document.body.appendChild(statsDiv);
268    }
269
270    // Update stats display
271    function updateStatsDisplay() {
272        const claimsSpan = document.getElementById('stat-claims');
273        const earnedSpan = document.getElementById('stat-earned');
274        
275        if (claimsSpan) claimsSpan.textContent = totalClaims;
276        if (earnedSpan) earnedSpan.textContent = totalEarned.toFixed(6);
277    }
278
279    // Initialize extension
280    async function init() {
281        console.log('Starting EarnFreeLite Auto Claimer...');
282        
283        // Wait for page to load
284        if (document.readyState === 'loading') {
285            document.addEventListener('DOMContentLoaded', init);
286            return;
287        }
288
289        // Initialize stats
290        await initStats();
291
292        // Create stats display
293        createStatsDisplay();
294
295        // Show startup notification
296        showNotification('🤖 Auto Claimer Active! Monitoring for claims...', 'info');
297
298        // Start auto-claim loop
299        setInterval(autoClaim, CONFIG.checkInterval);
300
301        // Update stats display periodically
302        setInterval(updateStatsDisplay, 1000);
303
304        // Run first check after a short delay
305        setTimeout(autoClaim, 2000);
306    }
307
308    // Start the extension
309    init();
310})();
EarnFreeLite Auto Claimer | Robomonkey