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

about 1 month 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