您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automated energy farming with draggable HUD, Farming Mode, Auto Login and Auto Resume farm - integrates with Smol Veyra Script Extension Hub for sidebar control and image blocking optimization.
// ==UserScript== // @name Smol - Veyra Farm Extension // @namespace http://violentmonkey.github.io/smol-veyra-farm-extension // @version 1.3 // @author Smol // @description Automated energy farming with draggable HUD, Farming Mode, Auto Login and Auto Resume farm - integrates with Smol Veyra Script Extension Hub for sidebar control and image blocking optimization. // @match https://demonicscans.org/* // @icon https://www.google.com/s2/favicons?sz=64&domain=demonicscans.org // @grant none // @license MIT License // ==/UserScript== (function() { 'use strict'; // edit this email and password value and set autologin to true if you use this script as standalone var YOUR_EMAIL = 'WRITE_YOUR_EMAIL_HERE'; // change into your actual email var YOUR_PASSWORD = 'WRITE_YOUR_PASSWORD_HERE'; // change into your actual password var AUTO_LOGIN = false; // change to true if you wish to enable autologin feature // Initialize farming localStorage if not exists if (localStorage.getItem('veyra-farming-automation') === null) { localStorage.setItem('veyra-farming-automation', 'false'); } if (localStorage.getItem('minus-energy-cap') === null) { localStorage.setItem('minus-energy-cap', '30'); } if (localStorage.getItem('target-farming-energy') === null) { localStorage.setItem('target-farming-energy', '150'); } if (localStorage.getItem('farming-mode') === null) { localStorage.setItem('farming-mode', 'energy-cap'); } if (localStorage.getItem('smol-script-expanded') === null) { localStorage.setItem('smol-script-expanded', 'false'); } if (localStorage.getItem('smol-script-farm-enabled') === null) { localStorage.setItem('smol-script-farm-enabled', 'true'); } if (localStorage.getItem('smol-script-autologin-enabled') === null) { localStorage.setItem('smol-script-autologin-enabled', AUTO_LOGIN.toString()); } // Check if image blocking is available const hasImageBlocking = typeof window.smolImageBlockEnabled !== 'undefined'; // Initialize extension if (window.location.hostname === 'demonicscans.org') { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => setTimeout(initAsExtension, 250)); } else { setTimeout(initAsExtension, 250); } } function initAsExtension() { const smolScript = window.smolScript ? window.smolScript : undefined const gameSidebar = document.querySelector('#game-sidebar'); const scriptExtension = document.getElementById('script-extension'); if (smolScript && gameSidebar && scriptExtension) { const scriptExpanded = document.getElementById('script-expanded'); if (scriptExpanded && !document.getElementById('farm-script-toggle')) { const farmDiv = document.createElement('div'); farmDiv.innerHTML = ` <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;"> <div style="font-size: 12px; color: #888;"><span>🌾 Farm Script</span></div> <input type="checkbox" id="farm-script-toggle" ${localStorage.getItem('smol-script-farm-enabled') === 'true' ? 'checked' : ''}></input> </div> `; scriptExpanded.appendChild(farmDiv); document.getElementById('farm-script-toggle').addEventListener('change', (e) => { localStorage.setItem('smol-script-farm-enabled', e.target.checked.toString()); window.location.reload(); }); } } if (localStorage.getItem('smol-script-farm-enabled') === 'true' && (!window.location.pathname.includes('.php') || window.location.pathname === '/index.php')) { initFarmingExtension(); } else if (localStorage.getItem('smol-script-farm-enabled') === 'true' && window.location.pathname === '/signin.php') { autoLogin() } } function autoLogin() { if (!window.location.href.includes("signin.php")) return false; const isEnabled = localStorage.getItem('smol-script-autologin-enabled') === 'true'; if (!isEnabled) return false; const email = YOUR_EMAIL; const password = YOUR_PASSWORD; if (!email || !password) return false; const emailInput = document.evaluate('//*[@id="login-container"]/form/input[1]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; const passwordInput = document.evaluate('//*[@id="login-container"]/form/input[2]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; const loginBtn = document.evaluate('//*[@id="login-container"]/form/input[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if (emailInput && passwordInput && loginBtn) { emailInput.value = email; passwordInput.value = password; loginBtn.click(); return true; } return false; } function initFarmingExtension() { createFarmingHUD(); if (getFarmingAutomation()) { setTimeout(runFarming, 1000); } } function createFarmingHUD() { if (document.getElementById('farming-hud-main')) return; const hud = document.createElement('div'); hud.id = 'farming-hud-main'; hud.className = 'veyra-glass'; // Load saved position or use default const savedPosition = sessionStorage.getItem('farm-hud-position'); if (savedPosition) { const pos = JSON.parse(savedPosition); hud.style.cssText = ` position: fixed; left: ${pos.left}px; top: ${pos.top}px; z-index: 2147483647; `; } else { hud.style.cssText = ` position: fixed; bottom: 16px; right: 16px; z-index: 2147483647; `; } document.body.appendChild(hud); makeDraggable(hud); updateFarmingHUD(); } function makeDraggable(element) { let isDragging = false; let startX, startY, startLeft, startTop; element.addEventListener('mousedown', (e) => { if (e.target.classList.contains('drag-handle')) { isDragging = true; startX = e.clientX; startY = e.clientY; const rect = element.getBoundingClientRect(); startLeft = rect.left; startTop = rect.top; element.style.cursor = 'grabbing'; e.preventDefault(); } }); document.addEventListener('mousemove', (e) => { if (isDragging) { const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; const newLeft = startLeft + deltaX; const newTop = startTop + deltaY; element.style.left = newLeft + 'px'; element.style.top = newTop + 'px'; element.style.right = 'auto'; element.style.bottom = 'auto'; } }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; element.style.cursor = 'default'; // Save position to sessionStorage const rect = element.getBoundingClientRect(); sessionStorage.setItem('farm-hud-position', JSON.stringify({ left: rect.left, top: rect.top })); } }); } function updateFarmingHUD() { const hud = document.getElementById('farming-hud-main'); if (!hud) return; const isRunning = getFarmingAutomation(); const farmingMode = localStorage.getItem('farming-mode') || 'energy-cap'; const energyCap = localStorage.getItem('minus-energy-cap') || '30'; const energyTarget = localStorage.getItem('target-farming-energy') || '150'; // Get current stamina and farm values const stamina = getStamina(); const farm = getFarm(); const staminaText = stamina ? `${stamina.current}/${stamina.max}` : '0/0'; const farmText = farm ? `${farm.current}/${farm.max}` : '0/0'; let statusText = 'Idle'; if (isRunning) { statusText = 'Farming Energy'; } const content = ` <div class="veyra-header"> <div class="veyra-title">Veyra — Farm</div> <div style="display: flex; align-items: center; gap: 8px;"> <span class="veyra-pill ${isRunning ? 'pill-live' : 'pill-stop'}">${isRunning ? 'RUNNING' : 'PAUSED'}</span> <div class="drag-handle" style="width: 16px; height: 16px; background: rgba(255,255,255,0.3); border-radius: 3px; cursor: grab; display: flex; align-items: center; justify-content: center; font-size: 10px;">⋮⋮</div> </div> </div> <div class="veyra-body"> <div class="veyra-row"> <div>Mode</div> <div><select id="farm-mode-select" class="veyra-select" ${isRunning ? 'disabled' : ''}> <option value="energy-cap" ${farmingMode === 'energy-cap' ? 'selected' : ''}>Energy Cap</option> <option value="energy-target" ${farmingMode === 'energy-target' ? 'selected' : ''}>Energy Target</option> </select></div> </div> <div class="veyra-row" id="energy-cap-row" style="display: ${farmingMode === 'energy-cap' ? 'flex' : 'none'}"> <div>Energy Cap</div> <div><input id="farm-energy-cap" type="number" class="veyra-input" min="0" value="${energyCap}" ${isRunning ? 'disabled' : ''}></div> </div> <div class="veyra-row" id="energy-target-row" style="display: ${farmingMode === 'energy-target' ? 'flex' : 'none'}"> <div>Energy Target</div> <div><input id="farm-energy-target" type="number" class="veyra-input" min="0" value="${energyTarget}" ${isRunning ? 'disabled' : ''}></div> </div> <div class="veyra-row"> <div>Auto Farm</div> <div><button id="farm-hud-toggle" class="veyra-btn">${isRunning ? 'Stop' : 'Start'}</button></div> </div> ${hasImageBlocking ? `<div class="veyra-row"> <div>Block Images</div> <div><input id="farm-image-block" type="checkbox" ${localStorage.getItem('smol-script-noimage') === 'true' ? 'checked' : ''}></div> </div>` : ''} <div class="veyra-divider"></div> <div class="veyra-row"> <div>Stamina</div> <div style="color:var(--glass-muted)">${staminaText}</div> </div> <div class="veyra-row"> <div>Farm</div> <div style="color:var(--glass-muted)">${farmText}</div> </div> <div class="veyra-divider"></div> <div class="veyra-row"> <div>Status</div> <div>${statusText}</div> </div> </div> `; hud.innerHTML = content; // Setup event listeners setTimeout(() => { const toggleBtn = document.getElementById('farm-hud-toggle'); const modeSelect = document.getElementById('farm-mode-select'); const energyCapInput = document.getElementById('farm-energy-cap'); const energyTargetInput = document.getElementById('farm-energy-target'); const energyCapRow = document.getElementById('energy-cap-row'); const energyTargetRow = document.getElementById('energy-target-row'); if (toggleBtn && !toggleBtn.hasAttribute('data-listener-added')) { toggleBtn.addEventListener('click', toggleFarmingFromHUD); toggleBtn.setAttribute('data-listener-added', 'true'); } if (modeSelect && !modeSelect.hasAttribute('data-listener-added')) { modeSelect.addEventListener('change', (e) => { localStorage.setItem('farming-mode', e.target.value); energyCapRow.style.display = e.target.value === 'energy-cap' ? 'flex' : 'none'; energyTargetRow.style.display = e.target.value === 'energy-target' ? 'flex' : 'none'; }); modeSelect.setAttribute('data-listener-added', 'true'); } if (energyCapInput && !energyCapInput.hasAttribute('data-listener-added')) { energyCapInput.addEventListener('change', (e) => { const value = Math.max(0, parseInt(e.target.value) || 30); localStorage.setItem('minus-energy-cap', value.toString()); e.target.value = value; }); energyCapInput.setAttribute('data-listener-added', 'true'); } if (energyTargetInput && !energyTargetInput.hasAttribute('data-listener-added')) { energyTargetInput.addEventListener('change', (e) => { const value = Math.max(0, parseInt(e.target.value) || 150); localStorage.setItem('target-farming-energy', value.toString()); e.target.value = value; }); energyTargetInput.setAttribute('data-listener-added', 'true'); } const imageBlockCheckbox = document.getElementById('farm-image-block'); if (imageBlockCheckbox && !imageBlockCheckbox.hasAttribute('data-listener-added')) { imageBlockCheckbox.addEventListener('change', (e) => { localStorage.setItem('smol-script-noimage', e.target.checked.toString()); window.dispatchEvent(new StorageEvent('storage', { key: 'smol-script-noimage', newValue: e.target.checked.toString() })); }); imageBlockCheckbox.setAttribute('data-listener-added', 'true'); } }, 100); } function toggleFarmingFromHUD() { const newRunningState = !getFarmingAutomation(); setFarmingAutomation(newRunningState); // Control image blocking during farming if (hasImageBlocking) { if (newRunningState) { localStorage.setItem('smol-script-noimage', 'true'); } else { // Restore previous state when stopping const checkbox = document.getElementById('farm-image-block'); if (checkbox) { localStorage.setItem('smol-script-noimage', checkbox.checked.toString()); } } window.dispatchEvent(new StorageEvent('storage', { key: 'smol-script-noimage', newValue: localStorage.getItem('smol-script-noimage') })); } updateFarmingHUD(); if (newRunningState) { showNotification('Starting farming automation...', 'success'); runFarming(); } else { showNotification('Farming automation stopped', 'info'); } } // Farming automation functions function getFarmingAutomation() { return localStorage.getItem('veyra-farming-automation') === 'true'; } function setFarmingAutomation(value) { localStorage.setItem('veyra-farming-automation', value.toString()); } function getStamina() { const staminaEl = document.evaluate( '//*[@id="discuscontainer"]/div[1]/div[1]/div[2]/span[1]/span', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; if (!staminaEl) return null; const [current, max] = staminaEl.innerText.split('/').map(s => parseInt(s.trim())); return { current, max }; } function getFarm() { const farmEl = document.evaluate( '//*[@id="discuscontainer"]/div[1]/div[1]/div[2]/span[2]/span', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; if (!farmEl) return null; const [current, max] = farmEl.innerText.split('/').map(s => parseInt(s.replace(/,/g, '').trim(), 10)); return { current, max }; } function checkUserLogin(bypass = false) { let userInfo, loginContainer; if (bypass) { userInfo = false; loginContainer = true; } else { userInfo = document.querySelector('.comments-section .user-info'); loginContainer = document.querySelector('#login-container'); } if ((!userInfo || loginContainer) && !window.location.href.includes("signin.php")) { console.log('User not logged in, clearing cookies and redirecting to login'); document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); }); sessionStorage.setItem("veyra_resume_page", window.location.href); window.location.href = "https://demonicscans.org/signin.php"; return false; } return true; } function checkFarmingLimits() { const stamina = getStamina(); const farm = getFarm(); if (!stamina || !farm) return false; if (!getFarmingAutomation()) return false; if (!checkUserLogin()) return false; const farmingMode = localStorage.getItem('farming-mode') || 'energy-cap'; if (farmingMode === 'energy-cap') { const minusEnergyCap = parseInt(localStorage.getItem('minus-energy-cap')) || 30; if (stamina.max - stamina.current <= minusEnergyCap) { setFarmingAutomation(false); updateFarmingHUD(); return false; } } else { const targetEnergy = parseInt(localStorage.getItem('target-farming-energy')) || 150; if (stamina.current >= targetEnergy) { setFarmingAutomation(false); updateFarmingHUD(); return false; } } if (farm.current >= farm.max) { setFarmingAutomation(false); startFarming(); return false; } return true; } function clickReaction() { const reaction = document.evaluate( '/html/body/div[5]/center/div/div[1]/div[3]/div[1]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; if (reaction) { reaction.scrollIntoView(); reaction.click(); console.log('✅ Clicked reaction on', window.location.href); return true; } else { console.log('⚠️ Reaction not found on', window.location.href); console.log('User not logged in, clearing cookies and redirecting to login'); document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); }); sessionStorage.setItem("veyra_resume_page", window.location.href); window.location.href = "https://demonicscans.org/signin.php"; return false; } } function goNextPage() { const nextBtn = document.querySelector('body > div.chapter-info > div > a.nextchap'); if (nextBtn) { console.log('➡️ Navigating to next chapter:', nextBtn.href); window.location.href = nextBtn.href; } else { console.log('❌ Next button not found, picking new manga'); startFarming(); } } function startFarming() { if (!getFarmingAutomation()) return; window.location.href = 'https://demonicscans.org'; } function pickRandomManga() { const owlItems = document.querySelectorAll('.owl-item .owl-element a'); if (owlItems.length === 0) { setTimeout(pickRandomManga, 1000); return; } const randomIndex = Math.floor(Math.random() * owlItems.length); const randomManga = owlItems[randomIndex]; console.log('Picked random manga:', randomManga.href); window.location.href = randomManga.href; } function startFromLastChapter() { const chapters = document.querySelectorAll('#chapters-list > li > a'); if (chapters.length === 0) { setTimeout(startFromLastChapter, 1000); return; } const lastChapter = chapters[chapters.length - 1]; console.log('Starting from last chapter:', lastChapter.href); window.location.href = lastChapter.href; } function runFarming() { updateFarmingHUD(); if (!getFarmingAutomation()) return; const currentPath = window.location.pathname; const currentUrl = window.location.href; // If automation starts from homepage or index.php - pick random manga if (currentPath === '/' || currentPath === '/index.php') { pickRandomManga(); return; } // If automation starts from manga page - go to last chapter if (currentPath.includes('/manga/')) { startFromLastChapter(); return; } // If automation starts from chapter page - check limits and continue if (currentPath.includes('/chapter/')) { if (!checkFarmingLimits()) { if (!checkUserLogin()) return false setTimeout(runFarming, 5000); return; } const reactSuccess = clickReaction(); if (reactSuccess) { setTimeout(() => { goNextPage(); }, 1500); } else { if (!checkUserLogin()) return false } } } function showNotification(msg, type = 'success') { let note = document.getElementById('farm-notification'); if (!note) { note = document.createElement('div'); note.id = 'farm-notification'; note.style.cssText = `position: fixed; top: 90px; right: 20px; background: #2ecc71; color: white; padding: 12px 20px; border-radius: 10px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); font-size: 15px; display: none; z-index: 9999;`; document.body.appendChild(note); } let emoji = ''; if (type === 'success') emoji = '✅ '; else if (type === 'error') emoji = '❌ '; else if (type === 'warning') emoji = '⚠️ '; else if (type === 'info') emoji = 'ℹ️ '; note.innerHTML = emoji + msg; if (type === 'error') { note.style.background = 'linear-gradient(135deg, #e74c3c, #c0392b)'; } else if (type === 'warning') { note.style.background = 'linear-gradient(135deg, #f39c12, #e67e22)'; } else if (type === 'info') { note.style.background = 'linear-gradient(135deg, #3498db, #2980b9)'; } else { note.style.background = 'linear-gradient(135deg, #2ecc71, #27ae60)'; } note.style.display = 'block'; setTimeout(() => { note.style.display = 'none'; }, 4000); } // Add CSS styles const style = document.createElement('style'); style.textContent = ` :root{ --glass-bg: rgba(255,255,255,0.06); --glass-border: rgba(255,255,255,0.08); --glass-text: #e6eef8; --glass-muted: #b6c2d3; --accent: #3aa3ff; --danger: #ff6b6b; } .veyra-glass { background: var(--glass-bg); color: var(--glass-text); backdrop-filter: blur(12px) saturate(120%); -webkit-backdrop-filter: blur(12px) saturate(120%); border: 1px solid var(--glass-border); border-radius: 14px; padding: 12px; min-width: 260px; box-shadow: 0 8px 30px rgba(2,6,23,0.6); font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size: 13px; user-select: none; box-sizing: border-box; } .veyra-header { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; } .veyra-title { font-weight:700; font-size:14px; } .veyra-body { display:block; } .veyra-row { display:flex; align-items:center; justify-content:space-between; gap:8px; margin:6px 0; } .veyra-btn { padding:6px 8px; border-radius:8px; border:none; cursor:pointer; background:linear-gradient(180deg,#3aa3ff,#1b7ed6); color:white; } .veyra-divider { height:1px; background:rgba(255,255,255,0.04); margin:8px 0; border-radius:2px; } .veyra-pill { font-size:11px; padding:4px 8px; border-radius:999px; } .pill-live { background:rgba(34,197,94,0.18); color:#c7ffd3; border:1px solid rgba(34,197,94,0.22); } .pill-stop { background:rgba(239,68,68,0.12); color:#ffd6d6; border:1px solid rgba(239,68,68,0.18); } .veyra-select, .veyra-input { padding: 4px 6px; border-radius: 6px; border: 1px solid var(--glass-border); background: rgba(255,255,255,0.04); color: var(--glass-text); font-size: 12px; width: 80px; } .veyra-select:disabled, .veyra-input:disabled { opacity: 0.5; cursor: not-allowed; } .drag-handle:hover { background: rgba(255,255,255,0.5) !important; } `; document.head.appendChild(style); })();