Original script by https://github.com/louisgeisler/LuccaFacesSolver, but improved by saving learnings to local storage and providing scripts to read
Paste this in console on the page with the GO button. When done, click replay and paste the script again.
(async (config) => {
try {
// Load saved learnings from localStorage
let foundNames = new Set(JSON.parse(localStorage.getItem('lucca_foundNames') || '[]'));
let imgId2Names = JSON.parse(localStorage.getItem('lucca_imgId2Names') || '{}');
console.log(`π§ Loaded ${Object.keys(imgId2Names).length} known employees`);
function sleep(duration) {
return new Promise((resolve) => {
setTimeout(() => resolve(), duration);
});
}
async function answer() {
try {
console.group("π‘ Answer Event")
var img = document.querySelector('#game app-timer .image');
if (!img) {
console.error("β Image element not found!");
console.groupEnd();
return;
}
let style = img.currentStyle || window.getComputedStyle(img, false);
let url = style.backgroundImage.slice(4, -1).replace(/"/g, "");
if (!url || url === 'none') {
console.error("β No background image!");
console.groupEnd();
return;
}
if (config.speedup) {
img.style.visibility = "hidden";
}
let result = await fetch(url);
let blob = await result.blob();
let id = [blob.type, blob.size].toString();
let possibleAnswerElements = [];
let attempts = 0;
while (!possibleAnswerElements.length && attempts < 50) {
await sleep(100);
possibleAnswerElements = [...document.querySelectorAll('#game .answers .answer')];
attempts++;
}
if (!possibleAnswerElements.length) {
console.error("β Answer buttons not found!");
console.groupEnd();
return;
}
let known = imgId2Names[id] ?? false;
let guessed;
if (known) {
guessed = known;
console.info(`β
Known: ${guessed}`)
} else {
console.info("β Unknown - learning...")
let bestAnswers = possibleAnswerElements.filter(e => !foundNames.has(e.innerHTML));
if (!bestAnswers.length) bestAnswers = possibleAnswerElements;
guessed = bestAnswers[Math.floor(Math.random() * bestAnswers.length)].innerHTML;
console.info(`π€ Guessing: '${guessed}'`)
}
let guessElement = possibleAnswerElements.find(e => e.innerHTML == guessed);
if (!guessElement) {
console.error("β Could not find answer element");
console.groupEnd();
return;
}
guessElement.click();
let rightElement;
attempts = 0;
while (!rightElement && attempts < 50) {
await sleep(100);
rightElement = document.querySelector('#game .answers .is-right');
attempts++;
}
if (!rightElement) {
console.error("β Right answer not found!");
console.groupEnd();
return;
}
let rightName = rightElement.innerHTML;
if (!known) {
console.info(`π§ Learned: '${rightName}'`)
imgId2Names[id] = rightName;
foundNames.add(rightName);
// SAVE IMMEDIATELY
localStorage.setItem('lucca_imgId2Names', JSON.stringify(imgId2Names));
localStorage.setItem('lucca_foundNames', JSON.stringify([...foundNames]));
console.info(`πΎ Saved! Total known: ${Object.keys(imgId2Names).length}`);
}
console.groupEnd()
} catch (error) {
console.error("β Error:", error);
console.groupEnd();
}
}
// Check if game already started
let img = document.querySelector('#game app-timer .image');
if (img) {
console.log("β
Game in progress! Attaching bot...");
let last_style = null;
const observer = new MutationObserver(function(mutations) {
if (img.style.backgroundImage != last_style && img.style.backgroundImage) {
answer();
last_style = img.style.backgroundImage;
}
});
observer.observe(img, {
attributes: true,
attributeFilter: ['style']
});
// Answer current question if present
if (img.style.backgroundImage) {
await answer();
}
console.log("π€ Bot active! Known employees:", Object.keys(imgId2Names).length);
return;
}
// Otherwise wait for start
console.log("β³ Waiting for start button...");
let start_button = document.querySelector('.rotation-loader');
let attempts = 0;
while (!start_button && attempts < 100) {
await sleep(100);
start_button = document.querySelector('.rotation-loader');
attempts++;
}
if (!start_button) {
console.error("β Start button not found!");
return;
}
console.info("π Starting game...");
start_button.click();
img = null;
attempts = 0;
while (!img && attempts < 100) {
await sleep(100);
img = document.querySelector('#game app-timer .image');
attempts++;
}
if (!img) {
console.error("β Game didn't start!");
return;
}
let last_style = null;
const observer = new MutationObserver(function(mutations) {
if (img.style.backgroundImage != last_style && img.style.backgroundImage) {
answer();
last_style = img.style.backgroundImage;
}
});
observer.observe(img, {
attributes: true,
attributeFilter: ['style']
});
await answer();
console.log("π€ Bot running! Paste script again after game ends to continue.");
} catch (error) {
console.error("π₯ Fatal error:", error);
}
})({
speedup: true // Hide images for faster runs
});
console.log(`
π Stats: ${Object.keys(JSON.parse(localStorage.getItem('lucca_imgId2Names') || '{}')).length} employees known
π Re-paste this script after each game to continue!
ποΈ Clear: localStorage.clear()
`);
console.table(JSON.parse(localStorage.getItem('lucca_imgId2Names')))
Object.keys(JSON.parse(localStorage.getItem('lucca_imgId2Names') || '{}')).length