Gameplay Optimizer for Veck.io

Advanced aimbot and ESP with right-click aim and E key ESP toggle

Size

28.2 KB

Version

1.1.1

Created

Dec 11, 2025

Updated

5 days ago

1// ==UserScript==
2// @name		Gameplay Optimizer for Veck.io
3// @description		Advanced aimbot and ESP with right-click aim and E key ESP toggle
4// @version		1.1.1
5// @match		https://*.veck.io/*
6// @icon		https://veck.io/favicon/favicon.ico
7// @grant		GM.getValue
8// @grant		GM.setValue
9// ==/UserScript==
10(function() {
11    'use strict';
12
13    console.log('[Veck.io Optimizer] Extension loaded - Aimbot & ESP');
14
15    // Feature states
16    let features = {
17        aimbot: false,
18        esp: false
19    };
20
21    let panelVisible = false;
22    let gameData = {
23        players: new Map(),
24        localPlayer: null,
25        enemies: [],
26        wsConnection: null
27    };
28
29    // WebSocket hook for intercepting game data
30    function hookWebSocket() {
31        const originalWebSocket = window.WebSocket;
32        
33        window.WebSocket = function(...args) {
34            console.log('[Veck.io Optimizer] WebSocket connection created:', args[0]);
35            const ws = new originalWebSocket(...args);
36            gameData.wsConnection = ws;
37            
38            // Intercept incoming messages
39            const originalAddEventListener = ws.addEventListener;
40            ws.addEventListener = function(type, listener, ...rest) {
41                if (type === 'message') {
42                    const wrappedListener = function(event) {
43                        try {
44                            interceptMessage(event.data);
45                        } catch (error) {
46                            console.error('[Veck.io Optimizer] Error intercepting message:', error);
47                        }
48                        return listener.apply(this, arguments);
49                    };
50                    return originalAddEventListener.call(this, type, wrappedListener, ...rest);
51                }
52                return originalAddEventListener.call(this, type, listener, ...rest);
53            };
54            
55            // Intercept outgoing messages
56            const originalSend = ws.send;
57            ws.send = function(data) {
58                try {
59                    const modified = modifyOutgoingData(data);
60                    if (modified !== data) {
61                        return originalSend.call(this, modified);
62                    }
63                } catch (error) {
64                    console.error('[Veck.io Optimizer] Error modifying outgoing data:', error);
65                }
66                return originalSend.apply(this, arguments);
67            };
68            
69            return ws;
70        };
71        
72        console.log('[Veck.io Optimizer] WebSocket hooked successfully');
73    }
74
75    // Intercept and parse game messages
76    function interceptMessage(data) {
77        try {
78            // Try to parse as JSON
79            if (typeof data === 'string') {
80                const parsed = JSON.parse(data);
81                processGameData(parsed);
82            } else if (data instanceof ArrayBuffer) {
83                // Handle binary data
84                processBinaryData(data);
85            } else if (data instanceof Blob) {
86                // Handle blob data
87                data.arrayBuffer().then(buffer => processBinaryData(buffer));
88            }
89        } catch (error) {
90            // Not JSON, might be binary protocol
91            if (data instanceof ArrayBuffer) {
92                processBinaryData(data);
93            }
94        }
95    }
96
97    // Process game data from WebSocket
98    function processGameData(data) {
99        // Look for player data in various formats
100        if (data.type === 'players' || data.players) {
101            const players = data.players || data;
102            if (Array.isArray(players)) {
103                players.forEach(player => {
104                    if (player.id && player.position) {
105                        gameData.players.set(player.id, player);
106                    }
107                });
108            }
109        }
110        
111        // Look for local player data
112        if (data.type === 'player' || data.you || data.self || data.localPlayer) {
113            gameData.localPlayer = data.you || data.self || data.localPlayer || data;
114            console.log('[Veck.io Optimizer] Local player updated:', gameData.localPlayer);
115        }
116        
117        // Look for enemy data
118        if (data.type === 'enemies' || data.entities) {
119            gameData.enemies = data.enemies || data.entities || [];
120        }
121        
122        // Look for update packets
123        if (data.type === 'update' || data.type === 'state') {
124            if (data.players) {
125                Object.keys(data.players).forEach(id => {
126                    const player = data.players[id];
127                    if (player.position) {
128                        gameData.players.set(id, player);
129                    }
130                });
131            }
132        }
133        
134        // Generic object scanning for position data
135        if (typeof data === 'object') {
136            Object.keys(data).forEach(key => {
137                const value = data[key];
138                if (value && typeof value === 'object') {
139                    // Check if it looks like position data
140                    if (value.x !== undefined && value.y !== undefined) {
141                        if (!gameData.positions) gameData.positions = [];
142                        gameData.positions.push(value);
143                    }
144                    // Check for player arrays
145                    if (Array.isArray(value)) {
146                        value.forEach(item => {
147                            if (item && item.id && item.position) {
148                                gameData.players.set(item.id, item);
149                            }
150                        });
151                    }
152                }
153            });
154        }
155    }
156
157    // Process binary game data
158    function processBinaryData(buffer) {
159        const view = new DataView(buffer);
160        
161        // Try to extract float positions (common in games)
162        try {
163            const positions = [];
164            for (let i = 0; i < buffer.byteLength - 11; i += 12) {
165                const x = view.getFloat32(i, true);
166                const y = view.getFloat32(i + 4, true);
167                const z = view.getFloat32(i + 8, true);
168                
169                // Sanity check for reasonable coordinates
170                if (Math.abs(x) < 10000 && Math.abs(y) < 10000 && Math.abs(z) < 10000) {
171                    positions.push({ x, y, z });
172                }
173            }
174            
175            if (positions.length > 0) {
176                gameData.binaryPositions = positions;
177                console.log('[Veck.io Optimizer] Extracted', positions.length, 'positions from binary data');
178            }
179        } catch (error) {
180            // Binary parsing failed
181        }
182    }
183
184    // Modify outgoing data for aimbot
185    function modifyOutgoingData(data) {
186        if (!features.aimbot) return data;
187        
188        try {
189            if (typeof data === 'string') {
190                const parsed = JSON.parse(data);
191                
192                // If this is a look/aim packet, modify it
193                if (parsed.type === 'look' || parsed.type === 'aim' || parsed.rotation || parsed.camera) {
194                    const target = getCurrentAimTarget();
195                    if (target) {
196                        const angles = calculateAimAngles(target);
197                        if (angles) {
198                            // Modify the rotation data
199                            if (parsed.rotation) {
200                                parsed.rotation.yaw = angles.yaw;
201                                parsed.rotation.pitch = angles.pitch;
202                            }
203                            if (parsed.camera) {
204                                parsed.camera.yaw = angles.yaw;
205                                parsed.camera.pitch = angles.pitch;
206                            }
207                            if (parsed.yaw !== undefined) {
208                                parsed.yaw = angles.yaw;
209                                parsed.pitch = angles.pitch;
210                            }
211                            console.log('[Veck.io Optimizer] Aimbot applied:', angles);
212                            return JSON.stringify(parsed);
213                        }
214                    }
215                }
216            }
217        } catch (error) {
218            // Not JSON or parsing failed
219        }
220        
221        return data;
222    }
223
224    // Load saved settings
225    async function loadSettings() {
226        try {
227            const saved = await GM.getValue('veckio_features', null);
228            if (saved) {
229                features = JSON.parse(saved);
230                console.log('[Veck.io Optimizer] Loaded settings:', features);
231            }
232        } catch (error) {
233            console.error('[Veck.io Optimizer] Error loading settings:', error);
234        }
235    }
236
237    // Save settings
238    async function saveSettings() {
239        try {
240            await GM.setValue('veckio_features', JSON.stringify(features));
241        } catch (error) {
242            console.error('[Veck.io Optimizer] Error saving settings:', error);
243        }
244    }
245
246    // Create control panel
247    function createPanel() {
248        const panel = document.createElement('div');
249        panel.id = 'veckio-optimizer-panel';
250        panel.innerHTML = `
251            <div class="veckio-panel-header">
252                <h3>🎮 Veck.io Optimizer</h3>
253                <button class="veckio-close-btn" id="veckio-close">×</button>
254            </div>
255            <div class="veckio-panel-content">
256                <div class="veckio-feature">
257                    <label class="veckio-switch">
258                        <input type="checkbox" id="aimbot-toggle" ${features.aimbot ? 'checked' : ''}>
259                        <span class="veckio-slider"></span>
260                    </label>
261                    <span class="veckio-label">🎯 Aimbot (Right Click)</span>
262                </div>
263                
264                <div class="veckio-feature">
265                    <label class="veckio-switch">
266                        <input type="checkbox" id="esp-toggle" ${features.esp ? 'checked' : ''}>
267                        <span class="veckio-slider"></span>
268                    </label>
269                    <span class="veckio-label">👁️ ESP (Press E)</span>
270                </div>
271                
272                <div class="veckio-info">
273                    <small>Press F2 to toggle panel | Players: <span id="player-count">0</span></small>
274                </div>
275            </div>
276        `;
277
278        document.body.appendChild(panel);
279        attachPanelListeners();
280        console.log('[Veck.io Optimizer] Panel created');
281    }
282
283    // Attach event listeners to panel controls
284    function attachPanelListeners() {
285        const closeBtn = document.getElementById('veckio-close');
286        if (closeBtn) {
287            closeBtn.addEventListener('click', togglePanel);
288        }
289
290        // Aimbot toggle
291        const aimbotToggle = document.getElementById('aimbot-toggle');
292        if (aimbotToggle) {
293            aimbotToggle.addEventListener('change', (e) => {
294                features.aimbot = e.target.checked;
295                saveSettings();
296                console.log('[Veck.io Optimizer] Aimbot:', features.aimbot);
297                if (features.aimbot) {
298                    enableAimbot();
299                } else {
300                    disableAimbot();
301                }
302            });
303        }
304
305        // ESP toggle
306        const espToggle = document.getElementById('esp-toggle');
307        if (espToggle) {
308            espToggle.addEventListener('change', (e) => {
309                features.esp = e.target.checked;
310                saveSettings();
311                console.log('[Veck.io Optimizer] ESP:', features.esp);
312                if (features.esp) {
313                    enableESP();
314                } else {
315                    disableESP();
316                }
317            });
318        }
319    }
320
321    // Toggle panel visibility
322    function togglePanel() {
323        const panel = document.getElementById('veckio-optimizer-panel');
324        if (panel) {
325            panelVisible = !panelVisible;
326            panel.style.display = panelVisible ? 'block' : 'none';
327        }
328    }
329
330    // ESP implementation with canvas overlay
331    let espCanvas = null;
332    let espContext = null;
333    let espInterval = null;
334
335    function enableESP() {
336        console.log('[Veck.io Optimizer] Enabling ESP');
337        
338        // Create overlay canvas
339        espCanvas = document.createElement('canvas');
340        espCanvas.id = 'veckio-esp-canvas';
341        espCanvas.style.cssText = `
342            position: fixed;
343            top: 0;
344            left: 0;
345            width: 100%;
346            height: 100%;
347            pointer-events: none;
348            z-index: 9998;
349        `;
350        espCanvas.width = window.innerWidth;
351        espCanvas.height = window.innerHeight;
352        document.body.appendChild(espCanvas);
353        
354        espContext = espCanvas.getContext('2d');
355        
356        // Update ESP overlay
357        espInterval = setInterval(() => {
358            drawESP();
359        }, 16); // ~60 FPS
360
361        // Handle window resize
362        window.addEventListener('resize', resizeESPCanvas);
363    }
364
365    function resizeESPCanvas() {
366        if (espCanvas) {
367            espCanvas.width = window.innerWidth;
368            espCanvas.height = window.innerHeight;
369        }
370    }
371
372    function disableESP() {
373        console.log('[Veck.io Optimizer] Disabling ESP');
374        
375        if (espInterval) {
376            clearInterval(espInterval);
377            espInterval = null;
378        }
379        
380        if (espCanvas) {
381            espCanvas.remove();
382            espCanvas = null;
383            espContext = null;
384        }
385        
386        window.removeEventListener('resize', resizeESPCanvas);
387    }
388
389    function drawESP() {
390        if (!espContext) return;
391        
392        // Clear canvas
393        espContext.clearRect(0, 0, espCanvas.width, espCanvas.height);
394        
395        // Update player count
396        const playerCount = gameData.players.size;
397        const playerCountEl = document.getElementById('player-count');
398        if (playerCountEl) {
399            playerCountEl.textContent = playerCount;
400        }
401        
402        // Draw ESP for all players
403        gameData.players.forEach((player) => {
404            if (!player.position) return;
405            
406            // Skip local player
407            if (gameData.localPlayer && player.id === gameData.localPlayer.id) return;
408            
409            // Project 3D position to 2D screen
410            const screenPos = worldToScreen(player.position);
411            if (!screenPos) return;
412            
413            // Determine if enemy
414            const isEnemy = !player.team || (gameData.localPlayer && player.team !== gameData.localPlayer.team);
415            
416            // Draw box
417            espContext.strokeStyle = isEnemy ? '#ff0000' : '#00ff00';
418            espContext.lineWidth = 2;
419            const boxWidth = 40;
420            const boxHeight = 80;
421            espContext.strokeRect(
422                screenPos.x - boxWidth / 2,
423                screenPos.y - boxHeight / 2,
424                boxWidth,
425                boxHeight
426            );
427            
428            // Draw head indicator (small circle at top)
429            espContext.fillStyle = '#ffff00';
430            espContext.beginPath();
431            espContext.arc(screenPos.x, screenPos.y - boxHeight / 2, 5, 0, Math.PI * 2);
432            espContext.fill();
433            
434            // Draw name
435            espContext.fillStyle = '#ffffff';
436            espContext.font = 'bold 12px Arial';
437            espContext.fillText(
438                player.name || 'Player',
439                screenPos.x - 20,
440                screenPos.y - boxHeight / 2 - 10
441            );
442            
443            // Draw health bar
444            if (player.health !== undefined) {
445                const healthPercent = player.health / (player.maxHealth || 100);
446                espContext.fillStyle = healthPercent > 0.5 ? '#00ff00' : '#ff0000';
447                espContext.fillRect(
448                    screenPos.x - boxWidth / 2,
449                    screenPos.y + boxHeight / 2 + 5,
450                    boxWidth * healthPercent,
451                    5
452                );
453            }
454            
455            // Draw distance
456            if (gameData.localPlayer && gameData.localPlayer.position) {
457                const distance = calculateDistance(
458                    gameData.localPlayer.position,
459                    player.position
460                );
461                espContext.fillStyle = '#ffff00';
462                espContext.font = '11px Arial';
463                espContext.fillText(
464                    Math.round(distance) + 'm',
465                    screenPos.x - 15,
466                    screenPos.y + boxHeight / 2 + 20
467                );
468            }
469        });
470        
471        // Draw binary positions if available
472        if (gameData.binaryPositions) {
473            gameData.binaryPositions.forEach(pos => {
474                const screenPos = worldToScreen(pos);
475                if (screenPos) {
476                    espContext.fillStyle = '#ff00ff';
477                    espContext.beginPath();
478                    espContext.arc(screenPos.x, screenPos.y, 5, 0, Math.PI * 2);
479                    espContext.fill();
480                }
481            });
482        }
483    }
484
485    // Convert 3D world position to 2D screen position
486    function worldToScreen(worldPos) {
487        const canvas = document.getElementById('unity-canvas');
488        if (!canvas) return null;
489        
490        const centerX = canvas.width / 2;
491        const centerY = canvas.height / 2;
492        
493        // Simple orthographic projection
494        const scale = 10; // Adjust based on game scale
495        const screenX = centerX + (worldPos.x * scale);
496        const screenY = centerY - (worldPos.y * scale);
497        
498        // Check if on screen
499        if (screenX < 0 || screenX > canvas.width || screenY < 0 || screenY > canvas.height) {
500            return null;
501        }
502        
503        return { x: screenX, y: screenY };
504    }
505
506    // Calculate distance between two 3D points
507    function calculateDistance(pos1, pos2) {
508        const dx = pos2.x - pos1.x;
509        const dy = pos2.y - pos1.y;
510        const dz = (pos2.z || 0) - (pos1.z || 0);
511        return Math.sqrt(dx * dx + dy * dy + dz * dz);
512    }
513
514    // Aimbot implementation
515    let aimbotInterval = null;
516    let isRightClickHeld = false;
517
518    function enableAimbot() {
519        console.log('[Veck.io Optimizer] Enabling aimbot');
520        
521        // Listen for right click
522        document.addEventListener('mousedown', handleRightClick);
523        document.addEventListener('mouseup', handleRightClickRelease);
524        document.addEventListener('contextmenu', preventContextMenu);
525        
526        // Start aimbot loop
527        aimbotInterval = setInterval(() => {
528            if (isRightClickHeld) {
529                applyAimbot();
530            }
531        }, 10); // 100 FPS for smooth aiming
532    }
533
534    function disableAimbot() {
535        console.log('[Veck.io Optimizer] Disabling aimbot');
536        
537        document.removeEventListener('mousedown', handleRightClick);
538        document.removeEventListener('mouseup', handleRightClickRelease);
539        document.removeEventListener('contextmenu', preventContextMenu);
540        
541        if (aimbotInterval) {
542            clearInterval(aimbotInterval);
543            aimbotInterval = null;
544        }
545        
546        isRightClickHeld = false;
547    }
548
549    function handleRightClick(e) {
550        if (e.button === 2) { // Right click
551            isRightClickHeld = true;
552            console.log('[Veck.io Optimizer] Aimbot activated (right click held)');
553        }
554    }
555
556    function handleRightClickRelease(e) {
557        if (e.button === 2) { // Right click
558            isRightClickHeld = false;
559            console.log('[Veck.io Optimizer] Aimbot deactivated (right click released)');
560        }
561    }
562
563    function preventContextMenu(e) {
564        if (features.aimbot) {
565            e.preventDefault();
566            return false;
567        }
568    }
569
570    function applyAimbot() {
571        if (!gameData.localPlayer || !gameData.localPlayer.position) return;
572        
573        const target = getCurrentAimTarget();
574        if (!target) return;
575        
576        const angles = calculateAimAngles(target);
577        if (!angles) return;
578        
579        // Send aim command through WebSocket
580        if (gameData.wsConnection && gameData.wsConnection.readyState === WebSocket.OPEN) {
581            try {
582                const aimData = JSON.stringify({
583                    type: 'aim',
584                    yaw: angles.yaw,
585                    pitch: angles.pitch
586                });
587                gameData.wsConnection.send(aimData);
588            } catch (error) {
589                console.error('[Veck.io Optimizer] Failed to send aim data:', error);
590            }
591        }
592    }
593
594    function getCurrentAimTarget() {
595        if (!gameData.localPlayer || !gameData.localPlayer.position) return null;
596        
597        let closestEnemy = null;
598        let closestDistance = Infinity;
599        
600        // Find closest enemy
601        gameData.players.forEach((player) => {
602            if (!player.position) return;
603            if (gameData.localPlayer && player.id === gameData.localPlayer.id) return;
604            
605            // Check if enemy (different team or no team)
606            const isEnemy = !player.team || (gameData.localPlayer.team && player.team !== gameData.localPlayer.team);
607            if (!isEnemy) return;
608            
609            const distance = calculateDistance(
610                gameData.localPlayer.position,
611                player.position
612            );
613            
614            if (distance < closestDistance) {
615                closestDistance = distance;
616                closestEnemy = player;
617            }
618        });
619        
620        return closestEnemy;
621    }
622
623    function calculateAimAngles(target) {
624        if (!gameData.localPlayer || !gameData.localPlayer.position || !target.position) return null;
625        
626        // Calculate head position (add height offset)
627        const headOffset = 1.7; // Typical head height in meters
628        const targetHeadPos = {
629            x: target.position.x,
630            y: target.position.y,
631            z: (target.position.z || 0) + headOffset
632        };
633        
634        // Calculate aim angles to head
635        const dx = targetHeadPos.x - gameData.localPlayer.position.x;
636        const dy = targetHeadPos.y - gameData.localPlayer.position.y;
637        const dz = targetHeadPos.z - (gameData.localPlayer.position.z || 0);
638        
639        const yaw = Math.atan2(dy, dx);
640        const pitch = Math.atan2(dz, Math.sqrt(dx * dx + dy * dy));
641        
642        return { yaw, pitch };
643    }
644
645    // Add CSS styles
646    function addStyles() {
647        const style = document.createElement('style');
648        style.textContent = `
649            #veckio-optimizer-panel {
650                position: fixed;
651                top: 50%;
652                left: 50%;
653                transform: translate(-50%, -50%);
654                background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%);
655                border: 2px solid #00ff88;
656                border-radius: 15px;
657                padding: 0;
658                z-index: 9999;
659                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
660                box-shadow: 0 10px 40px rgba(0, 255, 136, 0.3);
661                min-width: 320px;
662                display: none;
663            }
664
665            .veckio-panel-header {
666                background: linear-gradient(135deg, #00ff88 0%, #00cc6a 100%);
667                padding: 15px 20px;
668                border-radius: 13px 13px 0 0;
669                display: flex;
670                justify-content: space-between;
671                align-items: center;
672            }
673
674            .veckio-panel-header h3 {
675                margin: 0;
676                color: #1e1e2e;
677                font-size: 18px;
678                font-weight: bold;
679            }
680
681            .veckio-close-btn {
682                background: transparent;
683                border: none;
684                color: #1e1e2e;
685                font-size: 24px;
686                cursor: pointer;
687                padding: 0;
688                width: 30px;
689                height: 30px;
690                display: flex;
691                align-items: center;
692                justify-content: center;
693                border-radius: 5px;
694                transition: background 0.3s;
695            }
696
697            .veckio-close-btn:hover {
698                background: rgba(0, 0, 0, 0.1);
699            }
700
701            .veckio-panel-content {
702                padding: 20px;
703            }
704
705            .veckio-feature {
706                display: flex;
707                align-items: center;
708                margin-bottom: 15px;
709                padding: 12px;
710                background: rgba(255, 255, 255, 0.05);
711                border-radius: 8px;
712                transition: background 0.3s;
713            }
714
715            .veckio-feature:hover {
716                background: rgba(255, 255, 255, 0.08);
717            }
718
719            .veckio-label {
720                color: #ffffff;
721                font-size: 14px;
722                margin-left: 15px;
723                flex: 1;
724            }
725
726            .veckio-switch {
727                position: relative;
728                display: inline-block;
729                width: 50px;
730                height: 26px;
731            }
732
733            .veckio-switch input {
734                opacity: 0;
735                width: 0;
736                height: 0;
737            }
738
739            .veckio-slider {
740                position: absolute;
741                cursor: pointer;
742                top: 0;
743                left: 0;
744                right: 0;
745                bottom: 0;
746                background-color: #555;
747                transition: 0.4s;
748                border-radius: 26px;
749            }
750
751            .veckio-slider:before {
752                position: absolute;
753                content: "";
754                height: 18px;
755                width: 18px;
756                left: 4px;
757                bottom: 4px;
758                background-color: white;
759                transition: 0.4s;
760                border-radius: 50%;
761            }
762
763            input:checked + .veckio-slider {
764                background-color: #00ff88;
765            }
766
767            input:checked + .veckio-slider:before {
768                transform: translateX(24px);
769            }
770
771            .veckio-info {
772                text-align: center;
773                margin-top: 15px;
774                padding-top: 15px;
775                border-top: 1px solid rgba(255, 255, 255, 0.1);
776            }
777
778            .veckio-info small {
779                color: #888;
780                font-size: 12px;
781            }
782            
783            #player-count {
784                color: #00ff88;
785                font-weight: bold;
786            }
787        `;
788        document.head.appendChild(style);
789    }
790
791    // Initialize extension
792    async function init() {
793        console.log('[Veck.io Optimizer] Initializing...');
794        
795        // Hook WebSocket BEFORE page loads
796        hookWebSocket();
797        
798        // Wait for page to load
799        if (document.readyState === 'loading') {
800            document.addEventListener('DOMContentLoaded', initUI);
801        } else {
802            initUI();
803        }
804    }
805
806    async function initUI() {
807        // Load settings
808        await loadSettings();
809
810        // Add styles
811        addStyles();
812
813        // Create panel
814        createPanel();
815
816        // Listen for F2 key to toggle panel
817        document.addEventListener('keydown', (e) => {
818            if (e.key === 'F2') {
819                e.preventDefault();
820                togglePanel();
821            }
822            
823            // Listen for E key to toggle ESP
824            if (e.key === 'e' || e.key === 'E') {
825                const espToggle = document.getElementById('esp-toggle');
826                if (espToggle && !e.repeat) {
827                    features.esp = !features.esp;
828                    espToggle.checked = features.esp;
829                    saveSettings();
830                    console.log('[Veck.io Optimizer] ESP toggled via E key:', features.esp);
831                    if (features.esp) {
832                        enableESP();
833                    } else {
834                        disableESP();
835                    }
836                }
837            }
838        });
839
840        // Apply enabled features from saved settings
841        if (features.aimbot) enableAimbot();
842        if (features.esp) enableESP();
843
844        console.log('[Veck.io Optimizer] Ready! Press F2 for panel, Right-Click for aimbot, E for ESP');
845    }
846
847    // Start the extension
848    init();
849})();
Gameplay Optimizer for Veck.io | Robomonkey