Gameplay Optimizer for Veck.io

Advanced gameplay optimizer with aimbot, ESP, noclip, fly, infinite ammo, speed control, and weapon unlock features

Size

26.5 KB

Version

1.1.3

Created

Dec 11, 2025

Updated

5 days ago

1// ==UserScript==
2// @name		Gameplay Optimizer for Veck.io
3// @description		Advanced gameplay optimizer with aimbot, ESP, noclip, fly, infinite ammo, speed control, and weapon unlock features
4// @version		1.1.3
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 v1.2.0');
14
15    // Feature states
16    let features = {
17        aimbot: false,
18        esp: false
19    };
20
21    let panelVisible = false;
22    let gameData = {
23        players: [],
24        localPlayer: null,
25        matrices: {
26            modelView: null,
27            projection: null
28        }
29    };
30
31    // WebGL hooking for ESP and aimbot
32    let glContext = null;
33    let espCanvas = null;
34    let espContext = null;
35    let espInterval = null;
36    let aimbotInterval = null;
37
38    // Hook WebGL context to intercept rendering calls
39    function hookWebGL() {
40        console.log('[Veck.io Optimizer] Hooking WebGL...');
41        
42        const canvas = document.getElementById('unity-canvas');
43        if (!canvas) {
44            console.log('[Veck.io Optimizer] Unity canvas not found yet, will retry...');
45            return false;
46        }
47
48        // Hook getContext to capture WebGL context
49        const originalGetContext = HTMLCanvasElement.prototype.getContext;
50        HTMLCanvasElement.prototype.getContext = function(type, ...args) {
51            const context = originalGetContext.call(this, type, ...args);
52            
53            if ((type === 'webgl' || type === 'webgl2') && this.id === 'unity-canvas') {
54                console.log('[Veck.io Optimizer] WebGL context captured');
55                glContext = context;
56                hookWebGLCalls(context);
57            }
58            
59            return context;
60        };
61
62        // Try to get existing context
63        const gl = canvas.getContext('webgl') || canvas.getContext('webgl2');
64        if (gl) {
65            glContext = gl;
66            hookWebGLCalls(gl);
67        }
68        
69        return true;
70    }
71
72    // Hook WebGL rendering calls to extract player data
73    function hookWebGLCalls(gl) {
74        console.log('[Veck.io Optimizer] Hooking WebGL rendering calls');
75
76        // Hook uniformMatrix4fv to capture transformation matrices
77        const originalUniformMatrix4fv = gl.uniformMatrix4fv;
78        gl.uniformMatrix4fv = function(location, transpose, value) {
79            if (location && value && value.length === 16) {
80                // Store matrices for position calculations
81                if (!gameData.matrices.modelView) {
82                    gameData.matrices.modelView = Array.from(value);
83                } else {
84                    gameData.matrices.projection = Array.from(value);
85                }
86            }
87            return originalUniformMatrix4fv.call(this, location, transpose, value);
88        };
89
90        // Hook uniform3fv to capture positions
91        const originalUniform3fv = gl.uniform3fv;
92        gl.uniform3fv = function(location, value) {
93            if (location && value && value.length >= 3) {
94                // This might be a position vector
95                const x = value[0];
96                const y = value[1];
97                const z = value[2];
98                
99                // Filter out unreasonable values
100                if (Math.abs(x) < 1000 && Math.abs(y) < 1000 && Math.abs(z) < 1000) {
101                    // Check if this is a new position
102                    const posKey = `${x.toFixed(2)},${y.toFixed(2)},${z.toFixed(2)}`;
103                    const existingPlayer = gameData.players.find(p => p.posKey === posKey);
104                    
105                    if (!existingPlayer) {
106                        gameData.players.push({
107                            position: { x, y, z },
108                            posKey: posKey,
109                            timestamp: Date.now()
110                        });
111                        
112                        // Keep only recent players (last 2 seconds)
113                        const now = Date.now();
114                        gameData.players = gameData.players.filter(p => now - p.timestamp < 2000);
115                        
116                        // Limit to 50 players max
117                        if (gameData.players.length > 50) {
118                            gameData.players.shift();
119                        }
120                    }
121                }
122            }
123            return originalUniform3fv.call(this, location, value);
124        };
125
126        // Hook uniform4fv to capture positions
127        const originalUniform4fv = gl.uniform4fv;
128        gl.uniform4fv = function(location, value) {
129            if (location && value && value.length >= 3) {
130                const x = value[0];
131                const y = value[1];
132                const z = value[2];
133                
134                if (Math.abs(x) < 1000 && Math.abs(y) < 1000 && Math.abs(z) < 1000) {
135                    const posKey = `${x.toFixed(2)},${y.toFixed(2)},${z.toFixed(2)}`;
136                    const existingPlayer = gameData.players.find(p => p.posKey === posKey);
137                    
138                    if (!existingPlayer) {
139                        gameData.players.push({
140                            position: { x, y, z },
141                            posKey: posKey,
142                            timestamp: Date.now()
143                        });
144                        
145                        const now = Date.now();
146                        gameData.players = gameData.players.filter(p => now - p.timestamp < 2000);
147                        
148                        if (gameData.players.length > 50) {
149                            gameData.players.shift();
150                        }
151                    }
152                }
153            }
154            return originalUniform4fv.call(this, location, value);
155        };
156
157        // Hook drawArrays and drawElements to track rendering
158        const originalDrawArrays = gl.drawArrays;
159        gl.drawArrays = function(mode, first, count) {
160            return originalDrawArrays.call(this, mode, first, count);
161        };
162
163        const originalDrawElements = gl.drawElements;
164        gl.drawElements = function(mode, count, type, offset) {
165            return originalDrawElements.call(this, mode, count, type, offset);
166        };
167
168        console.log('[Veck.io Optimizer] WebGL hooks installed successfully');
169    }
170
171    // Load saved settings
172    async function loadSettings() {
173        try {
174            const saved = await GM.getValue('veckio_features', null);
175            if (saved) {
176                features = JSON.parse(saved);
177                console.log('[Veck.io Optimizer] Loaded settings:', features);
178            }
179        } catch (error) {
180            console.error('[Veck.io Optimizer] Error loading settings:', error);
181        }
182    }
183
184    // Save settings
185    async function saveSettings() {
186        try {
187            await GM.setValue('veckio_features', JSON.stringify(features));
188        } catch (error) {
189            console.error('[Veck.io Optimizer] Error saving settings:', error);
190        }
191    }
192
193    // Create control panel
194    function createPanel() {
195        const panel = document.createElement('div');
196        panel.id = 'veckio-optimizer-panel';
197        panel.innerHTML = `
198            <div class="veckio-panel-header">
199                <h3>🎮 Veck.io Optimizer</h3>
200                <button class="veckio-close-btn" id="veckio-close">×</button>
201            </div>
202            <div class="veckio-panel-content">
203                <div class="veckio-feature">
204                    <label class="veckio-switch">
205                        <input type="checkbox" id="aimbot-toggle" ${features.aimbot ? 'checked' : ''}>
206                        <span class="veckio-slider"></span>
207                    </label>
208                    <span class="veckio-label">🎯 Aimbot (Press F)</span>
209                </div>
210                
211                <div class="veckio-feature">
212                    <label class="veckio-switch">
213                        <input type="checkbox" id="esp-toggle" ${features.esp ? 'checked' : ''}>
214                        <span class="veckio-slider"></span>
215                    </label>
216                    <span class="veckio-label">👁️ ESP (Press E)</span>
217                </div>
218                
219                <div class="veckio-info">
220                    <small>Press F2 to toggle panel | Players detected: <span id="player-count">0</span></small>
221                </div>
222            </div>
223        `;
224
225        document.body.appendChild(panel);
226        attachPanelListeners();
227        console.log('[Veck.io Optimizer] Panel created');
228    }
229
230    // Attach event listeners to panel controls
231    function attachPanelListeners() {
232        const closeBtn = document.getElementById('veckio-close');
233        if (closeBtn) {
234            closeBtn.addEventListener('click', togglePanel);
235        }
236
237        // Aimbot toggle
238        const aimbotToggle = document.getElementById('aimbot-toggle');
239        if (aimbotToggle) {
240            aimbotToggle.addEventListener('change', (e) => {
241                features.aimbot = e.target.checked;
242                saveSettings();
243                console.log('[Veck.io Optimizer] Aimbot:', features.aimbot);
244                if (features.aimbot) {
245                    enableAimbot();
246                } else {
247                    disableAimbot();
248                }
249            });
250        }
251
252        // ESP toggle
253        const espToggle = document.getElementById('esp-toggle');
254        if (espToggle) {
255            espToggle.addEventListener('change', (e) => {
256                features.esp = e.target.checked;
257                saveSettings();
258                console.log('[Veck.io Optimizer] ESP:', features.esp);
259                if (features.esp) {
260                    enableESP();
261                } else {
262                    disableESP();
263                }
264            });
265        }
266    }
267
268    // Toggle panel visibility
269    function togglePanel() {
270        const panel = document.getElementById('veckio-optimizer-panel');
271        if (panel) {
272            panelVisible = !panelVisible;
273            panel.style.display = panelVisible ? 'block' : 'none';
274        }
275    }
276
277    // ESP implementation with canvas overlay
278    function enableESP() {
279        console.log('[Veck.io Optimizer] Enabling ESP');
280        
281        // Remove existing canvas if any
282        if (espCanvas) {
283            espCanvas.remove();
284        }
285        
286        // Create overlay canvas
287        espCanvas = document.createElement('canvas');
288        espCanvas.id = 'veckio-esp-canvas';
289        espCanvas.style.cssText = `
290            position: fixed;
291            top: 0;
292            left: 0;
293            width: 100vw;
294            height: 100vh;
295            pointer-events: none;
296            z-index: 9998;
297        `;
298        espCanvas.width = window.innerWidth;
299        espCanvas.height = window.innerHeight;
300        document.body.appendChild(espCanvas);
301        
302        espContext = espCanvas.getContext('2d');
303        
304        // Clear any existing interval
305        if (espInterval) {
306            clearInterval(espInterval);
307        }
308        
309        // Update ESP overlay
310        espInterval = setInterval(() => {
311            drawESP();
312        }, 16); // ~60 FPS
313
314        // Handle window resize
315        window.addEventListener('resize', resizeESPCanvas);
316        
317        console.log('[Veck.io Optimizer] ESP enabled successfully');
318    }
319
320    function resizeESPCanvas() {
321        if (espCanvas) {
322            espCanvas.width = window.innerWidth;
323            espCanvas.height = window.innerHeight;
324        }
325    }
326
327    function disableESP() {
328        console.log('[Veck.io Optimizer] Disabling ESP');
329        
330        if (espInterval) {
331            clearInterval(espInterval);
332            espInterval = null;
333        }
334        
335        if (espCanvas) {
336            espCanvas.remove();
337            espCanvas = null;
338            espContext = null;
339        }
340        
341        window.removeEventListener('resize', resizeESPCanvas);
342    }
343
344    function drawESP() {
345        if (!espContext || !espCanvas) return;
346        
347        // Clear canvas
348        espContext.clearRect(0, 0, espCanvas.width, espCanvas.height);
349        
350        // Update player count
351        const playerCountEl = document.getElementById('player-count');
352        if (playerCountEl) {
353            playerCountEl.textContent = gameData.players.length;
354        }
355        
356        // Draw ESP for all detected players
357        gameData.players.forEach((player, index) => {
358            if (!player.position) return;
359            
360            // Project 3D position to 2D screen
361            const screenPos = worldToScreen(player.position);
362            if (!screenPos) return;
363            
364            // Draw box
365            espContext.strokeStyle = '#00ff00';
366            espContext.lineWidth = 2;
367            const boxWidth = 40;
368            const boxHeight = 80;
369            espContext.strokeRect(
370                screenPos.x - boxWidth / 2,
371                screenPos.y - boxHeight / 2,
372                boxWidth,
373                boxHeight
374            );
375            
376            // Draw player indicator
377            espContext.fillStyle = '#00ff00';
378            espContext.font = 'bold 12px Arial';
379            espContext.fillText(
380                `Player ${index + 1}`,
381                screenPos.x - 25,
382                screenPos.y - boxHeight / 2 - 5
383            );
384            
385            // Draw distance if we have local player position
386            if (gameData.localPlayer && gameData.localPlayer.position) {
387                const distance = calculateDistance(
388                    gameData.localPlayer.position,
389                    player.position
390                );
391                espContext.fillStyle = '#ffff00';
392                espContext.fillText(
393                    Math.round(distance) + 'm',
394                    screenPos.x - 15,
395                    screenPos.y + boxHeight / 2 + 20
396                );
397            }
398            
399            // Draw crosshair on player
400            espContext.strokeStyle = '#ff0000';
401            espContext.lineWidth = 1;
402            const crosshairSize = 10;
403            espContext.beginPath();
404            espContext.moveTo(screenPos.x - crosshairSize, screenPos.y);
405            espContext.lineTo(screenPos.x + crosshairSize, screenPos.y);
406            espContext.moveTo(screenPos.x, screenPos.y - crosshairSize);
407            espContext.lineTo(screenPos.x, screenPos.y + crosshairSize);
408            espContext.stroke();
409        });
410    }
411
412    // Convert 3D world position to 2D screen position
413    function worldToScreen(worldPos) {
414        const canvas = document.getElementById('unity-canvas');
415        if (!canvas) return null;
416        
417        const centerX = canvas.width / 2;
418        const centerY = canvas.height / 2;
419        
420        // Simple orthographic projection with perspective
421        const scale = 5;
422        const depth = worldPos.z || 0;
423        const perspectiveFactor = 1 / (1 + depth * 0.01);
424        
425        const screenX = centerX + (worldPos.x * scale * perspectiveFactor);
426        const screenY = centerY - (worldPos.y * scale * perspectiveFactor);
427        
428        // Check if on screen
429        if (screenX < 0 || screenX > canvas.width || screenY < 0 || screenY > canvas.height) {
430            return null;
431        }
432        
433        return { x: screenX, y: screenY };
434    }
435
436    // Calculate distance between two 3D points
437    function calculateDistance(pos1, pos2) {
438        const dx = pos2.x - pos1.x;
439        const dy = pos2.y - pos1.y;
440        const dz = (pos2.z || 0) - (pos1.z || 0);
441        return Math.sqrt(dx * dx + dy * dy + dz * dz);
442    }
443
444    // Aimbot implementation
445    function enableAimbot() {
446        console.log('[Veck.io Optimizer] Enabling aimbot');
447        
448        // Clear any existing interval
449        if (aimbotInterval) {
450            clearInterval(aimbotInterval);
451        }
452        
453        aimbotInterval = setInterval(() => {
454            if (gameData.players.length === 0) return;
455            
456            // Find closest player
457            let closestPlayer = null;
458            let closestDistance = Infinity;
459            
460            gameData.players.forEach(player => {
461                if (!player.position) return;
462                
463                // Calculate distance from screen center
464                const screenPos = worldToScreen(player.position);
465                if (!screenPos) return;
466                
467                const canvas = document.getElementById('unity-canvas');
468                if (!canvas) return;
469                
470                const centerX = canvas.width / 2;
471                const centerY = canvas.height / 2;
472                
473                const distanceFromCenter = Math.sqrt(
474                    Math.pow(screenPos.x - centerX, 2) + 
475                    Math.pow(screenPos.y - centerY, 2)
476                );
477                
478                if (distanceFromCenter < closestDistance) {
479                    closestDistance = distanceFromCenter;
480                    closestPlayer = player;
481                }
482            });
483            
484            if (closestPlayer) {
485                aimAtTarget(closestPlayer.position);
486            }
487        }, 50);
488        
489        console.log('[Veck.io Optimizer] Aimbot enabled successfully');
490    }
491
492    function disableAimbot() {
493        console.log('[Veck.io Optimizer] Disabling aimbot');
494        if (aimbotInterval) {
495            clearInterval(aimbotInterval);
496            aimbotInterval = null;
497        }
498    }
499
500    function aimAtTarget(targetPos) {
501        const canvas = document.getElementById('unity-canvas');
502        if (!canvas) return;
503        
504        // Calculate screen position
505        const screenPos = worldToScreen(targetPos);
506        if (!screenPos) return;
507        
508        // Simulate mouse movement to target
509        const centerX = canvas.width / 2;
510        const centerY = canvas.height / 2;
511        
512        const deltaX = screenPos.x - centerX;
513        const deltaY = screenPos.y - centerY;
514        
515        // Create and dispatch mouse move event
516        const mouseMoveEvent = new MouseEvent('mousemove', {
517            bubbles: true,
518            cancelable: true,
519            view: window,
520            clientX: screenPos.x,
521            clientY: screenPos.y,
522            movementX: deltaX,
523            movementY: deltaY
524        });
525        
526        canvas.dispatchEvent(mouseMoveEvent);
527    }
528
529    // Add CSS styles
530    function addStyles() {
531        const style = document.createElement('style');
532        style.textContent = `
533            #veckio-optimizer-panel {
534                position: fixed;
535                top: 50%;
536                left: 50%;
537                transform: translate(-50%, -50%);
538                background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%);
539                border: 2px solid #00ff88;
540                border-radius: 15px;
541                padding: 0;
542                z-index: 9999;
543                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
544                box-shadow: 0 10px 40px rgba(0, 255, 136, 0.3);
545                min-width: 350px;
546                display: none;
547            }
548
549            .veckio-panel-header {
550                background: linear-gradient(135deg, #00ff88 0%, #00cc6a 100%);
551                padding: 15px 20px;
552                border-radius: 13px 13px 0 0;
553                display: flex;
554                justify-content: space-between;
555                align-items: center;
556            }
557
558            .veckio-panel-header h3 {
559                margin: 0;
560                color: #1e1e2e;
561                font-size: 18px;
562                font-weight: bold;
563            }
564
565            .veckio-close-btn {
566                background: transparent;
567                border: none;
568                color: #1e1e2e;
569                font-size: 24px;
570                cursor: pointer;
571                padding: 0;
572                width: 30px;
573                height: 30px;
574                display: flex;
575                align-items: center;
576                justify-content: center;
577                border-radius: 5px;
578                transition: background 0.3s;
579            }
580
581            .veckio-close-btn:hover {
582                background: rgba(0, 0, 0, 0.1);
583            }
584
585            .veckio-panel-content {
586                padding: 20px;
587            }
588
589            .veckio-feature {
590                display: flex;
591                align-items: center;
592                margin-bottom: 15px;
593                padding: 10px;
594                background: rgba(255, 255, 255, 0.05);
595                border-radius: 8px;
596                transition: background 0.3s;
597            }
598
599            .veckio-feature:hover {
600                background: rgba(255, 255, 255, 0.08);
601            }
602
603            .veckio-label {
604                color: #ffffff;
605                font-size: 14px;
606                margin-left: 15px;
607                flex: 1;
608            }
609
610            .veckio-switch {
611                position: relative;
612                display: inline-block;
613                width: 50px;
614                height: 26px;
615            }
616
617            .veckio-switch input {
618                opacity: 0;
619                width: 0;
620                height: 0;
621            }
622
623            .veckio-slider {
624                position: absolute;
625                cursor: pointer;
626                top: 0;
627                left: 0;
628                right: 0;
629                bottom: 0;
630                background-color: #555;
631                transition: 0.4s;
632                border-radius: 26px;
633            }
634
635            .veckio-slider:before {
636                position: absolute;
637                content: "";
638                height: 18px;
639                width: 18px;
640                left: 4px;
641                bottom: 4px;
642                background-color: white;
643                transition: 0.4s;
644                border-radius: 50%;
645            }
646
647            input:checked + .veckio-slider {
648                background-color: #00ff88;
649            }
650
651            input:checked + .veckio-slider:before {
652                transform: translateX(24px);
653            }
654
655            .veckio-info {
656                text-align: center;
657                margin-top: 15px;
658                padding-top: 15px;
659                border-top: 1px solid rgba(255, 255, 255, 0.1);
660            }
661
662            .veckio-info small {
663                color: #888;
664                font-size: 12px;
665            }
666            
667            #player-count {
668                color: #00ff88;
669                font-weight: bold;
670            }
671        `;
672        document.head.appendChild(style);
673    }
674
675    // Setup keyboard shortcuts
676    function setupKeyboardShortcuts() {
677        document.addEventListener('keydown', (e) => {
678            // F2 - Toggle panel
679            if (e.key === 'F2') {
680                e.preventDefault();
681                togglePanel();
682            }
683            
684            // E - Toggle ESP
685            if (e.key === 'e' || e.key === 'E') {
686                // Don't toggle if user is typing in an input field
687                if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
688                    return;
689                }
690                
691                e.preventDefault();
692                features.esp = !features.esp;
693                saveSettings();
694                
695                const espToggle = document.getElementById('esp-toggle');
696                if (espToggle) {
697                    espToggle.checked = features.esp;
698                }
699                
700                console.log('[Veck.io Optimizer] ESP toggled:', features.esp);
701                
702                if (features.esp) {
703                    enableESP();
704                } else {
705                    disableESP();
706                }
707            }
708            
709            // F - Toggle Aimbot
710            if (e.key === 'f' || e.key === 'F') {
711                // Don't toggle if user is typing in an input field
712                if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
713                    return;
714                }
715                
716                e.preventDefault();
717                features.aimbot = !features.aimbot;
718                saveSettings();
719                
720                const aimbotToggle = document.getElementById('aimbot-toggle');
721                if (aimbotToggle) {
722                    aimbotToggle.checked = features.aimbot;
723                }
724                
725                console.log('[Veck.io Optimizer] Aimbot toggled:', features.aimbot);
726                
727                if (features.aimbot) {
728                    enableAimbot();
729                } else {
730                    disableAimbot();
731                }
732            }
733        });
734        
735        console.log('[Veck.io Optimizer] Keyboard shortcuts enabled: F2=Panel, E=ESP, F=Aimbot');
736    }
737
738    // Initialize extension AFTER page loads
739    async function init() {
740        console.log('[Veck.io Optimizer] Waiting for page to fully load...');
741        
742        // Wait for window to fully load
743        if (document.readyState === 'complete') {
744            await initAfterLoad();
745        } else {
746            window.addEventListener('load', async () => {
747                await initAfterLoad();
748            });
749        }
750    }
751
752    async function initAfterLoad() {
753        console.log('[Veck.io Optimizer] Page loaded, initializing extension...');
754        
755        // Wait a bit more to ensure game is ready
756        await new Promise(resolve => setTimeout(resolve, 2000));
757        
758        // Hook WebGL
759        let hookAttempts = 0;
760        const maxAttempts = 10;
761        
762        const tryHook = () => {
763            hookAttempts++;
764            const success = hookWebGL();
765            
766            if (!success && hookAttempts < maxAttempts) {
767                console.log(`[Veck.io Optimizer] Retry hooking WebGL (${hookAttempts}/${maxAttempts})...`);
768                setTimeout(tryHook, 1000);
769            } else if (success) {
770                console.log('[Veck.io Optimizer] WebGL hooked successfully');
771                initUI();
772            } else {
773                console.error('[Veck.io Optimizer] Failed to hook WebGL after max attempts');
774                initUI(); // Still initialize UI
775            }
776        };
777        
778        tryHook();
779    }
780
781    async function initUI() {
782        // Load settings
783        await loadSettings();
784
785        // Add styles
786        addStyles();
787
788        // Create panel
789        createPanel();
790
791        // Setup keyboard shortcuts
792        setupKeyboardShortcuts();
793
794        // Apply enabled features
795        if (features.aimbot) enableAimbot();
796        if (features.esp) enableESP();
797
798        console.log('[Veck.io Optimizer] Initialization complete!');
799        console.log('[Veck.io Optimizer] Press F2 to open panel');
800        console.log('[Veck.io Optimizer] Press E to toggle ESP');
801        console.log('[Veck.io Optimizer] Press F to toggle Aimbot');
802    }
803
804    // Start the extension
805    init();
806})();
Gameplay Optimizer for Veck.io | Robomonkey