// Name: Agar.io Multibox Userscript Generator // Description: Generates a Tampermonkey userscript for a support autofarm tab that follows and feeds the main tab. // Author: vvar10 // GitHub: vvar10 import "@johnlindquist/kit" const lines = [ "// ==UserScript==", "// @name Agar.io Multibox Support/Follow", "// @namespace https://github.com/vvar10/agario-multibox", "// @version 0.1.0", "// @description Support/autofarm tab follows and feeds the paired main tab; toggle with Ctrl+Alt+A; choose role with Ctrl+Alt+M (main) or Ctrl+Alt+S (support); select group with Ctrl+Alt+1/2.", "// @match https://agar.io/*", "// @run-at document-end", "// @grant none", "// ==/UserScript==", "", "(function() {", " 'use strict';", "", " const STATE = {", " isMain: false,", " isSupport: false,", " enabled: true,", " group: localStorage.getItem('AG_MB_GROUP') || '1',", " };", "", " const CHANNEL_PREFIX = 'agario-mb-';", " let channel = new BroadcastChannel(CHANNEL_PREFIX + STATE.group);", "", " function setGroup(g) {", " if (!g) return;", " try {", " channel && channel.close && channel.close();", " } catch (_) {}", " STATE.group = g;", " localStorage.setItem('AG_MB_GROUP', g);", " channel = new BroadcastChannel(CHANNEL_PREFIX + g);", " channel.onmessage = onChannelMessage;", " overlayUpdate();", " }", "", " // Overlay status", " let ov = null;", " function overlayUpdate() {", " if (!ov) return;", " ov.innerHTML = ''", " + '<div><b>Agar Multibox</b></div>'", " + '<div>Group: ' + STATE.group + ' (Ctrl+Alt+1/2)</div>'", " + '<div>Role: ' + (STATE.isMain ? 'MAIN' : (STATE.isSupport ? 'SUPPORT' : 'IDLE')) + ' (Ctrl+Alt+M/S)</div>'", " + '<div>Enabled: ' + (STATE.enabled ? 'ON' : 'OFF') + ' (Ctrl+Alt+A)</div>';", " ov.style.opacity = STATE.enabled ? '0.9' : '0.5';", " }", " function overlayInit() {", " ov = document.createElement('div');", " ov.style.position = 'fixed';", " ov.style.top = '8px';", " ov.style.left = '8px';", " ov.style.zIndex = '99999';", " ov.style.font = '12px/1.2 -apple-system, Segoe UI, Roboto, sans-serif';", " ov.style.background = 'rgba(0,0,0,0.55)';", " ov.style.color = '#0f0';", " ov.style.padding = '6px 8px';", " ov.style.border = '1px solid rgba(0,255,0,0.3)';", " ov.style.borderRadius = '4px';", " ov.style.pointerEvents = 'none';", " overlayUpdate();", " document.addEventListener('DOMContentLoaded', () => {", " if (!document.body.contains(ov)) document.body.appendChild(ov);", " });", " if (document.body) document.body.appendChild(ov);", " }", " overlayInit();", "", " // Hotkeys", " window.addEventListener('keydown', function(e) {", " if (!e || !e.ctrlKey || !e.altKey) return;", " if (e.code === 'KeyA') {", " STATE.enabled = !STATE.enabled;", " overlayUpdate();", " e.preventDefault();", " } else if (e.code === 'KeyM') {", " STATE.isMain = !STATE.isMain;", " if (STATE.isMain) STATE.isSupport = false;", " overlayUpdate();", " e.preventDefault();", " } else if (e.code === 'KeyS') {", " STATE.isSupport = !STATE.isSupport;", " if (STATE.isSupport) STATE.isMain = false;", " overlayUpdate();", " e.preventDefault();", " } else if (e.code === 'Digit1') {", " setGroup('1');", " e.preventDefault();", " } else if (e.code === 'Digit2') {", " setGroup('2');", " e.preventDefault();", " }", " }, true);", "", " // Broadcast mouse pos from MAIN", " function getCanvasRect() {", " const canvas = document.querySelector('canvas');", " if (!canvas) return null;", " return canvas.getBoundingClientRect();", " }", "", " window.addEventListener('mousemove', function(e) {", " if (!STATE.enabled || !STATE.isMain) return;", " const rect = getCanvasRect();", " if (!rect) return;", " const x = (e.clientX - rect.left) / Math.max(1, rect.width);", " const y = (e.clientY - rect.top) / Math.max(1, rect.height);", " if (x >= -0.2 && x <= 1.2 && y >= -0.2 && y <= 1.2) {", " try {", " channel.postMessage({ t: 'pos', x: x, y: y, ts: performance.now() });", " } catch (_) {}", " // Mirror to localStorage as a fallback", " mirrorToLocalStorage(x, y);", " }", " }, { passive: true });", "", " // SUPPORT: listen and follow", " let target = { x: 0.5, y: 0.5, ts: 0 };", " let cur = { x: 0.5, y: 0.5 };", " function onChannelMessage(ev) {", " const d = ev && ev.data;", " if (!d || d.t !== 'pos') return;", " target.x = d.x; target.y = d.y; target.ts = d.ts || performance.now();", " }", " channel.onmessage = onChannelMessage;", "", " function dispatchMouseToCanvas(nx, ny) {", " const canvas = document.querySelector('canvas');", " if (!canvas) return;", " const rect = canvas.getBoundingClientRect();", " const clampedX = Math.min(Math.max(nx, 0), 1);", " const clampedY = Math.min(Math.max(ny, 0), 1);", " const cx = rect.left + clampedX * rect.width;", " const cy = rect.top + clampedY * rect.height;", " const eventOpts = {", " bubbles: true,", " cancelable: true,", " clientX: Math.round(cx),", " clientY: Math.round(cy),", " screenX: window.screenX + Math.round(cx),", " screenY: window.screenY + Math.round(cy),", " view: window", " };", " const ev = new MouseEvent('mousemove', eventOpts);", " canvas.dispatchEvent(ev);", " window.dispatchEvent(new MouseEvent('mousemove', eventOpts));", " document.dispatchEvent(new MouseEvent('mousemove', eventOpts));", " }", "", " // Feeding", " let feeding = false;", " let feedInterval = 0;", " function startFeeding() {", " if (feeding) return;", " feeding = true;", " feedInterval = window.setInterval(function() {", " const kd = new KeyboardEvent('keydown', { key: 'x', code: 'KeyX', bubbles: true });", " const ku = new KeyboardEvent('keyup', { key: 'x', code: 'KeyX', bubbles: true });", " window.dispatchEvent(kd); document.dispatchEvent(kd);", " window.dispatchEvent(ku); document.dispatchEvent(ku);", " }, 60);", " }", " function stopFeeding() {", " if (!feeding) return;", " feeding = false;", " window.clearInterval(feedInterval);", " }", "", " function supportLoop() {", " if (STATE.enabled && STATE.isSupport) {", " // Smoothly follow target", " cur.x += (target.x - cur.x) * 0.25;", " cur.y += (target.y - cur.y) * 0.25;", " dispatchMouseToCanvas(cur.x, cur.y);", "", " // Feed if very close to the main's pointer direction", " const dx = target.x - cur.x;", " const dy = target.y - cur.y;", " const dist = Math.hypot(dx, dy);", " if (dist < 0.02) startFeeding(); else stopFeeding();", " } else {", " stopFeeding();", " }", " window.requestAnimationFrame(supportLoop);", " }", " window.requestAnimationFrame(supportLoop);", "", " // Auto-respawn for SUPPORT", " function tryRespawn() {", " if (!STATE.enabled || !STATE.isSupport) return;", " // Try clicking a Play/Respawn button", " const btn = document.querySelector('.btn-play, .btn-primary, button[aria-label=\"Play\"], button[aria-label=\"Respawn\"], button[aria-label=\"Continue\"], button');", " if (btn && btn instanceof HTMLElement && btn.offsetParent !== null) {", " btn.click();", " } else {", " // Fallback: press Space to (re)spawn", " const kd = new KeyboardEvent('keydown', { key: ' ', code: 'Space', bubbles: true });", " const ku = new KeyboardEvent('keyup', { key: ' ', code: 'Space', bubbles: true });", " window.dispatchEvent(kd); document.dispatchEvent(kd);", " window.dispatchEvent(ku); document.dispatchEvent(ku);", " }", " }", " setInterval(tryRespawn, 1500);", "", " document.addEventListener('visibilitychange', function() {", " if (!document.hidden && STATE.isSupport && STATE.enabled) {", " const nx = target.x * 0.98 + 0.01;", " const ny = target.y * 0.98 + 0.01;", " dispatchMouseToCanvas(nx, ny);", " }", " });", "", " // Fallback sync via localStorage", " function lsKey() { return 'agario-mb-sync-' + STATE.group; }", " function mirrorToLocalStorage(x, y) {", " try {", " localStorage.setItem(lsKey(), JSON.stringify({ t: 'pos', x: x, y: y, ts: Date.now(), rnd: Math.random() }));", " } catch (_) {}", " }", " window.addEventListener('storage', function(e) {", " if (!e || e.key !== lsKey() || !e.newValue) return;", " try {", " const d = JSON.parse(e.newValue);", " if (d && d.t === 'pos') {", " target.x = d.x; target.y = d.y; target.ts = d.ts || performance.now();", " }", " } catch (_) {}", " });", "", "})();", "", ] const userscript = lines.join("\n") const defaultPath = home("Downloads", "agar-io-multibox.user.js") await writeFile(defaultPath, userscript) await copy(userscript) await notify(`Userscript copied to clipboard and saved:\n${defaultPath}`) await revealFile(defaultPath)