Skip to content

Commit ad71cbd

Browse files
feat: move artwork feature
-some bug fixes -extracted artwork reprocessing
1 parent fa59c90 commit ad71cbd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+31413
-0
lines changed

Extensions/Script-manager.js

Lines changed: 642 additions & 0 deletions
Large diffs are not rendered by default.

Extensions/auto-image-styles.css

Lines changed: 2194 additions & 0 deletions
Large diffs are not rendered by default.

Extensions/background.js

Lines changed: 921 additions & 0 deletions
Large diffs are not rendered by default.

Extensions/content-script.js

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
// Content script for WPlace AutoBOT - Creates in-page UI
2+
3+
// Check if we're on wplace.lives
4+
if (window.location.hostname === 'wplace.live') {
5+
6+
// Control variables
7+
let autobotButton = null;
8+
let buttonRemoved = false;
9+
let buttonHiddenByModal = false;
10+
let currentScript = null;
11+
12+
// Available scripts configuration - default script to execute
13+
const DEFAULT_SCRIPT = 'Script-manager.js'; // Script manager launcher
14+
15+
// Check if any modal is open
16+
function isAnyModalOpen() {
17+
const modals = document.querySelectorAll('dialog.modal[open], dialog[open]');
18+
return modals.length > 0;
19+
}
20+
21+
// Handle button visibility based on modals
22+
function handleButtonVisibility() {
23+
if (!autobotButton || buttonRemoved) return;
24+
25+
if (isAnyModalOpen()) {
26+
if (!buttonHiddenByModal) {
27+
buttonHiddenByModal = true;
28+
autobotButton.style.transition = 'all 0.3s ease-out';
29+
autobotButton.style.opacity = '0';
30+
autobotButton.style.transform = 'scale(0.8)';
31+
autobotButton.style.pointerEvents = 'none';
32+
}
33+
} else {
34+
if (buttonHiddenByModal) {
35+
buttonHiddenByModal = false;
36+
autobotButton.style.transition = 'all 0.3s ease-in';
37+
autobotButton.style.opacity = '1';
38+
autobotButton.style.transform = 'scale(1)';
39+
autobotButton.style.pointerEvents = 'auto';
40+
}
41+
}
42+
}
43+
44+
// Remove button with animation
45+
function removeButtonWithAnimation() {
46+
buttonRemoved = true;
47+
48+
if (autobotButton && autobotButton.parentNode) {
49+
autobotButton.style.transition = 'all 0.5s ease-out';
50+
autobotButton.style.opacity = '0';
51+
autobotButton.style.transform = 'scale(0.5) translateY(-10px)';
52+
53+
setTimeout(() => {
54+
if (autobotButton && autobotButton.parentNode) {
55+
autobotButton.parentNode.removeChild(autobotButton);
56+
autobotButton = null;
57+
}
58+
}, 500);
59+
}
60+
}
61+
62+
// Execute script functions
63+
async function executeScript(scriptName) {
64+
if (!autobotButton || currentScript) return;
65+
66+
try {
67+
// Change button appearance to loading
68+
autobotButton.innerHTML = `
69+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-5 animate-spin">
70+
<path d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z"/>
71+
</svg>
72+
`;
73+
autobotButton.style.opacity = '0.7';
74+
autobotButton.disabled = true;
75+
currentScript = scriptName;
76+
77+
// Send message to background script
78+
const response = await chrome.runtime.sendMessage({
79+
action: 'executeScript',
80+
scriptName: scriptName
81+
});
82+
83+
if (response && response.success) {
84+
// Show success
85+
autobotButton.innerHTML = `
86+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-5">
87+
<path d="M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z"/>
88+
</svg>
89+
`;
90+
autobotButton.style.background = '#4CAF50';
91+
autobotButton.disabled = false;
92+
autobotButton.title = `${scriptName} executed successfully`;
93+
94+
// Reset button after 2 seconds instead of removing it
95+
setTimeout(() => {
96+
resetButton();
97+
}, 2000);
98+
} else {
99+
throw new Error(response?.error || 'Failed to execute script');
100+
}
101+
102+
} catch (error) {
103+
console.error('Error executing script:', error);
104+
currentScript = null;
105+
106+
// Show error feedback
107+
if (autobotButton) {
108+
autobotButton.innerHTML = `
109+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-5">
110+
<path d="M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z"/>
111+
</svg>
112+
`;
113+
autobotButton.style.opacity = '1';
114+
autobotButton.style.background = '#f44336';
115+
autobotButton.title = `Error: ${error.message} - Click to retry`;
116+
117+
setTimeout(() => {
118+
resetButton();
119+
}, 3000);
120+
}
121+
}
122+
}
123+
124+
// Listen for script execution events from Script Manager
125+
window.addEventListener('autobot-execute-script', async (event) => {
126+
const { scriptName } = event.detail;
127+
console.log(`%c📡 Content script received execution request for: ${scriptName}`, 'color: #00ff41; font-weight: bold;');
128+
129+
// Execute the script using the content script's Chrome API access
130+
try {
131+
const response = await chrome.runtime.sendMessage({
132+
action: 'executeScript',
133+
scriptName: scriptName
134+
});
135+
136+
if (response && response.success) {
137+
console.log(`%c✅ ${scriptName} executed successfully via content script`, 'color: #39ff14; font-weight: bold;');
138+
} else {
139+
console.error(`%c❌ Script execution failed:`, 'color: #ff073a; font-weight: bold;', response?.error);
140+
}
141+
} catch (error) {
142+
console.error(`%c❌ Script execution error:`, 'color: #ff073a; font-weight: bold;', error);
143+
}
144+
});
145+
146+
// Reset button to initial state
147+
function resetButton() {
148+
if (autobotButton) {
149+
autobotButton.innerHTML = `
150+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-5">
151+
<path d="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12A2,2 0 0,1 6,10M18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12A2,2 0 0,1 18,10M8,17.5H16V16H8V17.5Z"/>
152+
</svg>
153+
`;
154+
autobotButton.style.background = '';
155+
autobotButton.title = `AutoBot - Click to run ${DEFAULT_SCRIPT}`;
156+
autobotButton.disabled = false;
157+
currentScript = null;
158+
}
159+
}
160+
161+
// Script menu functionality removed - button now directly executes the default script
162+
163+
// Create the AutoBot button
164+
function createAutoButton() {
165+
if (buttonRemoved) return;
166+
167+
const menuContainer = document.querySelector('.absolute.right-2.top-2.z-30 .flex.flex-col.gap-3.items-center');
168+
169+
if (!menuContainer) {
170+
setTimeout(createAutoButton, 1000);
171+
return;
172+
}
173+
174+
if (document.getElementById('wplace-autobot-btn')) {
175+
return;
176+
}
177+
178+
autobotButton = document.createElement('button');
179+
autobotButton.id = 'wplace-autobot-btn';
180+
autobotButton.className = 'btn btn-square shadow-md';
181+
autobotButton.title = `AutoBot - Click to run ${DEFAULT_SCRIPT}`;
182+
autobotButton.innerHTML = `
183+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-5">
184+
<path d="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12A2,2 0 0,1 6,10M18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12A2,2 0 0,1 18,10M8,17.5H16V16H8V17.5Z"/>
185+
</svg>
186+
`;
187+
188+
autobotButton.style.cssText = `
189+
transition: all 0.2s ease;
190+
`;
191+
192+
// Direct execution instead of showing menu
193+
autobotButton.addEventListener('click', () => {
194+
executeScript(DEFAULT_SCRIPT);
195+
});
196+
197+
// Insert button at the end of the container
198+
menuContainer.appendChild(autobotButton);
199+
200+
setTimeout(() => handleButtonVisibility(), 100);
201+
202+
console.log('AutoBot button added to menu');
203+
}
204+
205+
// Setup modal observers
206+
function setupModalObservers() {
207+
const modalAttributeObserver = new MutationObserver((mutations) => {
208+
mutations.forEach((mutation) => {
209+
if (mutation.type === 'attributes' && mutation.attributeName === 'open') {
210+
handleButtonVisibility();
211+
}
212+
});
213+
});
214+
215+
const domObserver = new MutationObserver((mutations) => {
216+
mutations.forEach((mutation) => {
217+
if (mutation.type === 'childList') {
218+
mutation.addedNodes.forEach((node) => {
219+
if (node.nodeType === Node.ELEMENT_NODE) {
220+
if (node.matches && node.matches('dialog.modal, dialog')) {
221+
modalAttributeObserver.observe(node, {
222+
attributes: true,
223+
attributeFilter: ['open']
224+
});
225+
handleButtonVisibility();
226+
}
227+
228+
const nestedModals = node.querySelectorAll ?
229+
node.querySelectorAll('dialog.modal, dialog') : [];
230+
nestedModals.forEach((modal) => {
231+
modalAttributeObserver.observe(modal, {
232+
attributes: true,
233+
attributeFilter: ['open']
234+
});
235+
});
236+
237+
if (nestedModals.length > 0) {
238+
handleButtonVisibility();
239+
}
240+
}
241+
});
242+
243+
if (mutation.removedNodes.length > 0) {
244+
handleButtonVisibility();
245+
}
246+
}
247+
});
248+
});
249+
250+
const existingModals = document.querySelectorAll('dialog.modal, dialog');
251+
existingModals.forEach((modal) => {
252+
modalAttributeObserver.observe(modal, {
253+
attributes: true,
254+
attributeFilter: ['open']
255+
});
256+
});
257+
258+
domObserver.observe(document.body, {
259+
childList: true,
260+
subtree: true
261+
});
262+
}
263+
264+
// Observer to recreate button if removed
265+
const buttonObserver = new MutationObserver((mutations) => {
266+
if (!buttonRemoved) {
267+
mutations.forEach((mutation) => {
268+
if (mutation.type === 'childList') {
269+
if (!document.getElementById('wplace-autobot-btn')) {
270+
setTimeout(createAutoButton, 500);
271+
}
272+
}
273+
});
274+
}
275+
});
276+
277+
window.addEventListener("message", (event) => {
278+
if (event.source !== window) return;
279+
if (event.data.source !== "my-userscript") return;
280+
const message = event.data;
281+
if (message.type === "setCookie" && message.value) {
282+
console.log("🍪 Content script received setCookie message:", message);
283+
chrome.runtime.sendMessage(
284+
{ type: "setCookie", value: message.value },
285+
(response) => {
286+
console.log("📥 Content script received response from background:", response);
287+
// Send response back to userscript
288+
window.postMessage({
289+
type: "setCookieResponse",
290+
status: response ? response.status || 'ok' : 'error',
291+
originalMessage: message
292+
}, "*");
293+
294+
if (response && response.status === "ok") {
295+
console.log("✅ Forwarded token to background.");
296+
}
297+
}
298+
);
299+
}
300+
});
301+
302+
window.addEventListener("message", (event) => {
303+
if (event.source !== window) return;
304+
const msg = event.data;
305+
if (msg && msg.source === "my-userscript") {
306+
if (msg.type === "getAccounts") {
307+
chrome.runtime.sendMessage({ type: "getAccounts" }, (response) => {
308+
if (response && response.accounts) {
309+
window.postMessage(
310+
{
311+
source: "extension",
312+
type: "accountsData",
313+
accounts: response.accounts,
314+
},
315+
"*"
316+
);
317+
}
318+
});
319+
}
320+
}
321+
});
322+
323+
chrome.runtime.onMessage.addListener((msg) => {
324+
if (msg.type === "cookieSet") {
325+
window.postMessage(
326+
{
327+
source: "my-extension",
328+
type: "cookieSet",
329+
value: msg.value,
330+
},
331+
"*"
332+
);
333+
}
334+
});
335+
336+
window.addEventListener("message", (event) => {
337+
if (event.source !== window) return;
338+
const msg = event.data;
339+
if (msg?.type === "deleteAccount" && typeof msg.index === "number") {
340+
chrome.runtime.sendMessage(
341+
{ type: "deleteAccount", index: msg.index },
342+
(response) => {
343+
window.postMessage(
344+
{
345+
type: "deleteAccountResult",
346+
index: msg.index,
347+
status: response?.status || "error",
348+
},
349+
"*"
350+
);
351+
}
352+
);
353+
}
354+
});
355+
356+
// Initialization
357+
if (document.readyState === 'loading') {
358+
document.addEventListener('DOMContentLoaded', () => {
359+
createAutoButton();
360+
setupModalObservers();
361+
});
362+
} else {
363+
createAutoButton();
364+
setupModalObservers();
365+
}
366+
367+
setTimeout(() => {
368+
createAutoButton();
369+
setupModalObservers();
370+
}, 2000);
371+
372+
buttonObserver.observe(document.body, {
373+
childList: true,
374+
subtree: true
375+
});
376+
377+
console.log('WPlace AutoBOT content script loaded');
378+
}
379+
380+

Extensions/icons/icon128.png

110 KB
Loading

Extensions/icons/icon16.png

110 KB
Loading

Extensions/icons/icon256.png

60.3 KB
Loading

Extensions/icons/icon32.png

110 KB
Loading

Extensions/icons/icon48.png

110 KB
Loading

Extensions/icons/icon64.png

60.3 KB
Loading

0 commit comments

Comments
 (0)