49 lines
2.1 KiB
JavaScript
49 lines
2.1 KiB
JavaScript
// Captcha detection via MutationObserver
|
|
// Watches document.body for #hcaptcha_window being added/removed.
|
|
// Confirmed selector from live DOM: DIV#hcaptcha_window > DIV.h-captcha
|
|
// ----------------------------------------------------------------
|
|
let captchaActive = false;
|
|
|
|
function reportCaptcha(detected) {
|
|
const player_id = uw.Game?.player_id;
|
|
if (!player_id) return;
|
|
fetch(`${BASE_URL}/api/captcha/alert?player_id=${player_id}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ detected })
|
|
}).catch(e => log(`captcha report failed: ${e}`));
|
|
}
|
|
|
|
function detectCaptcha() {
|
|
setInterval(() => {
|
|
const win = document.getElementById('hcaptcha_window');
|
|
let isVisible = false;
|
|
|
|
if (win) {
|
|
// Check if it's actually visible on screen (not display: none by the game)
|
|
const style = window.getComputedStyle(win);
|
|
if (style.display !== 'none' && style.visibility !== 'hidden') {
|
|
isVisible = true;
|
|
}
|
|
}
|
|
|
|
if (isVisible && !captchaActive) {
|
|
captchaActive = true;
|
|
paused = true;
|
|
const label = document.getElementById('grc_label');
|
|
const btn = document.getElementById('grc_btn');
|
|
if (label) label.textContent = '⚠ CAPTCHA';
|
|
if (btn) btn.style.filter = 'brightness(70%) sepia(100%) hue-rotate(300deg) saturate(1000%) contrast(0.8)';
|
|
log('⚠ CAPTCHA detected — bot paused, alerting server');
|
|
reportCaptcha(true);
|
|
} else if (!isVisible && captchaActive) {
|
|
captchaActive = false;
|
|
// Don't auto-resume — let the user click the button manually
|
|
log('✅ Captcha resolved — alert cleared (bot remains paused)');
|
|
reportCaptcha(false);
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|