// ==UserScript==
// @name Smol - Veyra PvP Extension
// @namespace http://violentmonkey.github.io/smol-veyra-pvp-extension
// @version 1.2
// @author Smol
// @description Enhanced PvP automation with draggable HUD - integrates with Smol Script Extension Hub for sidebar control and Asura-cr Extension compatibility
// @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';
// PvP automation variables
var originalAlert = window.alert;
var originalConfirm = window.confirm;
var originalPrompt = window.prompt;
// Initialize PvP localStorage if not exists
if (localStorage.getItem('smol-pvp-automation') === null) {
localStorage.setItem('smol-pvp-automation', 'false');
}
if (localStorage.getItem('smol-pvp-auto-surrend') === null) {
localStorage.setItem('smol-pvp-auto-surrend', 'false');
}
if (localStorage.getItem('smol-pvp-automation-mode') === null) {
localStorage.setItem('smol-pvp-automation-mode', 'all');
}
if (localStorage.getItem('smol-pvp-automation-x-count') === null) {
localStorage.setItem('smol-pvp-automation-x-count', '0');
}
if (localStorage.getItem('smol-pvp-automation-x-remaining') === null) {
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
}
if (localStorage.getItem('smol-script-expanded') === null) {
localStorage.setItem('smol-script-expanded', 'false');
}
if (localStorage.getItem('smol-script-pvp-enabled') === null) {
localStorage.setItem('smol-script-pvp-enabled', 'true');
}
// 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('pvp-script-toggle')) {
const smolSettings = {
scriptPvpEnabled: localStorage.getItem('smol-script-pvp-enabled') === 'true'
};
const pvpDiv = document.createElement('div');
pvpDiv.innerHTML = `
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<span style="font-size: 12px; color: #888;">⚔️ PvP Script</span>
<input type="checkbox" id="pvp-script-toggle" ${smolSettings.scriptPvpEnabled ? 'checked' : ''}></input>
</div>
`;
scriptExpanded.appendChild(pvpDiv);
document.getElementById('pvp-script-toggle').addEventListener('change', (e) => {
localStorage.setItem('smol-script-pvp-enabled', e.target.checked.toString());
window.location.reload();
});
}
}
if (localStorage.getItem('smol-script-pvp-enabled') === 'true' && (window.location.pathname === '/pvp.php' || window.location.pathname === '/pvp_battle.php')) {
initPvPExtension();
}
}
function initPvPExtension() {
const currentPath = window.location.pathname;
if (currentPath.includes('pvp.php')) {
initPvPMods();
} else if (currentPath.includes('pvp_battle.php')) {
initPvPBattleMods();
}
createPvPHUD();
}
function initPvPMods() {
createPvPAutomationButton();
initPvPAutomation();
}
function initPvPBattleMods() {
initPvPAutomation();
hideConflictingElements();
startBattleStatsInterval();
}
var battleStatsInterval = null;
var lastBattleStats = null;
function startBattleStatsInterval() {
if (battleStatsInterval) return;
lastBattleStats = null;
battleStatsInterval = setInterval(() => {
if (getPvPAutomation()) {
clearInterval(battleStatsInterval);
battleStatsInterval = null;
return;
}
readBattleStats();
const currentStats = window.battleStats;
if (!lastBattleStats ||
lastBattleStats.enemyDamage !== currentStats.enemyDamage ||
lastBattleStats.yourDamage !== currentStats.yourDamage) {
updatePvPBattleStats();
lastBattleStats = { ...currentStats };
// Stop interval if stats are populated (content updated)
if (currentStats.enemyDamage > 0 || currentStats.yourDamage > 0) {
clearInterval(battleStatsInterval);
battleStatsInterval = null;
}
}
}, 500);
}
function stopBattleStatsInterval() {
if (battleStatsInterval) {
clearInterval(battleStatsInterval);
battleStatsInterval = null;
}
lastBattleStats = null;
}
function hideConflictingElements() {
setTimeout(() => {
const autoSlashBtn = document.getElementById('auto-slash-btn');
const pvpPredictionBox = document.getElementById('pvp-prediction-box');
if (autoSlashBtn) {
autoSlashBtn.style.display = 'none';
}
if (pvpPredictionBox) {
pvpPredictionBox.style.display = 'none';
}
}, 400);
}
function createPvPHUD() {
if (document.getElementById('pvp-hud-main')) return;
const hud = document.createElement('div');
hud.id = 'pvp-hud-main';
hud.className = 'veyra-glass';
// Load saved position or use default
const savedPosition = sessionStorage.getItem('pvp-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);
updatePvPHUD();
}
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('pvp-hud-position', JSON.stringify({
left: rect.left,
top: rect.top
}));
}
});
}
function updatePvPHUD() {
const hud = document.getElementById('pvp-hud-main');
if (!hud) return;
const isRunning = getPvPAutomation();
const coinsEl = document.querySelector('#pvp-coins');
const coins = coinsEl ? parseInt(coinsEl.textContent) : 0;
const automationMode = localStorage.getItem('smol-pvp-automation-mode') || 'all';
const remaining = parseInt(localStorage.getItem('smol-pvp-automation-x-remaining') || '0');
const isBattleOnly = localStorage.getItem('pvp-battle-only-mode') === 'true';
const currentPath = window.location.pathname;
const inBattlePage = currentPath.includes('pvp_battle.php');
let statusText = 'Idle';
if (isRunning) {
statusText = isBattleOnly ? 'Attack Only' : 'Fully Automated';
}
const content = `
<div class="veyra-header">
<div class="veyra-title">Veyra — PVP</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">
${!inBattlePage || !isBattleOnly ? `
<div class="veyra-row">
<div>Mode</div>
<div><select id="pvp-mode-select" class="veyra-select" ${isRunning ? 'disabled' : ''}>
<option value="all" ${automationMode === 'all' ? 'selected' : ''}>All Coins</option>
<option value="x" ${automationMode === 'x' ? 'selected' : ''}>X Times</option>
</select></div>
</div>
<div class="veyra-row" id="x-count-row" style="display: ${automationMode === 'x' ? 'flex' : 'none'}">
<div>Count</div>
<div><input id="pvp-x-count" type="number" class="veyra-input" min="1" max="20" value="${localStorage.getItem('smol-pvp-automation-x-count') || '1'}" ${isRunning ? 'disabled' : ''}></div>
</div>` : ''}
<div class="veyra-row">
<div>Auto PVP</div>
<div><button id="pvp-hud-toggle" class="veyra-btn">${isRunning ? 'Stop' : 'Start'}</button></div>
</div>
<div class="veyra-row">
<div>Auto Surrender</div>
<div><input id="smol-pvp-auto-surrender" type="checkbox" ${localStorage.getItem('smol-pvp-auto-surrend') === 'true' ? 'checked' : ''}></div>
</div>
${!inBattlePage ? `
<div class="veyra-row">
<div>Coins</div>
<div style="color:var(--glass-muted)">${coins}</div>
</div>
${automationMode === 'x' && isRunning ? `<div class="veyra-row"><div>Remaining</div><div style="color:var(--glass-muted)">${remaining}</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('pvp-hud-toggle');
const modeSelect = document.getElementById('pvp-mode-select');
const xCountInput = document.getElementById('pvp-x-count');
const xCountRow = document.getElementById('x-count-row');
if (toggleBtn && !toggleBtn.hasAttribute('data-listener-added')) {
toggleBtn.addEventListener('click', togglePvPFromHUD);
toggleBtn.setAttribute('data-listener-added', 'true');
}
if (modeSelect && !modeSelect.hasAttribute('data-listener-added')) {
modeSelect.addEventListener('change', (e) => {
localStorage.setItem('smol-pvp-automation-mode', e.target.value);
xCountRow.style.display = e.target.value === 'x' ? 'flex' : 'none';
});
modeSelect.setAttribute('data-listener-added', 'true');
}
if (xCountInput && !xCountInput.hasAttribute('data-listener-added')) {
xCountInput.addEventListener('change', (e) => {
const value = Math.max(1, Math.min(20, parseInt(e.target.value) || 1));
localStorage.setItem('smol-pvp-automation-x-count', value.toString());
e.target.value = value;
});
xCountInput.setAttribute('data-listener-added', 'true');
}
const autoSurrenderCheckbox = document.getElementById('smol-pvp-auto-surrender');
if (autoSurrenderCheckbox && !autoSurrenderCheckbox.hasAttribute('data-listener-added')) {
autoSurrenderCheckbox.addEventListener('change', (e) => {
localStorage.setItem('smol-pvp-auto-surrend', e.target.checked.toString());
});
autoSurrenderCheckbox.setAttribute('data-listener-added', 'true');
}
}, 100);
}
function togglePvPFromHUD() {
const isRunning = getPvPAutomation();
const currentPath = window.location.pathname;
if (isRunning) {
setPvPAutomation(false);
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
showNotification('PvP automation stopped', 'info');
} else {
if (currentPath.includes('pvp_battle.php')) {
// In battle page, just start attack loop and mark as battle-only mode
stopBattleStatsInterval();
localStorage.setItem('pvp-battle-only-mode', 'true');
setPvPAutomation(true);
showNotification('Attack loop started', 'success');
startBattleLoop();
} else {
// In pvp.php or other pages, start full automation
localStorage.removeItem('pvp-battle-only-mode');
const coinsEl = document.querySelector('#pvp-coins');
const coins = coinsEl ? parseInt(coinsEl.textContent) : 0;
const automationMode = localStorage.getItem('smol-pvp-automation-mode') || 'all';
if (coins === 0) {
showNotification('No PvP coins available', 'error');
return;
}
if (automationMode === 'x') {
const xCount = parseInt(localStorage.getItem('smol-pvp-automation-x-count') || '1');
if (xCount > coins) {
showNotification(`Not enough coins! You have ${coins} coins but need ${xCount}`, 'error');
return;
}
localStorage.setItem('smol-pvp-automation-x-remaining', xCount.toString());
showNotification(`Starting PvP automation for ${xCount} battles...`, 'success');
} else {
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
showNotification('Starting PvP automation for all coins...', 'success');
}
setPvPAutomation(true);
if (!window.location.pathname.includes('pvp.php') && !window.location.pathname.includes('pvp_battle.php')) {
window.location.href = 'pvp.php';
} else {
startPvPAutomation();
}
}
}
updatePvPHUD();
}
function createPvPAutomationButton() {
const heroRow = document.querySelector('.hero-row');
const btnStartTop = document.getElementById('btnStartTop');
if (heroRow && btnStartTop && !document.getElementById('btnAutomationAllPvp')) {
const automationAllBtn = document.createElement('button');
automationAllBtn.id = 'btnAutomationAllPvp';
automationAllBtn.className = 'hero-btn';
automationAllBtn.title = 'PvP Automation All Coin';
automationAllBtn.draggable = false;
automationAllBtn.textContent = 'Automate PvP (All Coins)';
automationAllBtn.addEventListener('click', togglePvPAutomationAll);
btnStartTop.insertAdjacentElement('afterend', automationAllBtn);
updatePvPHeroButtonState();
}
}
function updatePvPHeroButtonState() {
const allBtn = document.getElementById('btnAutomationAllPvp');
const coinsEl = document.querySelector('#pvp-coins');
const coins = coinsEl ? parseInt(coinsEl.textContent) : 1;
const isRunning = getPvPAutomation();
if (allBtn) {
if (coins === 0 && !isRunning) {
allBtn.disabled = true;
allBtn.style.cursor = 'not-allowed';
allBtn.textContent = 'No PvP Coins';
allBtn.style.background = '#6c7086';
} else {
allBtn.disabled = false;
allBtn.style.cursor = 'pointer';
if (isRunning) {
allBtn.textContent = 'Stop PvP';
allBtn.style.background = '#f38ba8';
} else {
allBtn.textContent = 'Automate PvP (All Coins)';
allBtn.style.background = '';
}
}
}
}
function initPvPAutomation() {
const currentPath = window.location.pathname;
if (currentPath.includes('pvp_battle.php')) {
if (getPvPAutomation()) {
window.alert = () => true;
window.confirm = () => true;
window.prompt = () => true;
}
createPvPBattleHUD();
createPvPStopButton();
if (getPvPAutomation()) {
startBattleLoop();
}
} else if (currentPath.includes('pvp.php')) {
updatePvPHeroButtonState();
if (getPvPAutomation()) {
setTimeout(checkCoinsAndBattle, 1000);
}
}
}
function createPvPBattleHUD() {
const myHpText = document.getElementById('myHpText');
if (!myHpText || document.getElementById('pvp-battle-hud')) return;
const hudDiv = document.createElement('div');
hudDiv.id = 'pvp-battle-hud';
hudDiv.innerHTML = `
<div style="border-bottom: 1px solid; margin: 8px 0;"></div>
<div>
<div>⚔️ Enemy Damage: <span id="pvp-stats-enemy-damage">0</span></div>
<div style="margin-bottom: 10px">⚔️ Your Damage: <span id="pvp-stats-your-damage">0</span></div>
<div class="pvp-chip" id="pvp-prediction">Waiting Attack</div>
</div>
<div style="border-bottom: 1px solid; margin: 8px 0;"></div>
`;
myHpText.insertAdjacentElement('afterend', hudDiv);
}
function createPvPStopButton() {
const attackBtnWrap = document.querySelector('.attack-btn-wrap');
if (!attackBtnWrap || document.getElementById('pvp-stop-btn')) return;
const stopBtn = document.createElement('button');
stopBtn.id = 'pvp-stop-btn';
stopBtn.style.cssText = `
background: linear-gradient(180deg, #74c0fc, #5aa3e0);
border: 1px solid #88ccffff;
color: white;
padding: 10px 14px;
border-radius: 12px;
cursor: pointer;
box-shadow: 0 8px 18px rgb(238 59 125 / 28%);
min-width: 140px;
font-weight: 700;
font-size: 14px;
letter-spacing: .2px;
line-height: 1rem;
`;
stopBtn.addEventListener('click', handlePvPStopButtonClick);
attackBtnWrap.appendChild(stopBtn);
updatePvPStopButtonState();
}
function updatePvPStopButtonState() {
const stopBtn = document.getElementById('pvp-stop-btn');
if (!stopBtn) return;
const isPvPRunning = getPvPAutomation();
if (isPvPRunning) {
stopBtn.textContent = '⏹️ Stop Auto';
stopBtn.style.background = 'linear-gradient(180deg, #eb4582, #d33855)';
stopBtn.style.border = '1px solid #ef6095';
} else {
stopBtn.textContent = '⚔️ Start Auto';
stopBtn.style.background = 'linear-gradient(180deg, #74c0fc, #5aa3e0)';
stopBtn.style.border = '1px solid #88ccffff';
}
}
function handlePvPStopButtonClick() {
const isPvPRunning = getPvPAutomation();
if (isPvPRunning) {
setPvPAutomation(false);
window.alert = originalAlert;
window.confirm = originalConfirm;
window.prompt = originalPrompt;
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
updatePvPHeroButtonState();
updatePvPStopButtonState();
showNotification('Attack loop stopped', 'info');
} else {
// In battle page, just start attack loop and mark as battle-only mode
stopBattleStatsInterval();
localStorage.setItem('pvp-battle-only-mode', 'true');
setPvPAutomation(true);
updatePvPStopButtonState();
showNotification('Attack loop started', 'success');
startBattleLoop();
}
updatePvPHUD();
}
function updatePvPBattleStats() {
const enemyDamageEl = document.getElementById('pvp-stats-enemy-damage');
const yourDamageEl = document.getElementById('pvp-stats-your-damage');
const predictionEl = document.getElementById('pvp-prediction');
if (!enemyDamageEl || !yourDamageEl || !predictionEl) return;
readBattleStats();
const stats = window.battleStats || { enemyDamage: 0, yourDamage: 0 };
enemyDamageEl.textContent = stats.enemyDamage;
yourDamageEl.textContent = stats.yourDamage;
if (stats.enemyDamage === 0 || stats.yourDamage === 0) {
predictionEl.textContent = 'Waiting Attack';
predictionEl.className = 'pvp-chip';
} else {
const enemyHealthEl = document.getElementById('enemyHpText');
const yourHealthEl = document.getElementById('myHpText');
const enemyMaxHealth = enemyHealthEl ? parseInt(enemyHealthEl.textContent.split('/')[1].replace(/[^0-9,.]/g, '')) : 0;
const yourMaxHealth = yourHealthEl ? parseInt(yourHealthEl.textContent.split('/')[1].replace(/[^0-9,.]/g, '')) : 0;
const atkNeeded = enemyMaxHealth / stats.yourDamage;
const enemyAtkNeeded = yourMaxHealth / stats.enemyDamage;
if (enemyAtkNeeded > atkNeeded) {
predictionEl.textContent = 'You will WIN';
predictionEl.className = 'pvp-chip success';
} else {
predictionEl.textContent = 'You will LOSE';
predictionEl.className = 'pvp-chip danger';
}
}
}
// PvP Automation System
function getPvPAutomation() {
return localStorage.getItem('smol-pvp-automation') === 'true';
}
function setPvPAutomation(value) {
localStorage.setItem('smol-pvp-automation', value.toString());
}
function togglePvPAutomationAll() {
const coinsEl = document.querySelector('#pvp-coins');
const coins = coinsEl ? parseInt(coinsEl.textContent) : 0;
const isRunning = getPvPAutomation();
if (isRunning) {
setPvPAutomation(false);
localStorage.setItem('smol-pvp-automation-mode', 'all');
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
updatePvPHeroButtonState();
showNotification('PvP automation stopped', 'info');
return;
}
if (coins === 0) {
showNotification('No PvP coins available', 'error');
return;
}
localStorage.setItem('smol-pvp-automation-mode', 'all');
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
setPvPAutomation(true);
updatePvPHeroButtonState();
if (!window.location.pathname.includes('pvp.php') && !window.location.pathname.includes('pvp_battle.php')) {
showNotification('Starting PvP automation for all coins...', 'success');
window.location.href = 'pvp.php';
} else {
showNotification('Starting PvP automation for all coins...', 'success');
startPvPAutomation();
}
}
function startPvPAutomation() {
if (!getPvPAutomation()) return;
if (window.location.pathname.includes('pvp.php')) {
checkCoinsAndBattle();
} else if (window.location.pathname.includes('pvp_battle.php')) {
startBattleLoop();
}
}
function checkCoinsAndBattle() {
if (!getPvPAutomation()) return;
const coinsEl = document.querySelector('#pvp-coins');
if (!coinsEl) {
setTimeout(checkCoinsAndBattle, 1000);
return;
}
const coins = parseInt(coinsEl.textContent);
const automationMode = localStorage.getItem('smol-pvp-automation-mode') || 'all';
const remaining = parseInt(localStorage.getItem('smol-pvp-automation-x-remaining') || '0');
// Check stopping conditions
if (automationMode === 'x' && remaining <= 0) {
showNotification('PvP automation completed', 'success');
setPvPAutomation(false);
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
updatePvPHeroButtonState();
return;
}
if (coins <= 0) {
showNotification('No more PVP coins available', 'warning');
setPvPAutomation(false);
localStorage.setItem('smol-pvp-automation-x-remaining', '0');
updatePvPHeroButtonState();
updatePvPHUD();
return;
}
performSingleBattle().then(async () => {
setTimeout(() => {
window.location.href = 'https://demonicscans.org/pvp.php';
}, 1000);
});
}
function performSingleBattle() {
const automationMode = localStorage.getItem('smol-pvp-automation-mode') || 'all';
const remaining = parseInt(localStorage.getItem('smol-pvp-automation-x-remaining') || '0');
if (automationMode === 'x') {
const newRemaining = remaining - 1;
localStorage.setItem('smol-pvp-automation-x-remaining', newRemaining.toString());
}
return new Promise((resolve) => {
const startBtn = document.querySelector('#btnStartTop');
if (!startBtn) {
resolve();
return;
}
startBtn.click();
const attackLoop = async () => {
if (!getPvPAutomation()) {
resolve();
return;
}
const endBody = document.querySelector('#endBody');
if (endBody && endBody.textContent.trim() !== '') {
resolve();
return;
}
// Check for auto surrender
if (localStorage.getItem('smol-pvp-auto-surrend') === 'true') {
const stats = window.battleStats;
if (stats && stats.enemyDamage > 0 && stats.yourDamage > 0) {
const enemyHealthEl = document.getElementById('enemyHpText');
const yourHealthEl = document.getElementById('myHpText');
const enemyMaxHealth = enemyHealthEl ? parseInt(enemyHealthEl.textContent.split('/')[1].replace(/[^0-9,.]/g, '')) : 0;
const yourMaxHealth = yourHealthEl ? parseInt(yourHealthEl.textContent.split('/')[1].replace(/[^0-9,.]/g, '')) : 0;
const atkNeeded = enemyMaxHealth / stats.yourDamage;
const enemyAtkNeeded = yourMaxHealth / stats.enemyDamage;
if (enemyAtkNeeded < atkNeeded) {
const surrenderBtn = document.getElementById('btnSurrender');
if (surrenderBtn) {
surrenderBtn.click();
resolve();
return;
}
}
}
}
const attackBtn = document.querySelector('.attack-btn.skill-btn[data-cost="1"]');
if (attackBtn && attackBtn.offsetParent !== null) {
attackBtn.click();
setTimeout(() => {
readBattleStats();
updatePvPBattleStats();
}, 500);
}
setTimeout(attackLoop, 1070);
};
attackLoop();
});
}
function startBattleLoop() {
if (!getPvPAutomation()) return;
const endBody = document.querySelector('#endBody');
if (endBody && endBody.textContent.trim() !== '') {
// Check if this is battle-only mode (triggered from battle page buttons)
if (localStorage.getItem('pvp-battle-only-mode') === 'true') {
setPvPAutomation(false);
localStorage.removeItem('pvp-battle-only-mode');
updatePvPStopButtonState();
updatePvPHUD();
showNotification('Battle finished - Attack loop stopped', 'info');
return;
}
// Full automation mode - continue to next battle
setTimeout(() => {
window.location.href = 'https://demonicscans.org/pvp.php';
}, 2000);
return;
}
// Check for auto surrender
if (localStorage.getItem('smol-pvp-auto-surrend') === 'true') {
const stats = window.battleStats;
if (stats && stats.enemyDamage > 0 && stats.yourDamage > 0) {
const enemyHealthEl = document.getElementById('enemyHpText');
const yourHealthEl = document.getElementById('myHpText');
const enemyMaxHealth = enemyHealthEl ? parseInt(enemyHealthEl.textContent.split('/')[1].replace(/[^0-9,.]/g, '')) : 0;
const yourMaxHealth = yourHealthEl ? parseInt(yourHealthEl.textContent.split('/')[1].replace(/[^0-9,.]/g, '')) : 0;
const atkNeeded = enemyMaxHealth / stats.yourDamage;
const enemyAtkNeeded = yourMaxHealth / stats.enemyDamage;
if (enemyAtkNeeded <= atkNeeded) {
const surrenderBtn = document.getElementById('btnSurrender');
if (surrenderBtn) {
surrenderBtn.click();
setTimeout(() => {
window.location.href = 'https://demonicscans.org/pvp.php';
}, 2000);
return;
}
}
}
}
const attackBtn = document.querySelector('.attack-btn.skill-btn[data-cost="1"]');
if (attackBtn && attackBtn.offsetParent !== null) {
attackBtn.click();
setTimeout(() => {
readBattleStats();
updatePvPBattleStats();
}, 500);
}
setTimeout(startBattleLoop, 1000);
}
function readBattleStats() {
const logItems = document.querySelectorAll('#logWrap .log-item .log-left');
const enemyDamage = logItems.length > 0 ? logItems[0].querySelector('strong')?.innerText || 0 : 0;
const yourDamage = logItems.length > 1 ? logItems[1].querySelector('strong')?.innerText || 0 : 0;
window.battleStats = {
enemyDamage: parseInt(enemyDamage.toString().replace(/,/g, '')) || 0,
yourDamage: parseInt(yourDamage.toString().replace(/,/g, '')) || 0
};
}
function showNotification(msg, type = 'success') {
let note = document.getElementById('pvp-notification');
if (!note) {
note = document.createElement('div');
note.id = 'pvp-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); }
.pvp-chip {
text-align: center;
color: #fafafa;
border-radius: 999px;
padding: 4px 6px;
font-weight: 600;
font-size: 12px;
}
.pvp-chip.danger {
color: #bb2d2d;
border: 1px solid #d33939;
}
.pvp-chip.success {
color: #3ddd65;
border: 1px solid #45e26d;
}
.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;
}
`;
document.head.appendChild(style);
})();