');
$hintsPanel.insertAfter($rightBar.children().eq(3)).append($hintsBox);
// --- INICIO: Botón de Victoria Instantánea (Totalmente Independiente y Toggle) ---
const $instantWinButton = $('');
$instantWinButton.insertAfter($hintsPanel);
// Habilitar desde el inicio (asumiendo que allWordLists está disponible globalmente)
$instantWinButton.prop('disabled', allWordLists === null);
$instantWinButton.on('click', async () => {
if (isInstantWinActive) {
// Si ya está activo, es un clic para DETENER
isInstantWinActive = false;
$instantWinButton.prop('disabled', false).text('Adivinar Rapido');
console.log('[Instant Win] Envío de batches detenido manualmente.');
$hintsBox.prepend('Envío detenido manualmente. ');
return;
}
// Si no está activo, es un clic para INICIAR
if (!allWordLists) {
console.error("[Instant Win] La lista de palabras no está disponible (allWordLists es null).");
alert('Error: La lista de palabras no está cargada. Por favor, recarga la página.');
return;
}
// Determinar el idioma actual del juego
const gameLang = $('#langselector').val();
const wordsForLang = allWordLists[gameLang] || allWordLists['en']; // Fallback a inglés
if (!wordsForLang || wordsForLang.length === 0) {
console.warn(`[Instant Win] Lista de palabras vacía para el idioma '${gameLang}'.`);
alert(`No se pudo encontrar la lista de palabras para el idioma '${gameLang}'.`);
return;
}
const batchesToSend = generateNinetyNineCharBatches(wordsForLang);
if (batchesToSend.length === 0) {
console.warn("[Instant Win] No se pudieron generar batches de palabras para enviar. Lista de idioma vacía o palabras muy largas.");
alert('No se pudieron generar batches para enviar. Intenta de nuevo.');
return;
}
console.warn(`[Instant Win] Iniciando envío de ${batchesToSend.length} batches agresivamente. El chat puede congelarse o fallar. ALTA PROBABILIDAD DE SILENCIAMIENTO/DESCONEXIÓN.`);
$instantWinButton.text('Detener Envío'); // Botón ahora es para detener
// No deshabilitar el botón, ya que es un toggle
isInstantWinActive = true; // Activar el flag de envío
const delayBetweenBatches = 700; // Retraso en milisegundos entre el envío de cada batch
for (let i = 0; i < batchesToSend.length; i++) {
if (!isInstantWinActive) { // Verificar si el flag se ha desactivado
console.log("[Instant Win] Proceso de envío de batches interrumpido.");
break;
}
const batch = batchesToSend[i];
if ($inputChat.is(':hidden') || $inputChat.prop('disabled')) {
console.error('[Instant Win] Chat input no está visible o está deshabilitado. Deteniendo envío.');
isInstantWinActive = false; // Desactivar flag si falla el envío
break;
}
$inputChat.val(batch);
$sendButton.click();
console.log(`[Instant Win Progress] Enviado Batch ${i+1}/${batchesToSend.length}: ${batch.substring(0, 30)}...`);
await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
}
// Finalización del ciclo (ya sea por completar o por interrupción)
if (isInstantWinActive) { // Si terminó sin interrupción
console.log('[Instant Win] Proceso de envío de batches completado. Revisa el chat para el resultado.');
$hintsBox.prepend('Envío de batches completado. Revisa el chat. ');
}
$instantWinButton.prop('disabled', false).text('Adivinar Rapido'); // Re-habilitar y resetear texto
isInstantWinActive = false; // Asegurar que el flag esté en false al finalizar
});
// --- FIN: Botón de Victoria Instantánea ---
// --- Handler para palabras clickeadas en la lista de sugerencias ---
$("body").on('click', '.hintClick', event => {
$inputChat.val(event.target.innerHTML);
$sendButton.click();
});
// --- Lógica para generar y mostrar sugerencias (panel izquierdo - NO AFECTA AL BOTÓN VICTORIA INSTANTÁNEA) ---
const assist = () => {
$hintsBox.empty(); // Limpiar el cuadro de sugerencias primero
if (!allWordLists) {
$hintsBox.append('Cargando lista de palabras...');
lastGeneratedHints = [];
return;
}
const gameLang = $('#langselector').val();
const currentLangWordList = allWordLists[gameLang] || allWordLists['en']; // Fallback a inglés
if (!currentLangWordList || currentLangWordList.length === 0) {
$hintsBox.append(`Lista de palabras no disponible para '${gameLang}'.`);
lastGeneratedHints = [];
return;
}
const targetWordText = $targetWord.text(); // El texto como "_ _ _ _ _" o "A _ _ L E"
let hints;
// MODIFICACIÓN CLAVE: Si la palabra objetivo es genérica o vacía, usa todas las palabras.
const isGenericPattern = !targetWordText ||
targetWordText.replace(/\s/g, '').replace(/_/g, '').trim() === '' ||
targetWordText.includes('?');
if (isGenericPattern) {
hints = currentLangWordList; // Muestra TODAS las palabras si el patrón es genérico
} else {
// Convertir la palabra objetivo a un patrón regex (ej. "_ _ A _ _" -> "^. . A . . $")
const regexPattern = targetWordText.replace(/\s/g, '').replace(/_/g, '.');
const wordRegex = new RegExp(`^${regexPattern}$`, 'i');
hints = currentLangWordList.filter(word => wordRegex.test(word));
}
lastGeneratedHints = []; // Siempre limpiar, esta lista es para el panel
if (hints.length === 0) {
$hintsBox.append('Lo siento, no se encontró ninguna palabra!');
} else {
$hintsBox.append('Haz clic en cualquier palabra para enviarla: ');
lastGeneratedHints = hints; // Almacenar las sugerencias para el panel (si se clickean)
// Filtrar y ordenar para mostrar primero las que coinciden con la entrada del usuario en el chat
const inputVal = $inputChat.val().toLowerCase();
let matchingHints = hints.filter(hint => inputVal === '' || hint.toLowerCase().includes(inputVal));
let nonMatchingHints = hints.filter(hint => inputVal !== '' && !hint.toLowerCase().includes(inputVal));
matchingHints.sort((a, b) => {
const aExact = a.toLowerCase() === inputVal;
const bExact = b.toLowerCase() === inputVal;
if (aExact && !bExact) return -1;
if (!aExact && bExact) return 1;
return a.length - b.length; // Luego por longitud
});
let html = matchingHints.map(hint => `${hint}`).join(', ');
if (nonMatchingHints.length > 0) {
html += ', ' + nonMatchingHints.map(hint => `${hint}`).join(', ');
}
$hintsBox.append(html);
}
};
$inputChat.on('input', assist); // Actualizar sugerencias del panel al escribir en el chat
// --- Observadores para la visibilidad y actualización de la palabra objetivo (para el panel y botón) ---
const targetWordElem = $targetWord[0]; // Referencia al elemento DOM del patrón de la palabra
const hintsPanel = $('#hintsPanel');
if (targetWordElem) {
const wordTipObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// El panel y el botón se ocultan SOLO si el display de targetWord_tip es 'none'.
// Permanecen visibles si el contenido es '?' o '_ _ _ _'.
const isTargetWordHiddenCompletely = targetWordElem.style.display === 'none';
if (isTargetWordHiddenCompletely) {
//nothing happens because I want the menu allways visible
} else {
hintsPanel.show();
$instantWinButton.show();
assist(); // Re-generar sugerencias del panel al aparecer/cambiar la palabra objetivo
}
});
});
wordTipObserver.observe(targetWordElem, { attributes: true, attributeFilter: ['style'], childList: true, subtree: true });
}
// Observador para el botón de refrescar palabra (se habilita cuando hay nueva palabra)
const refreshListElem = $('#wordchooser-refreshlist')[0];
if (refreshListElem) {
const refreshWordObserver = new MutationObserver((mutations) => {
if (mutations[0].target.disabled === false) {
setTimeout(assist, 50); // Dar un pequeño respiro para que el DOM se actualice y el panel se actualice
}
});
refreshWordObserver.observe(refreshListElem, { attributes: true });
}
};
// --- Activadores al inicio ---
// 1. Setup del Instant Win Stopper (se ejecutará una vez al inicio del script)
setupInstantWinStopperListeners();
// 2. Iniciar el panel de ayuda y los observadores cuando se detecte que la sala es de adivinanza de palabras
// La lista de palabras ya está hardcodeada (allWordLists), por lo que está disponible instantáneamente.
const roomKeywords = /\слов|Palabras|Word/;
const infotextElement = $('#infotext')[0];
if (infotextElement) {
const infotextObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (roomKeywords.test(mutation.target.textContent)) {
wordCheatPanel(); // Iniciar el panel y sus lógicas
// FORZAR la llamada a assist() inmediatamente después de que el panel se inicialice.
// Esto asegura que la lista se muestre al instante, sin esperar un cambio de estilo.
setTimeout(() => {
const $targetWord = $('#targetword_tip');
// Asegurarse de que el panel esté visible si targetWord_tip no está oculto
if ($targetWord.length && $targetWord.css('display') !== 'none') {
$('#hintsPanel').show();
$('#instantWinButton').show();
// Ejecutar assist para llenar el panel con palabras
assist();
}
}, 100); // Pequeño retraso para asegurar que los elementos estén renderizados
infotextObserver.disconnect(); // Desconectar el observador una vez activado
}
});
});
infotextObserver.observe(infotextElement, { childList: true, subtree: true });
}
});
})(window.jQuery.noConflict(true));