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.6

Created

Mar 26, 2026

Updated

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