Automatically claims rain bonuses in Hollywoodbets Aviator game
Size
12.2 KB
Version
1.1.1
Created
Nov 22, 2025
Updated
20 days ago
1// ==UserScript==
2// @name Aviator Rain Auto Claimer
3// @description Automatically claims rain bonuses in Hollywoodbets Aviator game
4// @version 1.1.1
5// @match https://*.hollywoodbets.net/*
6// @icon https://www.hollywoodbets.net/favicon.ico
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log("✅ Aviator Rain Auto Claimer loaded");
12
13 let active = true; // Auto-enabled by default
14 let loop;
15 let lastClaimTime = 0;
16 const CLAIM_DELAY = 1000; // 1 second delay between claims
17 const CHECK_INTERVAL = 400; // Check every 400ms for fast detection
18
19 // --- Add Styles ---
20 const style = document.createElement('style');
21 style.textContent = `
22 #aviatorAutoBtn {
23 position: fixed;
24 bottom: 20px;
25 right: 20px;
26 z-index: 999999;
27 width: 70px;
28 height: 70px;
29 border-radius: 50%;
30 background-color: #009933;
31 color: white;
32 font-weight: bold;
33 font-size: 12px;
34 text-align: center;
35 line-height: 70px;
36 cursor: pointer;
37 box-shadow: 0 4px 10px rgba(0,0,0,0.3);
38 user-select: none;
39 transition: all 0.3s ease;
40 }
41 #aviatorAutoBtn:hover {
42 transform: scale(1.1);
43 }
44 #aviatorAutoBtn.inactive {
45 background-color: #b30000;
46 }
47 @keyframes slideIn {
48 from {
49 transform: translateX(400px);
50 opacity: 0;
51 }
52 to {
53 transform: translateX(0);
54 opacity: 1;
55 }
56 }
57 @keyframes slideOut {
58 from {
59 transform: translateX(0);
60 opacity: 1;
61 }
62 to {
63 transform: translateX(400px);
64 opacity: 0;
65 }
66 }
67 `;
68 document.head.appendChild(style);
69
70 // --- Create Floating Toggle Button ---
71 const btn = document.createElement("div");
72 btn.id = "aviatorAutoBtn";
73 btn.innerText = "Auto ON";
74 document.body.appendChild(btn);
75
76 // --- Function: Show Notification ---
77 function showNotification(message) {
78 const notification = document.createElement('div');
79 notification.textContent = message;
80 notification.style.cssText = `
81 position: fixed;
82 top: 20px;
83 right: 20px;
84 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
85 color: white;
86 padding: 15px 25px;
87 border-radius: 10px;
88 font-size: 16px;
89 font-weight: bold;
90 z-index: 999998;
91 box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
92 animation: slideIn 0.3s ease-out;
93 `;
94
95 document.body.appendChild(notification);
96
97 // Remove notification after 3 seconds
98 setTimeout(() => {
99 notification.style.animation = 'slideOut 0.3s ease-out';
100 setTimeout(() => notification.remove(), 300);
101 }, 3000);
102 }
103
104 // --- Function: Auto-Click Claim Button ---
105 function autoClickClaim() {
106 if (!active) return;
107
108 const now = Date.now();
109
110 // Enforce delay between claims
111 if (now - lastClaimTime < CLAIM_DELAY) {
112 return;
113 }
114
115 // Comprehensive selectors for rain claim buttons
116 const claimSelectors = [
117 // Angular rain components
118 'app-chat-message-claim button',
119 'app-chat-message-claim',
120 'app-chat-rain-message button',
121 'app-chat-rain-message',
122 'app-rain-claim button',
123 'app-rain-claim',
124
125 // Rain class selectors
126 '[class*="rain"] button',
127 '[class*="rain-claim"]',
128 '[class*="rain-message"]',
129 '[class*="chat-rain"]',
130 '.rain button',
131 '.rain-wrapper button',
132
133 // Claim class selectors
134 '.claim-button',
135 'button[class*="claim"]',
136 '[class*="claim-btn"]',
137
138 // ID selectors
139 '[id*="rain"] button',
140 '[id*="claim"] button',
141
142 // Hollywoodbets specific
143 '[data-testid*="claim"]',
144 'button[aria-label*="claim" i]'
145 ];
146
147 for (const selector of claimSelectors) {
148 try {
149 const elements = document.querySelectorAll(selector);
150
151 for (const element of elements) {
152 // Check if element is visible
153 if (element.offsetParent === null) continue;
154
155 // Get text content
156 const text = (element.innerText || element.textContent || '').toUpperCase();
157 const className = (element.className || '').toLowerCase();
158 const parentClass = (element.parentElement?.className || '').toLowerCase();
159
160 // Check for CLAIM NOW, CLAIM, or rain-related elements
161 const hasClaimNow = text.includes('CLAIM NOW') || text.includes('CLAIM');
162 const hasRainClass = className.includes('rain') || parentClass.includes('rain');
163 const hasClaimClass = className.includes('claim') || parentClass.includes('claim');
164
165 if (hasClaimNow || (hasRainClass && element.tagName === 'BUTTON') || hasClaimClass) {
166 element.click();
167 console.log("🎯 Clicked RAIN/CLAIM button:", element, "Text:", text);
168 showNotification('Rain Claimed! 🎉');
169 lastClaimTime = now;
170 return; // Exit after first successful claim
171 }
172 }
173 } catch (err) {
174 console.log("Error with selector:", selector, err);
175 }
176 }
177
178 // Fallback: Look for any button with "CLAIM" text in rain contexts
179 try {
180 const allButtons = document.querySelectorAll('button, div[role="button"], span[role="button"]');
181 for (const button of allButtons) {
182 if (button.offsetParent === null) continue;
183
184 const text = (button.innerText || button.textContent || '').toUpperCase();
185 const hasClaimText = text.includes('CLAIM NOW') || text.includes('CLAIM');
186
187 // Check if button or any parent has 'rain' in class
188 let hasRainParent = false;
189 let parent = button.parentElement;
190 let depth = 0;
191 while (parent && depth < 5) {
192 const pClass = (parent.className || '').toLowerCase();
193 if (pClass.includes('rain') || pClass.includes('claim')) {
194 hasRainParent = true;
195 break;
196 }
197 parent = parent.parentElement;
198 depth++;
199 }
200
201 if (hasClaimText && hasRainParent) {
202 button.click();
203 console.log("🎯 Clicked CLAIM button (fallback):", button, "Text:", text);
204 showNotification('Rain Claimed! 🎉');
205 lastClaimTime = now;
206 return;
207 }
208 }
209 } catch (err) {
210 console.log("Fallback error:", err);
211 }
212 }
213
214 // --- Function: Auto Scroll Chats ---
215 function autoScrollChats() {
216 if (!active) return;
217
218 const chats = document.querySelectorAll(`
219 .chat, .chat-container, .chat-room, .chat-message-rain-wrapper,
220 [class*='chat'], [class*='messages'], [id*='chat'], [id*='messages']
221 `);
222 chats.forEach(el => {
223 if (el.scrollHeight > el.clientHeight && getComputedStyle(el).overflowY !== "visible") {
224 el.scrollTop = el.scrollHeight;
225 }
226 });
227 }
228
229 // --- Function: Ensure Chat is Open ---
230 function ensureChatIsOpen() {
231 if (!active) return;
232
233 const chatButton = document.querySelector('[data-testid="chat-button"]');
234 const chatPanel = document.querySelector('[data-testid="layout-right-sidebar"]');
235
236 // Check if chat panel exists and has content (meaning it's open)
237 const isChatOpen = chatPanel && chatPanel.offsetParent !== null;
238
239 if (chatButton && !isChatOpen) {
240 console.log('Aviator Rain Auto Claimer: Opening chat panel...');
241 chatButton.click();
242 }
243 }
244
245 // --- Combined Action ---
246 function performActions() {
247 autoClickClaim();
248 autoScrollChats();
249 }
250
251 // --- Toggle ON/OFF ---
252 btn.addEventListener("click", () => {
253 active = !active;
254 if (active) {
255 btn.classList.remove("inactive");
256 btn.innerText = "Auto ON";
257 console.log("✅ Auto Claim + Scroll ENABLED");
258 showNotification('Auto Claimer Active! 🚀');
259 loop = setInterval(performActions, CHECK_INTERVAL);
260 } else {
261 btn.classList.add("inactive");
262 btn.innerText = "Auto OFF";
263 console.log("⛔ Auto Claim + Scroll DISABLED");
264 showNotification('Auto Claimer Disabled');
265 clearInterval(loop);
266 }
267 });
268
269 // --- Use MutationObserver for instant detection ---
270 function setupMutationObserver() {
271 const observer = new MutationObserver((mutations) => {
272 if (!active) return;
273
274 for (const mutation of mutations) {
275 if (mutation.addedNodes.length > 0) {
276 // Check if any added node contains a claim button
277 mutation.addedNodes.forEach(node => {
278 if (node.nodeType === 1) { // Element node
279 const text = (node.innerText || node.textContent || '').toUpperCase();
280 const className = (node.className || '').toLowerCase();
281
282 // Check for rain/claim related elements
283 const hasClaimText = text.includes('CLAIM NOW') || text.includes('CLAIM');
284 const hasRainClass = className.includes('rain') || className.includes('claim');
285
286 if (hasClaimText || hasRainClass) {
287 console.log('Aviator Rain Auto Claimer: New claim element detected via MutationObserver!');
288 setTimeout(autoClickClaim, 300); // Small delay to ensure button is ready
289 }
290 }
291 });
292 }
293 }
294 });
295
296 // Observe the entire document for changes
297 observer.observe(document.body, {
298 childList: true,
299 subtree: true
300 });
301
302 console.log('Aviator Rain Auto Claimer: MutationObserver setup complete');
303 }
304
305 // --- Initialize the extension ---
306 function init() {
307 console.log('Aviator Rain Auto Claimer: Initializing...');
308
309 // Wait for page to load
310 if (document.readyState === 'loading') {
311 document.addEventListener('DOMContentLoaded', init);
312 return;
313 }
314
315 // Ensure we're on the Aviator page
316 if (!window.location.href.includes('aviator')) {
317 console.log('Aviator Rain Auto Claimer: Not on Aviator page, waiting...');
318 // Check URL changes
319 const urlCheckInterval = setInterval(() => {
320 if (window.location.href.includes('aviator')) {
321 clearInterval(urlCheckInterval);
322 init();
323 }
324 }, 3000);
325 return;
326 }
327
328 console.log('Aviator Rain Auto Claimer: ✅ Active on Aviator page');
329
330 // Ensure chat is open after a delay
331 setTimeout(ensureChatIsOpen, 3000);
332
333 // Setup MutationObserver for instant detection
334 setupMutationObserver();
335
336 // Start the auto-claim loop
337 loop = setInterval(performActions, CHECK_INTERVAL);
338
339 // Show startup notification
340 setTimeout(() => {
341 showNotification('Auto Claimer Active! 🚀');
342 }, 2000);
343 }
344
345 // Start the extension
346 init();
347
348 console.log("🚀 Aviator Rain Auto Claimer ready");
349})();