// Content script for WPlace AutoBOT - Creates in-page UI
// Check if we're on wplace.live
if (window.location.hostname === 'wplace.live') {
// Control variables
let autobotButton = null;
let buttonRemoved = false;
let buttonHiddenByModal = false;
let currentScript = null;
// Available scripts configuration - default script to execute
const DEFAULT_SCRIPT = 'Script-manager.js'; // Script manager launcher
// Check if any modal is open
function isAnyModalOpen() {
const modals = document.querySelectorAll('dialog.modal[open], dialog[open]');
return modals.length > 0;
}
// Handle button visibility based on modals
function handleButtonVisibility() {
if (!autobotButton || buttonRemoved) return;
if (isAnyModalOpen()) {
if (!buttonHiddenByModal) {
buttonHiddenByModal = true;
autobotButton.style.transition = 'all 0.3s ease-out';
autobotButton.style.opacity = '0';
autobotButton.style.transform = 'scale(0.8)';
autobotButton.style.pointerEvents = 'none';
}
} else {
if (buttonHiddenByModal) {
buttonHiddenByModal = false;
autobotButton.style.transition = 'all 0.3s ease-in';
autobotButton.style.opacity = '1';
autobotButton.style.transform = 'scale(1)';
autobotButton.style.pointerEvents = 'auto';
}
}
}
// Remove button with animation
function removeButtonWithAnimation() {
buttonRemoved = true;
if (autobotButton && autobotButton.parentNode) {
autobotButton.style.transition = 'all 0.5s ease-out';
autobotButton.style.opacity = '0';
autobotButton.style.transform = 'scale(0.5) translateY(-10px)';
setTimeout(() => {
if (autobotButton && autobotButton.parentNode) {
autobotButton.parentNode.removeChild(autobotButton);
autobotButton = null;
}
}, 500);
}
}
// Execute script function
async function executeScript(scriptName) {
if (!autobotButton || currentScript) return;
try {
// Change button appearance to loading
autobotButton.innerHTML = `
`;
autobotButton.style.opacity = '0.7';
autobotButton.disabled = true;
currentScript = scriptName;
// Send message to background script
const response = await chrome.runtime.sendMessage({
action: 'executeScript',
scriptName: scriptName
});
if (response && response.success) {
// Show success
autobotButton.innerHTML = `
`;
autobotButton.style.background = '#4CAF50';
autobotButton.disabled = false;
autobotButton.title = `${scriptName} executed successfully`;
// Reset button after 2 seconds instead of removing it
setTimeout(() => {
resetButton();
}, 2000);
} else {
throw new Error(response?.error || 'Failed to execute script');
}
} catch (error) {
console.error('Error executing script:', error);
currentScript = null;
// Show error feedback
if (autobotButton) {
autobotButton.innerHTML = `
`;
autobotButton.style.opacity = '1';
autobotButton.style.background = '#f44336';
autobotButton.title = `Error: ${error.message} - Click to retry`;
setTimeout(() => {
resetButton();
}, 3000);
}
}
}
// Listen for script execution events from Script Manager
window.addEventListener('autobot-execute-script', async (event) => {
const { scriptName } = event.detail;
console.log(`%c📡 Content script received execution request for: ${scriptName}`, 'color: #00ff41; font-weight: bold;');
// Execute the script using the content script's Chrome API access
try {
const response = await chrome.runtime.sendMessage({
action: 'executeScript',
scriptName: scriptName
});
if (response && response.success) {
console.log(`%c✅ ${scriptName} executed successfully via content script`, 'color: #39ff14; font-weight: bold;');
} else {
console.error(`%c❌ Script execution failed:`, 'color: #ff073a; font-weight: bold;', response?.error);
}
} catch (error) {
console.error(`%c❌ Script execution error:`, 'color: #ff073a; font-weight: bold;', error);
}
});
// Reset button to initial state
function resetButton() {
if (autobotButton) {
autobotButton.innerHTML = `
`;
autobotButton.style.background = '';
autobotButton.title = `AutoBot - Click to run ${DEFAULT_SCRIPT}`;
autobotButton.disabled = false;
currentScript = null;
}
}
// Script menu functionality removed - button now directly executes the default script
// Create the AutoBot button
function createAutoButton() {
if (buttonRemoved) return;
const menuContainer = document.querySelector('.absolute.right-2.top-2.z-30 .flex.flex-col.gap-3.items-center');
if (!menuContainer) {
setTimeout(createAutoButton, 1000);
return;
}
if (document.getElementById('wplace-autobot-btn')) {
return;
}
autobotButton = document.createElement('button');
autobotButton.id = 'wplace-autobot-btn';
autobotButton.className = 'btn btn-square shadow-md';
autobotButton.title = `AutoBot - Click to run ${DEFAULT_SCRIPT}`;
autobotButton.innerHTML = `
`;
autobotButton.style.cssText = `
transition: all 0.2s ease;
`;
// Direct execution instead of showing menu
autobotButton.addEventListener('click', () => {
executeScript(DEFAULT_SCRIPT);
});
// Insert button at the end of the container
menuContainer.appendChild(autobotButton);
setTimeout(() => handleButtonVisibility(), 100);
console.log('AutoBot button added to menu');
}
// Setup modal observers
function setupModalObservers() {
const modalAttributeObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'open') {
handleButtonVisibility();
}
});
});
const domObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.matches && node.matches('dialog.modal, dialog')) {
modalAttributeObserver.observe(node, {
attributes: true,
attributeFilter: ['open']
});
handleButtonVisibility();
}
const nestedModals = node.querySelectorAll ?
node.querySelectorAll('dialog.modal, dialog') : [];
nestedModals.forEach((modal) => {
modalAttributeObserver.observe(modal, {
attributes: true,
attributeFilter: ['open']
});
});
if (nestedModals.length > 0) {
handleButtonVisibility();
}
}
});
if (mutation.removedNodes.length > 0) {
handleButtonVisibility();
}
}
});
});
const existingModals = document.querySelectorAll('dialog.modal, dialog');
existingModals.forEach((modal) => {
modalAttributeObserver.observe(modal, {
attributes: true,
attributeFilter: ['open']
});
});
domObserver.observe(document.body, {
childList: true,
subtree: true
});
}
// Observer to recreate button if removed
const buttonObserver = new MutationObserver((mutations) => {
if (!buttonRemoved) {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
if (!document.getElementById('wplace-autobot-btn')) {
setTimeout(createAutoButton, 500);
}
}
});
}
});
// Initialization
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
createAutoButton();
setupModalObservers();
});
} else {
createAutoButton();
setupModalObservers();
}
setTimeout(() => {
createAutoButton();
setupModalObservers();
}, 2000);
buttonObserver.observe(document.body, {
childList: true,
subtree: true
});
console.log('WPlace AutoBOT content script loaded');
}