YouNow Plinko Auto-Win

Makes the ball in the Plinko mini-game always go the best way possible

Size

8.6 KB

Version

1.1.3

Created

Nov 27, 2025

Updated

16 days ago

1// ==UserScript==
2// @name		YouNow Plinko Auto-Win
3// @description		Makes the ball in the Plinko mini-game always go the best way possible
4// @version		1.1.3
5// @match		https://*.younow.com/*
6// @icon		https://www.younow.com/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    console.log('YouNow Plinko Auto-Win extension loaded');
12
13    // Randomly choose left or right edge as target (both are optimal)
14    const targetSide = Math.random() < 0.5 ? 'left' : 'right';
15    console.log(`Target side selected: ${targetSide}`);
16
17    let hooksInstalled = false;
18    let canvasHooked = false;
19
20    // Install hooks immediately to catch early game initialization
21    function installHooks() {
22        if (hooksInstalled) return;
23        hooksInstalled = true;
24
25        console.log('Installing canvas and physics hooks...');
26
27        // Hook into HTMLCanvasElement.prototype.getContext BEFORE the game loads
28        const originalGetContext = HTMLCanvasElement.prototype.getContext;
29        
30        HTMLCanvasElement.prototype.getContext = function(type, ...args) {
31            const context = originalGetContext.call(this, type, ...args);
32            
33            // Only hook into the Plinko game canvas
34            if (type === '2d' && (this.id === 'defaultCanvas0' || this.className.includes('p5Canvas'))) {
35                if (!canvasHooked) {
36                    console.log('Plinko canvas context intercepted!');
37                    hookCanvasContext(context, this);
38                    canvasHooked = true;
39                }
40            }
41            
42            return context;
43        };
44
45        // Hook into Matter.js if it exists or will exist
46        hookMatterJS();
47        
48        // Keep checking for Matter.js in case it loads later
49        const checkInterval = setInterval(() => {
50            if (typeof window.Matter !== 'undefined') {
51                console.log('Matter.js detected, installing physics hooks');
52                hookMatterJS();
53                clearInterval(checkInterval);
54            }
55        }, 500);
56
57        setTimeout(() => clearInterval(checkInterval), 15000);
58    }
59
60    function hookCanvasContext(context, canvas) {
61        const originalArc = context.arc;
62        const originalFill = context.fill;
63        const originalStroke = context.stroke;
64        let lastBallY = 0;
65        let ballDetected = false;
66        
67        // Hook arc (used to draw circles)
68        context.arc = function(x, y, radius, startAngle, endAngle, anticlockwise) {
69            // Detect ball (circle with radius between 5-20 pixels)
70            if (radius > 5 && radius < 20 && y > lastBallY) {
71                ballDetected = true;
72                // Calculate target position based on selected side
73                const edgeOffset = 25;
74                const targetX = targetSide === 'left' ? edgeOffset : canvas.width - edgeOffset;
75                
76                // Apply strong drift towards target
77                const drift = (targetX - x) * 0.2;
78                x = x + drift;
79                
80                console.log(`Ball guided to ${targetSide}: x=${x.toFixed(1)}, y=${y.toFixed(1)}`);
81                lastBallY = y;
82            }
83            
84            return originalArc.call(this, x, y, radius, startAngle, endAngle, anticlockwise);
85        };
86
87        // Also hook fill and stroke to detect drawing operations
88        context.fill = function(...args) {
89            if (ballDetected) {
90                console.log('Ball fill detected');
91                ballDetected = false;
92            }
93            return originalFill.call(this, ...args);
94        };
95
96        context.stroke = function(...args) {
97            if (ballDetected) {
98                console.log('Ball stroke detected');
99                ballDetected = false;
100            }
101            return originalStroke.call(this, ...args);
102        };
103    }
104
105    function hookMatterJS() {
106        if (typeof window.Matter === 'undefined' || !window.Matter.Body) return;
107
108        const Matter = window.Matter;
109        console.log('Hooking Matter.js physics engine');
110        
111        // Hook setVelocity
112        const originalSetVelocity = Matter.Body.setVelocity;
113        Matter.Body.setVelocity = function(body, velocity) {
114            if (body.label === 'ball' || body.circleRadius || body.isCircle) {
115                const canvas = document.getElementById('defaultCanvas0');
116                if (canvas && body.position) {
117                    const edgeOffset = 25;
118                    const targetX = targetSide === 'left' ? edgeOffset : canvas.width - edgeOffset;
119                    const currentX = body.position.x;
120                    const distance = Math.abs(currentX - targetX);
121                    
122                    if (distance > 5) {
123                        const direction = currentX < targetX ? 1 : -1;
124                        velocity.x = velocity.x + (direction * 1.2);
125                        console.log(`Matter.js velocity adjusted: ${velocity.x.toFixed(2)} towards ${targetSide}`);
126                    }
127                }
128            }
129            
130            return originalSetVelocity.call(this, body, velocity);
131        };
132
133        // Hook applyForce
134        const originalApplyForce = Matter.Body.applyForce;
135        Matter.Body.applyForce = function(body, position, force) {
136            if (body.label === 'ball' || body.circleRadius || body.isCircle) {
137                const canvas = document.getElementById('defaultCanvas0');
138                if (canvas && body.position) {
139                    const edgeOffset = 25;
140                    const targetX = targetSide === 'left' ? edgeOffset : canvas.width - edgeOffset;
141                    const currentX = body.position.x;
142                    const distance = Math.abs(currentX - targetX);
143                    
144                    if (distance > 5) {
145                        const direction = currentX < targetX ? 1 : -1;
146                        force.x = force.x + (direction * 0.0005);
147                    }
148                }
149            }
150            
151            return originalApplyForce.call(this, body, position, force);
152        };
153
154        // Hook setPosition to force ball to edge
155        const originalSetPosition = Matter.Body.setPosition;
156        Matter.Body.setPosition = function(body, position) {
157            if (body.label === 'ball' || body.circleRadius || body.isCircle) {
158                const canvas = document.getElementById('defaultCanvas0');
159                if (canvas) {
160                    const edgeOffset = 25;
161                    const targetX = targetSide === 'left' ? edgeOffset : canvas.width - edgeOffset;
162                    const distance = Math.abs(position.x - targetX);
163                    
164                    if (distance > 5) {
165                        const drift = (targetX - position.x) * 0.1;
166                        position.x = position.x + drift;
167                        console.log(`Matter.js position adjusted: ${position.x.toFixed(2)} towards ${targetSide}`);
168                    }
169                }
170            }
171            
172            return originalSetPosition.call(this, body, position);
173        };
174    }
175
176    // Try to hook existing canvas if it already exists
177    function hookExistingCanvas() {
178        const canvas = document.getElementById('defaultCanvas0');
179        if (canvas && !canvasHooked) {
180            console.log('Found existing canvas, attempting to hook...');
181            // Force a new context retrieval to trigger our hook
182            try {
183                const ctx = canvas.getContext('2d');
184                if (ctx && !canvasHooked) {
185                    hookCanvasContext(ctx, canvas);
186                    canvasHooked = true;
187                    console.log('Successfully hooked existing canvas context');
188                }
189            } catch (e) {
190                console.error('Failed to hook existing canvas:', e);
191            }
192        }
193    }
194
195    // Install hooks immediately
196    installHooks();
197
198    // Also watch for game container to appear
199    const observer = new MutationObserver(() => {
200        const gameContainer = document.getElementById('plinko-game-container');
201        const canvas = document.getElementById('defaultCanvas0');
202        
203        if (gameContainer || canvas) {
204            console.log('Plinko game detected in DOM!');
205            installHooks();
206            hookExistingCanvas();
207        }
208    });
209
210    if (document.body) {
211        observer.observe(document.body, {
212            childList: true,
213            subtree: true
214        });
215    }
216
217    // Try to hook existing canvas immediately
218    setTimeout(() => hookExistingCanvas(), 100);
219    setTimeout(() => hookExistingCanvas(), 500);
220    setTimeout(() => hookExistingCanvas(), 1000);
221
222    console.log('YouNow Plinko Auto-Win extension initialized and ready');
223})();
YouNow Plinko Auto-Win | Robomonkey