-
-
Save Kitue/2431baa6df27d782dc0d6c9ca503331f to your computer and use it in GitHub Desktop.
Counts daily total battles, daily battles per opponent and obelisk skirmish battles.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Neopets Battle Counter | |
// @version 1.4 | |
// @description Counts your total daily battles, battles per day per opponent (displayed on relevant opponent page only) and tracks your total Obelisk battles per skirmish. | |
// @author Raven | |
// @match *://www.neopets.com/dome/arena.phtml | |
// @grant none | |
// ==/UserScript== | |
(function () { | |
'use strict'; | |
// CONFIGURABLE SETTINGS // Change between true/false to edit how counts are displayed | |
const showTotalBattleCount = true; // Display a daily count of all your battles (resets daily) | |
const showObeliskBattleCount = true; // Display a count of your total skirmish battles (resets at start of new skirmish) | |
const showOpponentBattleCount = true; // Display a daily count for battles vs the active opponent (resets daily) | |
const recordWinsOnly = false; // Set to true to record only wins, set to false to record all battles including draws and losses | |
const OnlyOnObeliskPage = true; // Show Obelisk counter only when battling Obelisk opponents | |
// END CONFIGURABLE SETTINGS // | |
let battleCounted = false; | |
const BattleRecordAge = 7; // In days | |
// Create a counter container in the middle of the popup | |
function createCounterContainer() { | |
const popupContents = document.querySelector('.bdPopupGeneric.middle'); | |
if (!popupContents) return null; | |
let counterContainer = document.getElementById('battleCounterContainer'); | |
if (!counterContainer) { | |
counterContainer = document.createElement('div'); | |
counterContainer.id = 'battleCounterContainer'; | |
counterContainer.style.position = 'absolute'; | |
counterContainer.style.bottom = '10px'; | |
counterContainer.style.width = '98%'; | |
counterContainer.style.margin = '5px'; | |
counterContainer.style.borderRadius = '4px'; | |
counterContainer.style.backgroundColor = '#FFFFFF'; | |
counterContainer.style.zIndex = '1000'; | |
counterContainer.style.textAlign = 'center'; | |
counterContainer.style.display = 'flex'; | |
counterContainer.style.flexDirection = 'column'; | |
counterContainer.style.gap = '0px'; | |
popupContents.appendChild(counterContainer); | |
} | |
return counterContainer; | |
} | |
function createCombinedCounter() { | |
const counterContainer = createCounterContainer(); | |
if (!counterContainer) return; | |
let combinedCounter = document.getElementById('combinedBattleCounter'); | |
if (!combinedCounter) { | |
combinedCounter = document.createElement('div'); | |
combinedCounter.id = 'combinedBattleCounter'; | |
combinedCounter.style.padding = '2px'; | |
combinedCounter.style.width = '90%'; | |
combinedCounter.style.margin = '0 auto'; | |
combinedCounter.style.display = 'block'; | |
counterContainer.appendChild(combinedCounter); | |
} | |
updateCombinedCounter(); | |
} | |
// Update the combined counter to display battle counts | |
function updateCombinedCounter() { | |
const totalCount = showTotalBattleCount ? (localStorage.getItem('totalBattleCount') || '0') : null; | |
const obeliskCount = showObeliskBattleCount ? (localStorage.getItem('obeliskBattleCount') || '0') : null; | |
const combinedCounter = document.getElementById('combinedBattleCounter'); | |
if (combinedCounter) { | |
let displayText = ''; | |
if (totalCount !== null) { | |
displayText += `Total Daily ${recordWinsOnly ? 'Wins' : 'Battles'}: <span style="color: #C41E3A;">${parseInt(totalCount).toLocaleString()}</span>`; | |
} | |
if (obeliskCount !== null && parseInt(obeliskCount) > 0 && (!OnlyOnObeliskPage || isObeliskOpponent())) { | |
if (displayText) displayText += ' | '; | |
displayText += `Skirmish ${recordWinsOnly ? 'Wins' : 'Battles'}: <span style="color: #C41E3A;">${parseInt(obeliskCount).toLocaleString()}</span>`; | |
} | |
if (displayText) { | |
combinedCounter.innerHTML = `<strong>${displayText}</strong>`; | |
combinedCounter.style.display = 'block'; | |
} else { | |
combinedCounter.style.display = 'none'; | |
} | |
} | |
} | |
// Add obelisk contribution (for debugging) | |
function addObeliskContribution() { | |
const div = document.createElement('div'); // Declare the `div` variable | |
div.textContent = "Obelisk Contribution Added"; | |
document.body.appendChild(div); // Append the div to the document body | |
return "Obelisk contribution added successfully!"; | |
} | |
window.addObeliskContribution = addObeliskContribution; | |
// Initialize opponent-specific counters | |
function initializeOpponentCounter(opponentName) { | |
const counterId = `battleCount-${opponentName}`; | |
const label = `Daily ${recordWinsOnly ? 'Wins' : 'Battles'} VS ${opponentName}`; | |
const container = createCounterContainer(); | |
if (!document.getElementById(counterId)) { | |
const opponentCounter = document.createElement('div'); | |
opponentCounter.id = counterId; | |
opponentCounter.style.backgroundColor = 'rgba(255, 255, 255, 0.9)'; | |
opponentCounter.style.padding = '4px'; | |
opponentCounter.style.borderRadius = '4px'; | |
opponentCounter.style.width = '90%'; | |
opponentCounter.style.margin = '0 auto'; | |
opponentCounter.innerHTML = `<strong>${label}: <span id="${counterId}-value" style="color: #C41E3A;">0</span></strong>`; | |
container.appendChild(opponentCounter); | |
} | |
resetCounterIfNecessary(counterId); | |
const storedValue = localStorage.getItem(counterId) || '0'; | |
updateCounter(counterId, storedValue); | |
} | |
// Reset counter if necessary (e.g., daily reset) | |
function resetCounterIfNecessary(counterKey, resetDays = 1) { | |
const currentDate = new Date(); | |
const pstDate = new Date(currentDate.toLocaleString('en-US', { timeZone: 'America/Los_Angeles' })); | |
const midnightPST = new Date(pstDate.setHours(0, 0, 0, 0)); | |
const storedDate = localStorage.getItem(`${counterKey}-date`); | |
const lastDate = storedDate ? new Date(storedDate) : null; | |
const storedTimestamp = localStorage.getItem(`${counterKey}-timestamp`); | |
const lastTimestamp = storedTimestamp ? new Date(storedTimestamp) : null; | |
const sevenDaysAgo = new Date(currentDate - BattleRecordAge * 24 * 60 * 60 * 1000); | |
if (lastTimestamp && lastTimestamp < sevenDaysAgo) { | |
localStorage.removeItem(counterKey); // Remove the old records | |
localStorage.removeItem(`${counterKey}-timestamp`); | |
localStorage.removeItem(`${counterKey}-date`); | |
} | |
if (counterKey === 'obeliskBattleCount') { | |
const isMonday = pstDate.getDay() === 1; // 0 = Sunday, 1 = Monday | |
if (!lastDate || (isMonday && pstDate >= midnightPST && pstDate.getDate() !== lastDate.getDate())) { | |
localStorage.setItem(`${counterKey}-date`, midnightPST.toISOString()); | |
localStorage.setItem(counterKey, '0'); | |
} | |
} else { | |
if (!lastDate || pstDate >= midnightPST && pstDate.getDate() !== lastDate.getDate()) { | |
localStorage.setItem(`${counterKey}-date`, midnightPST.toISOString()); | |
localStorage.setItem(counterKey, '0'); | |
} | |
} | |
} | |
// Check if current opponent is from the Obelisk section | |
function isObeliskOpponent() { | |
const p2headshot = document.querySelector('#p2headshot'); | |
if (p2headshot) { | |
const backgroundImage = p2headshot.style.backgroundImage || ''; | |
const obeliskFactions = ['_order', '_thief', '_awakened', '_seekers', '_brute', '_sway']; | |
return obeliskFactions.some((faction) => backgroundImage.includes(faction)); | |
} | |
return false; | |
} | |
// Increment the counter based on the key | |
function incrementCounter(counterKey, opponent, resetDays = 1) { | |
resetCounterIfNecessary(counterKey, resetDays); | |
const currentCount = parseInt(localStorage.getItem(counterKey) || '0', 10) + 1; | |
localStorage.setItem(counterKey, currentCount); | |
localStorage.setItem(`${counterKey}-timestamp`, new Date().toISOString()); | |
if (opponent) { | |
const opponentKey = `battleCount-${opponent}`; | |
resetCounterIfNecessary(opponentKey, resetDays); | |
const opponentCount = parseInt(localStorage.getItem(opponentKey) || '0', 10) + 1; | |
localStorage.setItem(opponentKey, opponentCount); | |
localStorage.setItem(`${opponentKey}-timestamp`, new Date().toISOString()); | |
return opponentCount; | |
} | |
return currentCount; | |
} | |
// Update the counter displayed on the page | |
function updateCounter(counterId, value) { | |
const counterElement = document.getElementById(`${counterId}-value`); | |
if (counterElement) { | |
counterElement.textContent = parseInt(value).toLocaleString(); | |
} | |
} | |
// Clean up expired records | |
function cleanupExpiredRecords() { | |
const now = new Date(); | |
const sevenDaysAgo = new Date(now - BattleRecordAge * 24 * 60 * 60 * 1000); | |
Object.keys(localStorage).forEach((key) => { | |
if (key.endsWith('-timestamp')) { | |
const timestamp = new Date(localStorage.getItem(key)); | |
if (timestamp < sevenDaysAgo) { | |
const baseKey = key.replace('-timestamp', ''); | |
localStorage.removeItem(baseKey); | |
localStorage.removeItem(key); | |
localStorage.removeItem(`${baseKey}-date`); | |
} | |
} | |
}); | |
} | |
// Initialize all counters | |
function initializeCounters() { | |
createCombinedCounter(); | |
const opponent = getOpponentName(); | |
if (showOpponentBattleCount && opponent !== 'Unknown Opponent') { | |
initializeOpponentCounter(opponent); | |
} | |
if (!checkInitialHP()) { | |
return; // Do not initialize counters if either starts with 0 HP | |
} | |
const hpCheckInterval = setInterval(() => { | |
handleBattle(opponent); | |
if (battleCounted) clearInterval(hpCheckInterval); | |
}, 1000); | |
const rewardsObserver = new MutationObserver(() => { | |
const rewardText = document.querySelector('#bd_rewards .rewardstext'); | |
if (rewardText) { | |
rewardText.style.paddingTop = '0'; | |
const rewardsLoot = document.querySelector('#bd_rewardsloot'); | |
if (rewardsLoot) rewardsLoot.style.height = '100px'; | |
rewardsObserver.disconnect(); | |
} | |
}); | |
rewardsObserver.observe(document, { childList: true, subtree: true }); | |
} | |
// Get current opponent name | |
function getOpponentName() { | |
const opponentElement = document.querySelector('#p2name'); | |
return opponentElement ? opponentElement.textContent.trim() : 'Unknown Opponent'; | |
} | |
// Check initial HP status for both participants | |
function checkInitialHP() { | |
const p1hp = document.querySelector('#p1hp'); | |
const p2hp = document.querySelector('#p2hp'); | |
if (p1hp && p2hp) { | |
const p1InitialHP = parseInt(p1hp.textContent.trim(), 10); | |
const p2InitialHP = parseInt(p2hp.textContent.trim(), 10); | |
if (p1InitialHP <= 0 || p2InitialHP <= 0) { | |
console.warn('Battle not counted: Initial HP is 0 for one or both participants.'); | |
return false; | |
} | |
} | |
return true; | |
} | |
// Handle the battle detection and counting | |
function handleBattle(opponent) { | |
if (battleCounted) return; | |
const p1hp = document.querySelector('#p1hp'); | |
const p2hp = document.querySelector('#p2hp'); | |
if (p1hp && p2hp) { | |
const p1hpValue = parseInt(p1hp.textContent.trim(), 10); | |
const p2hpValue = parseInt(p2hp.textContent.trim(), 10); | |
// Determine whether to count the battle | |
if ( | |
(recordWinsOnly && p2hpValue === 0 && p1hpValue > 0) || // Only count wins if recordWinsOnly is true | |
(!recordWinsOnly && (p1hpValue === 0 || p2hpValue === 0)) // Count all battles if recordWinsOnly is false | |
) { | |
battleCounted = true; | |
// Increment the total battle count | |
incrementCounter('totalBattleCount'); | |
// Increment obelisk battle count if applicable | |
if (isObeliskOpponent()) { | |
incrementCounter('obeliskBattleCount'); | |
localStorage.setItem('obeliskBattleCount-date', new Date().toISOString()); | |
} | |
// Increment opponent-specific count if applicable | |
if (opponent !== 'Unknown Opponent') { | |
const opponentKey = `battleCount-${opponent}`; | |
const opponentCount = incrementCounter(opponentKey); | |
updateCounter(opponentKey, opponentCount); | |
} | |
// Update the combined counter display | |
updateCombinedCounter(); | |
} | |
} | |
} | |
cleanupExpiredRecords(); // Run cleanup on script initialization | |
const observer = new MutationObserver((mutations, me) => { | |
try { | |
if ( | |
document.querySelector('#p2name') && | |
document.querySelector('.bdPopupGeneric.middle') && | |
document.querySelector('#p1hp') && | |
document.querySelector('#p2hp') | |
) { | |
initializeCounters(); | |
addObeliskContribution(); // Call the function here | |
me.disconnect(); | |
} | |
} catch (error) { | |
console.error('Error in MutationObserver:', error); | |
} | |
}); | |
observer.observe(document, { childList: true, subtree: true }); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment