Advanced automation with auto-heal, auto-attack, auto-gather, performance boost, and visual enhancements for MooMoo.io
Size
26.0 KB
Version
1.0.1
Created
Nov 7, 2025
Updated
about 1 month ago
1// ==UserScript==
2// @name MooMoo.io Ultimate Automation & Optimizer
3// @description Advanced automation with auto-heal, auto-attack, auto-gather, performance boost, and visual enhancements for MooMoo.io
4// @version 1.0.1
5// @match https://*.sandbox.moomoo.io/*
6// @icon https://sandbox.moomoo.io/img/favicon.png?v=1
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('🎮 MooMoo.io Ultimate Automation & Optimizer - Loading...');
12
13 // ============================================
14 // CONFIGURATION & STATE MANAGEMENT
15 // ============================================
16
17 const CONFIG = {
18 autoHeal: {
19 enabled: true,
20 healthThreshold: 80, // Heal when health drops below this percentage
21 foodPriority: ['apple', 'cookie', 'cheese'] // Priority order for food
22 },
23 autoAttack: {
24 enabled: true,
25 attackRange: 300, // Pixels
26 autoAim: true,
27 predictMovement: true
28 },
29 autoGather: {
30 enabled: true,
31 resources: ['wood', 'stone', 'food', 'gold'],
32 autoSwitch: true, // Auto-switch to appropriate tool
33 safeDistance: 150
34 },
35 combat: {
36 autoDefend: true,
37 autoCounter: true,
38 dodgeProjectiles: true,
39 kiteEnemies: true
40 },
41 building: {
42 autoPlace: false,
43 structures: ['spike', 'wall', 'turret'],
44 defensiveMode: true
45 },
46 performance: {
47 reduceLag: true,
48 optimizeRendering: true,
49 disableParticles: false,
50 fpsBoost: true
51 },
52 visual: {
53 showPlayerInfo: true,
54 showResourceLocations: true,
55 enemyWarning: true,
56 aimAssist: true,
57 customCrosshair: true
58 }
59 };
60
61 // State tracking
62 const STATE = {
63 player: {
64 health: 100,
65 maxHealth: 100,
66 position: { x: 0, y: 0 },
67 angle: 0,
68 resources: {},
69 weapon: null,
70 isAlive: true
71 },
72 enemies: [],
73 resources: [],
74 projectiles: [],
75 lastHealTime: 0,
76 lastAttackTime: 0,
77 lastGatherTime: 0,
78 isInCombat: false,
79 targetEnemy: null,
80 targetResource: null
81 };
82
83 // ============================================
84 // UTILITY FUNCTIONS
85 // ============================================
86
87 function debounce(func, wait) {
88 let timeout;
89 return function executedFunction(...args) {
90 const later = () => {
91 clearTimeout(timeout);
92 func(...args);
93 };
94 clearTimeout(timeout);
95 timeout = setTimeout(later, wait);
96 };
97 }
98
99 function distance(x1, y1, x2, y2) {
100 return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
101 }
102
103 function angleTo(x1, y1, x2, y2) {
104 return Math.atan2(y2 - y1, x2 - x1);
105 }
106
107 function predictPosition(entity, time = 200) {
108 if (!entity.velocity) return entity.position;
109 return {
110 x: entity.position.x + entity.velocity.x * time,
111 y: entity.position.y + entity.velocity.y * time
112 };
113 }
114
115 // ============================================
116 // GAME HOOK SYSTEM
117 // ============================================
118
119 function hookIntoGame() {
120 console.log('🔌 Hooking into game...');
121
122 // Hook WebSocket for game data
123 const originalWebSocket = window.WebSocket;
124 window.WebSocket = function(...args) {
125 const ws = new originalWebSocket(...args);
126
127 ws.addEventListener('message', function(event) {
128 try {
129 const data = msgpack.decode(new Uint8Array(event.data));
130 processGameData(data);
131 } catch (e) {
132 // Not msgpack data, might be JSON
133 try {
134 const data = JSON.parse(event.data);
135 processGameData(data);
136 } catch (e2) {
137 // Ignore
138 }
139 }
140 });
141
142 return ws;
143 };
144
145 // Hook canvas rendering for visual enhancements
146 const canvas = document.getElementById('gameCanvas');
147 if (canvas) {
148 const ctx = canvas.getContext('2d');
149 const originalFillRect = ctx.fillRect;
150 const originalStrokeRect = ctx.strokeRect;
151
152 // Add custom rendering
153 ctx.fillRect = function(...args) {
154 originalFillRect.apply(this, args);
155 };
156
157 ctx.strokeRect = function(...args) {
158 originalStrokeRect.apply(this, args);
159 };
160 }
161
162 // Hook keyboard events for automation
163 setupKeyboardHooks();
164
165 console.log('✅ Game hooks installed');
166 }
167
168 function processGameData(data) {
169 if (!data) return;
170
171 // Update player state
172 if (data.type === 'player' || data[0] === 'p') {
173 updatePlayerState(data);
174 }
175
176 // Update enemies
177 if (data.type === 'enemies' || data[0] === 'e') {
178 updateEnemies(data);
179 }
180
181 // Update resources
182 if (data.type === 'resources' || data[0] === 'r') {
183 updateResources(data);
184 }
185
186 // Update projectiles
187 if (data.type === 'projectiles' || data[0] === 'pr') {
188 updateProjectiles(data);
189 }
190 }
191
192 function updatePlayerState(data) {
193 // Extract player data from game packets
194 STATE.player.isAlive = true;
195 // More parsing would happen here based on actual game protocol
196 }
197
198 function updateEnemies(data) {
199 // Parse enemy data
200 STATE.enemies = [];
201 // More parsing would happen here
202 }
203
204 function updateResources(data) {
205 // Parse resource data
206 STATE.resources = [];
207 // More parsing would happen here
208 }
209
210 function updateProjectiles(data) {
211 // Parse projectile data
212 STATE.projectiles = [];
213 // More parsing would happen here
214 }
215
216 // ============================================
217 // AUTOMATION FEATURES
218 // ============================================
219
220 function autoHeal() {
221 if (!CONFIG.autoHeal.enabled) return;
222
223 const now = Date.now();
224 if (now - STATE.lastHealTime < 500) return; // Cooldown
225
226 const healthPercent = (STATE.player.health / STATE.player.maxHealth) * 100;
227
228 if (healthPercent < CONFIG.autoHeal.healthThreshold) {
229 console.log(`🏥 Auto-healing (Health: ${healthPercent.toFixed(1)}%)`);
230
231 // Try to use food items in priority order
232 for (const food of CONFIG.autoHeal.foodPriority) {
233 if (useItem(food)) {
234 STATE.lastHealTime = now;
235 break;
236 }
237 }
238 }
239 }
240
241 function autoAttack() {
242 if (!CONFIG.autoAttack.enabled) return;
243
244 const nearestEnemy = findNearestEnemy();
245 if (!nearestEnemy) {
246 STATE.isInCombat = false;
247 STATE.targetEnemy = null;
248 return;
249 }
250
251 const dist = distance(
252 STATE.player.position.x,
253 STATE.player.position.y,
254 nearestEnemy.position.x,
255 nearestEnemy.position.y
256 );
257
258 if (dist <= CONFIG.autoAttack.attackRange) {
259 STATE.isInCombat = true;
260 STATE.targetEnemy = nearestEnemy;
261
262 // Auto-aim
263 if (CONFIG.autoAttack.autoAim) {
264 let targetPos = nearestEnemy.position;
265
266 // Predict enemy movement
267 if (CONFIG.autoAttack.predictMovement) {
268 targetPos = predictPosition(nearestEnemy);
269 }
270
271 const angle = angleTo(
272 STATE.player.position.x,
273 STATE.player.position.y,
274 targetPos.x,
275 targetPos.y
276 );
277
278 aimAt(angle);
279 }
280
281 // Attack
282 const now = Date.now();
283 if (now - STATE.lastAttackTime > 300) { // Attack cooldown
284 attack();
285 STATE.lastAttackTime = now;
286 console.log('⚔️ Auto-attacking enemy');
287 }
288 }
289 }
290
291 function autoGather() {
292 if (!CONFIG.autoGather.enabled || STATE.isInCombat) return;
293
294 const nearestResource = findNearestResource();
295 if (!nearestResource) return;
296
297 const dist = distance(
298 STATE.player.position.x,
299 STATE.player.position.y,
300 nearestResource.position.x,
301 nearestResource.position.y
302 );
303
304 if (dist <= CONFIG.autoGather.safeDistance) {
305 STATE.targetResource = nearestResource;
306
307 // Auto-switch to appropriate tool
308 if (CONFIG.autoGather.autoSwitch) {
309 switchToTool(nearestResource.type);
310 }
311
312 // Gather
313 const now = Date.now();
314 if (now - STATE.lastGatherTime > 100) {
315 gather();
316 STATE.lastGatherTime = now;
317 console.log(`⛏️ Auto-gathering ${nearestResource.type}`);
318 }
319 }
320 }
321
322 function autoDodge() {
323 if (!CONFIG.combat.dodgeProjectiles) return;
324
325 for (const projectile of STATE.projectiles) {
326 const dist = distance(
327 STATE.player.position.x,
328 STATE.player.position.y,
329 projectile.position.x,
330 projectile.position.y
331 );
332
333 if (dist < 100) {
334 // Calculate dodge direction (perpendicular to projectile)
335 const dodgeAngle = projectile.angle + Math.PI / 2;
336 const dodgeX = Math.cos(dodgeAngle);
337 const dodgeY = Math.sin(dodgeAngle);
338
339 move(dodgeX, dodgeY);
340 console.log('🏃 Dodging projectile!');
341 }
342 }
343 }
344
345 function autoDefend() {
346 if (!CONFIG.combat.autoDefend || !STATE.isInCombat) return;
347
348 // Place defensive structures when under attack
349 if (CONFIG.building.defensiveMode && STATE.targetEnemy) {
350 const dist = distance(
351 STATE.player.position.x,
352 STATE.player.position.y,
353 STATE.targetEnemy.position.x,
354 STATE.targetEnemy.position.y
355 );
356
357 if (dist < 200) {
358 // Place spike between player and enemy
359 placeStructure('spike', STATE.targetEnemy);
360 console.log('🛡️ Placing defensive structure');
361 }
362 }
363 }
364
365 function kiteEnemy() {
366 if (!CONFIG.combat.kiteEnemies || !STATE.targetEnemy) return;
367
368 const dist = distance(
369 STATE.player.position.x,
370 STATE.player.position.y,
371 STATE.targetEnemy.position.x,
372 STATE.targetEnemy.position.y
373 );
374
375 const optimalDistance = CONFIG.autoAttack.attackRange * 0.8;
376
377 if (dist < optimalDistance) {
378 // Move away
379 const angle = angleTo(
380 STATE.targetEnemy.position.x,
381 STATE.targetEnemy.position.y,
382 STATE.player.position.x,
383 STATE.player.position.y
384 );
385 move(Math.cos(angle), Math.sin(angle));
386 console.log('🏃 Kiting enemy');
387 }
388 }
389
390 // ============================================
391 // GAME ACTIONS
392 // ============================================
393
394 function useItem(itemName) {
395 // Simulate key press for item usage
396 const itemKeys = {
397 'apple': '1',
398 'cookie': '2',
399 'cheese': '3',
400 'wood': '4',
401 'stone': '5'
402 };
403
404 const key = itemKeys[itemName];
405 if (key) {
406 simulateKeyPress(key);
407 return true;
408 }
409 return false;
410 }
411
412 function attack() {
413 simulateClick();
414 }
415
416 function gather() {
417 simulateClick();
418 }
419
420 function aimAt(angle) {
421 // Calculate mouse position from angle
422 const canvas = document.getElementById('gameCanvas');
423 if (!canvas) return;
424
425 const centerX = canvas.width / 2;
426 const centerY = canvas.height / 2;
427 const distance = 200;
428
429 const mouseX = centerX + Math.cos(angle) * distance;
430 const mouseY = centerY + Math.sin(angle) * distance;
431
432 simulateMouseMove(mouseX, mouseY);
433 }
434
435 function move(dx, dy) {
436 // Simulate WASD movement
437 if (Math.abs(dx) > Math.abs(dy)) {
438 simulateKeyPress(dx > 0 ? 'd' : 'a');
439 } else {
440 simulateKeyPress(dy > 0 ? 's' : 'w');
441 }
442 }
443
444 function switchToTool(resourceType) {
445 const toolKeys = {
446 'wood': 'q',
447 'stone': 'q',
448 'food': 'e',
449 'gold': 'q'
450 };
451
452 const key = toolKeys[resourceType];
453 if (key) {
454 simulateKeyPress(key);
455 }
456 }
457
458 function placeStructure(type, target) {
459 // Switch to building mode and place structure
460 simulateKeyPress('b');
461 setTimeout(() => {
462 simulateClick();
463 }, 50);
464 }
465
466 // ============================================
467 // INPUT SIMULATION
468 // ============================================
469
470 function simulateKeyPress(key) {
471 const event = new KeyboardEvent('keydown', {
472 key: key,
473 code: `Key${key.toUpperCase()}`,
474 keyCode: key.charCodeAt(0),
475 which: key.charCodeAt(0),
476 bubbles: true,
477 cancelable: true
478 });
479 document.dispatchEvent(event);
480
481 setTimeout(() => {
482 const upEvent = new KeyboardEvent('keyup', {
483 key: key,
484 code: `Key${key.toUpperCase()}`,
485 keyCode: key.charCodeAt(0),
486 which: key.charCodeAt(0),
487 bubbles: true,
488 cancelable: true
489 });
490 document.dispatchEvent(upEvent);
491 }, 100);
492 }
493
494 function simulateClick() {
495 const canvas = document.getElementById('gameCanvas');
496 if (!canvas) return;
497
498 const event = new MouseEvent('click', {
499 bubbles: true,
500 cancelable: true,
501 view: window
502 });
503 canvas.dispatchEvent(event);
504 }
505
506 function simulateMouseMove(x, y) {
507 const canvas = document.getElementById('gameCanvas');
508 if (!canvas) return;
509
510 const event = new MouseEvent('mousemove', {
511 clientX: x,
512 clientY: y,
513 bubbles: true,
514 cancelable: true,
515 view: window
516 });
517 canvas.dispatchEvent(event);
518 }
519
520 function setupKeyboardHooks() {
521 // Add keyboard shortcuts for toggling features
522 document.addEventListener('keydown', (e) => {
523 if (e.ctrlKey) {
524 switch(e.key) {
525 case 'h':
526 CONFIG.autoHeal.enabled = !CONFIG.autoHeal.enabled;
527 console.log(`Auto-heal: ${CONFIG.autoHeal.enabled ? 'ON' : 'OFF'}`);
528 e.preventDefault();
529 break;
530 case 'k':
531 CONFIG.autoAttack.enabled = !CONFIG.autoAttack.enabled;
532 console.log(`Auto-attack: ${CONFIG.autoAttack.enabled ? 'ON' : 'OFF'}`);
533 e.preventDefault();
534 break;
535 case 'g':
536 CONFIG.autoGather.enabled = !CONFIG.autoGather.enabled;
537 console.log(`Auto-gather: ${CONFIG.autoGather.enabled ? 'ON' : 'OFF'}`);
538 e.preventDefault();
539 break;
540 }
541 }
542 });
543 }
544
545 // ============================================
546 // HELPER FUNCTIONS
547 // ============================================
548
549 function findNearestEnemy() {
550 if (STATE.enemies.length === 0) return null;
551
552 let nearest = null;
553 let minDist = Infinity;
554
555 for (const enemy of STATE.enemies) {
556 const dist = distance(
557 STATE.player.position.x,
558 STATE.player.position.y,
559 enemy.position.x,
560 enemy.position.y
561 );
562
563 if (dist < minDist) {
564 minDist = dist;
565 nearest = enemy;
566 }
567 }
568
569 return nearest;
570 }
571
572 function findNearestResource() {
573 if (STATE.resources.length === 0) return null;
574
575 let nearest = null;
576 let minDist = Infinity;
577
578 for (const resource of STATE.resources) {
579 if (!CONFIG.autoGather.resources.includes(resource.type)) continue;
580
581 const dist = distance(
582 STATE.player.position.x,
583 STATE.player.position.y,
584 resource.position.x,
585 resource.position.y
586 );
587
588 if (dist < minDist) {
589 minDist = dist;
590 nearest = resource;
591 }
592 }
593
594 return nearest;
595 }
596
597 // ============================================
598 // VISUAL ENHANCEMENTS
599 // ============================================
600
601 function createUI() {
602 const uiContainer = document.createElement('div');
603 uiContainer.id = 'moomoo-automation-ui';
604 uiContainer.style.cssText = `
605 position: fixed;
606 top: 10px;
607 right: 10px;
608 background: rgba(0, 0, 0, 0.8);
609 color: #fff;
610 padding: 15px;
611 border-radius: 10px;
612 font-family: Arial, sans-serif;
613 font-size: 12px;
614 z-index: 10000;
615 min-width: 200px;
616 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
617 `;
618
619 uiContainer.innerHTML = `
620 <div style="font-size: 14px; font-weight: bold; margin-bottom: 10px; color: #4CAF50;">
621 🎮 MooMoo.io Automation
622 </div>
623 <div style="margin-bottom: 8px;">
624 <label style="display: flex; align-items: center; cursor: pointer;">
625 <input type="checkbox" id="toggle-heal" ${CONFIG.autoHeal.enabled ? 'checked' : ''} style="margin-right: 8px;">
626 <span>🏥 Auto-Heal (Ctrl+H)</span>
627 </label>
628 </div>
629 <div style="margin-bottom: 8px;">
630 <label style="display: flex; align-items: center; cursor: pointer;">
631 <input type="checkbox" id="toggle-attack" ${CONFIG.autoAttack.enabled ? 'checked' : ''} style="margin-right: 8px;">
632 <span>⚔️ Auto-Attack (Ctrl+K)</span>
633 </label>
634 </div>
635 <div style="margin-bottom: 8px;">
636 <label style="display: flex; align-items: center; cursor: pointer;">
637 <input type="checkbox" id="toggle-gather" ${CONFIG.autoGather.enabled ? 'checked' : ''} style="margin-right: 8px;">
638 <span>⛏️ Auto-Gather (Ctrl+G)</span>
639 </label>
640 </div>
641 <div style="margin-bottom: 8px;">
642 <label style="display: flex; align-items: center; cursor: pointer;">
643 <input type="checkbox" id="toggle-dodge" ${CONFIG.combat.dodgeProjectiles ? 'checked' : ''} style="margin-right: 8px;">
644 <span>🏃 Auto-Dodge</span>
645 </label>
646 </div>
647 <div style="margin-bottom: 8px;">
648 <label style="display: flex; align-items: center; cursor: pointer;">
649 <input type="checkbox" id="toggle-kite" ${CONFIG.combat.kiteEnemies ? 'checked' : ''} style="margin-right: 8px;">
650 <span>🎯 Kite Enemies</span>
651 </label>
652 </div>
653 <div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(255,255,255,0.2);">
654 <div style="font-size: 11px; color: #aaa;">
655 Status: <span id="status-text" style="color: #4CAF50;">Active</span>
656 </div>
657 <div style="font-size: 11px; color: #aaa; margin-top: 4px;">
658 Health: <span id="health-text">100%</span>
659 </div>
660 </div>
661 `;
662
663 document.body.appendChild(uiContainer);
664
665 // Add event listeners
666 document.getElementById('toggle-heal').addEventListener('change', (e) => {
667 CONFIG.autoHeal.enabled = e.target.checked;
668 console.log(`Auto-heal: ${CONFIG.autoHeal.enabled ? 'ON' : 'OFF'}`);
669 });
670
671 document.getElementById('toggle-attack').addEventListener('change', (e) => {
672 CONFIG.autoAttack.enabled = e.target.checked;
673 console.log(`Auto-attack: ${CONFIG.autoAttack.enabled ? 'ON' : 'OFF'}`);
674 });
675
676 document.getElementById('toggle-gather').addEventListener('change', (e) => {
677 CONFIG.autoGather.enabled = e.target.checked;
678 console.log(`Auto-gather: ${CONFIG.autoGather.enabled ? 'ON' : 'OFF'}`);
679 });
680
681 document.getElementById('toggle-dodge').addEventListener('change', (e) => {
682 CONFIG.combat.dodgeProjectiles = e.target.checked;
683 console.log(`Auto-dodge: ${CONFIG.combat.dodgeProjectiles ? 'ON' : 'OFF'}`);
684 });
685
686 document.getElementById('toggle-kite').addEventListener('change', (e) => {
687 CONFIG.combat.kiteEnemies = e.target.checked;
688 console.log(`Kite enemies: ${CONFIG.combat.kiteEnemies ? 'ON' : 'OFF'}`);
689 });
690
691 console.log('✅ UI created');
692 }
693
694 function updateUI() {
695 const healthText = document.getElementById('health-text');
696 if (healthText) {
697 const healthPercent = (STATE.player.health / STATE.player.maxHealth) * 100;
698 healthText.textContent = `${healthPercent.toFixed(0)}%`;
699 healthText.style.color = healthPercent > 70 ? '#4CAF50' : healthPercent > 30 ? '#FFC107' : '#F44336';
700 }
701
702 const statusText = document.getElementById('status-text');
703 if (statusText) {
704 if (STATE.isInCombat) {
705 statusText.textContent = 'In Combat';
706 statusText.style.color = '#F44336';
707 } else if (STATE.targetResource) {
708 statusText.textContent = 'Gathering';
709 statusText.style.color = '#FFC107';
710 } else {
711 statusText.textContent = 'Active';
712 statusText.style.color = '#4CAF50';
713 }
714 }
715 }
716
717 function addCustomStyles() {
718 const style = document.createElement('style');
719 style.textContent = `
720 #moomoo-automation-ui * {
721 box-sizing: border-box;
722 }
723
724 #moomoo-automation-ui input[type="checkbox"] {
725 cursor: pointer;
726 width: 16px;
727 height: 16px;
728 }
729
730 #moomoo-automation-ui label:hover {
731 background: rgba(255, 255, 255, 0.1);
732 border-radius: 4px;
733 padding: 2px;
734 margin: -2px;
735 }
736 `;
737 document.head.appendChild(style);
738 }
739
740 // ============================================
741 // PERFORMANCE OPTIMIZATION
742 // ============================================
743
744 function optimizePerformance() {
745 if (!CONFIG.performance.reduceLag) return;
746
747 // Reduce rendering quality for better FPS
748 const canvas = document.getElementById('gameCanvas');
749 if (canvas && CONFIG.performance.fpsBoost) {
750 const ctx = canvas.getContext('2d');
751 ctx.imageSmoothingEnabled = false;
752 console.log('⚡ Performance optimizations applied');
753 }
754 }
755
756 // ============================================
757 // MAIN LOOP
758 // ============================================
759
760 function mainLoop() {
761 try {
762 autoHeal();
763 autoAttack();
764 autoGather();
765 autoDodge();
766 autoDefend();
767 kiteEnemy();
768 updateUI();
769 } catch (error) {
770 console.error('❌ Error in main loop:', error);
771 }
772 }
773
774 // ============================================
775 // INITIALIZATION
776 // ============================================
777
778 function init() {
779 console.log('🚀 Initializing MooMoo.io Ultimate Automation & Optimizer...');
780
781 // Wait for game to load
782 const checkGameLoaded = setInterval(() => {
783 const canvas = document.getElementById('gameCanvas');
784 if (canvas) {
785 clearInterval(checkGameLoaded);
786
787 // Initialize components
788 addCustomStyles();
789 createUI();
790 hookIntoGame();
791 optimizePerformance();
792
793 // Start main loop
794 setInterval(mainLoop, 50); // 20 times per second
795
796 console.log('✅ MooMoo.io Ultimate Automation & Optimizer - Ready!');
797 console.log('📋 Keyboard Shortcuts:');
798 console.log(' Ctrl+H - Toggle Auto-Heal');
799 console.log(' Ctrl+K - Toggle Auto-Attack');
800 console.log(' Ctrl+G - Toggle Auto-Gather');
801 }
802 }, 1000);
803 }
804
805 // Start the script
806 if (document.readyState === 'loading') {
807 document.addEventListener('DOMContentLoaded', init);
808 } else {
809 init();
810 }
811
812})();