hv-unified/src/page-detector.js
GaboGG 4bc90d9332 Monster Lab floating panel + page detection, Beast recommendation
- Monster Lab page detected via ss=ml
- Floating draggable panel replaces inline UI (was messing layout)
- Feed All + Happy Pills All buttons
- Class recommendation for first monster
- Drag-to-move via header grab
2026-07-20 20:35:14 -04:00

100 lines
3.3 KiB
JavaScript

// ═══════════════════════════════════════════════════════════════════════
// PAGE DETECTOR — detect current page and player level
// ═══════════════════════════════════════════════════════════════════════
function detectPage() {
// Battle page detection by DOM elements (most reliable)
if (document.getElementById('textlog') ||
document.getElementById('riddlemaster') ||
document.getElementById('pane_vitals') ||
document.getElementById('battle_root')) {
return 'battle';
}
// URL-based page detection
const url = window.location.href || '';
const pages = {
'ss=ch': 'character',
'ss=eq': 'equipshop',
'ss=is': 'itemshop',
'ss=am': 'armory',
'ss=ar': 'arena',
'ss=gr': 'grindfest',
'ss=iw': 'itemworld',
'ss=ml': 'monsterlab',
'ss=sh': 'shrine',
'ss=mm': 'mooglemail',
'ss=tr': 'training',
'ss=rb': 'ring',
'ss=re': 'repair',
'ss=up': 'upgrade',
'ss=en': 'enchant',
'ss=sv': 'salvage',
'ss=rf': 'reforge',
'ss=sf': 'soulfuse',
'ss=ab': 'abilities',
'ss=ml': 'monster',
'ss=it': 'invitems',
'ss=se': 'settings',
'ss=ss': 'spiritshop',
'ss=mk': 'market',
'ss=lt': 'lottery',
'ss=la': 'lastarena',
};
for (const [param, page] of Object.entries(pages)) {
if (url.includes(param)) return page;
}
return 'bazaar';
}
function isBattlePage() {
return !!(document.getElementById('textlog') ||
document.getElementById('riddlemaster') ||
document.getElementById('pane_vitals'));
}
function detectLevel() {
const container = document.querySelector('#level_readout > div');
if (!container) {
try {
const s = parseInt(localStorage[SP + 'playerLevel']);
if (s > 0) STATE.level = s;
} catch (e) {}
return;
}
// Battle page format: innerText = "Normal Lv.10"
const text = (container.innerText || container.textContent || '').trim();
const textMatch = text.match(/(\w+)\s+Lv\.?\s*(\d+)/);
if (textMatch) {
STATE.difficulty = textMatch[1];
STATE.level = parseInt(textMatch[2]) || 1;
updateTier();
return;
}
// CSS-font rendering (overworld page): "Nightmare Lv.52"
const cssText = readCSSText(container);
const cssMatch = cssText.match(/(\w+)\s+lv\.\s*(\d+)/i);
if (cssMatch) {
STATE.difficulty = cssMatch[1].charAt(0).toUpperCase() + cssMatch[1].slice(1);
cacheDifficulty();
}
// CSS-digit rendering for level number
const digits = readCSSDigits(container);
if (digits !== null && digits > 0) {
STATE.level = digits;
updateTier();
}
if (STATE.level > 1) {
try { localStorage[SP + 'playerLevel'] = STATE.level; } catch (e) {}
}
}
function updateTier() {
const lv = STATE.level || 1;
STATE.tier = lv >= 300 ? 'master' : lv >= 150 ? 'veteran' : lv >= 50 ? 'adept' : 'novice';
}