// ==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);
})();