Last active 1726118709

Revision a8ffb3c25c102824abdffd384eb237a70a2c2e60

blum.js Raw
1// ==UserScript==
2// @name Blum Autoclicker
3// @version 1.0
4// @namespace Nobler's
5// @author https://twitter.com/cryptonobler
6// @match https://telegram.blum.codes/*
7// @grant none
8// @icon https://img.bitgetimg.com/multiLang/web/6a914e6e4aa70f6fd2bdf790f0f8401f.png
9// @downloadURL https://twitter.com/cryptonobler
10// @updateURL https://twitter.com/cryptonobler
11// @homepage https://twitter.com/cryptonobler
12// ==/UserScript==
13
14let GAME_SETTINGS = {
15 minBombHits: Math.floor(Math.random() * 2),
16 minIceHits: Math.floor(Math.random() * 2) + 2,
17 flowerSkipPercentage: Math.floor(Math.random() * 11) + 15,
18 minDelayMs: 1500,
19 maxDelayMs: 4500,
20 autoClickPlay: false,
21};
22let isGamePaused = false;
23try {
24 let gameStats = {
25 score: 0,
26 bombHits: 0,
27 iceHits: 0,
28 flowersSkipped: 0,
29 isGameOver: false,
30 };
31 const originalPush = Array.prototype.push;
32 Array.prototype.push = function (...items) {
33 if (!isGamePaused) {
34 items.forEach((item) => handleGameElement(item));
35 }
36 return originalPush.apply(this, items);
37 };
38 function handleGameElement(element) {
39 if (!element || !element.item) return;
40 const { type } = element.item;
41 switch (type) {
42 case "CLOVER":
43 processFlower(element);
44 break;
45 case "BOMB":
46 processBomb(element);
47 break;
48 case "FREEZE":
49 processIce(element);
50 break;
51 }
52 }
53 function processFlower(element) {
54 const shouldSkip = Math.random() < GAME_SETTINGS.flowerSkipPercentage / 100;
55 if (shouldSkip) {
56 gameStats.flowersSkipped++;
57 } else {
58 gameStats.score++;
59 clickElement(element);
60 }
61 }
62 function processBomb(element) {
63 if (gameStats.bombHits < GAME_SETTINGS.minBombHits) {
64 gameStats.score = 0;
65 clickElement(element);
66 gameStats.bombHits++;
67 }
68 }
69 function processIce(element) {
70 if (gameStats.iceHits < GAME_SETTINGS.minIceHits) {
71 clickElement(element);
72 gameStats.iceHits++;
73 }
74 }
75 function clickElement(element) {
76 element.onClick(element);
77 element.isExplosion = true;
78 element.addedAt = performance.now();
79 }
80 function checkGameCompletion() {
81 const rewardElement = document.querySelector(
82 "#app > div > div > div.content > div.reward"
83 );
84 if (rewardElement && !gameStats.isGameOver) {
85 gameStats.isGameOver = true;
86 resetGameStats();
87 }
88 }
89 function resetGameStats() {
90 gameStats = {
91 score: 0,
92 bombHits: 0,
93 iceHits: 0,
94 flowersSkipped: 0,
95 isGameOver: false,
96 };
97 }
98 function getNewGameDelay() {
99 return Math.floor(
100 Math.random() *
101 (GAME_SETTINGS.maxDelayMs - GAME_SETTINGS.minDelayMs + 1) +
102 GAME_SETTINGS.minDelayMs
103 );
104 }
105 function checkAndClickPlayButton() {
106 const playButtons = document.querySelectorAll(
107 'button.kit-button.is-large.is-primary, a.play-btn[href="/game"], button.kit-button.is-large.is-primary'
108 );
109 playButtons.forEach((button) => {
110 if (
111 !isGamePaused &&
112 GAME_SETTINGS.autoClickPlay &&
113 (/Play/.test(button.textContent) || /Continue/.test(button.textContent))
114 ) {
115 setTimeout(() => {
116 button.click();
117 gameStats.isGameOver = false;
118 }, getNewGameDelay());
119 }
120 });
121 }
122 function continuousPlayButtonCheck() {
123 checkAndClickPlayButton();
124 setTimeout(continuousPlayButtonCheck, 1000);
125 }
126 const observer = new MutationObserver((mutations) => {
127 for (const mutation of mutations) {
128 if (mutation.type === "childList") {
129 checkGameCompletion();
130 }
131 }
132 });
133 const appElement = document.querySelector("#app");
134 if (appElement) {
135 observer.observe(appElement, { childList: true, subtree: true });
136 }
137 continuousPlayButtonCheck();
138 const settingsMenu = document.createElement("div");
139 settingsMenu.className = "settings-menu";
140 settingsMenu.style.display = "none";
141 const menuTitle = document.createElement("h3");
142 menuTitle.className = "settings-title";
143 menuTitle.textContent = "Blum Autoclicker";
144 const closeButton = document.createElement("button");
145 closeButton.className = "settings-close-button";
146 closeButton.textContent = "×";
147 closeButton.onclick = () => {
148 settingsMenu.style.display = "none";
149 };
150 menuTitle.appendChild(closeButton);
151 settingsMenu.appendChild(menuTitle);
152 function updateSettingsMenu() {
153 document.getElementById("flowerSkipPercentage").value =
154 GAME_SETTINGS.flowerSkipPercentage;
155 document.getElementById("flowerSkipPercentageDisplay").textContent =
156 GAME_SETTINGS.flowerSkipPercentage;
157 document.getElementById("minIceHits").value = GAME_SETTINGS.minIceHits;
158 document.getElementById("minIceHitsDisplay").textContent =
159 GAME_SETTINGS.minIceHits;
160 document.getElementById("minBombHits").value = GAME_SETTINGS.minBombHits;
161 document.getElementById("minBombHitsDisplay").textContent =
162 GAME_SETTINGS.minBombHits;
163 document.getElementById("minDelayMs").value = GAME_SETTINGS.minDelayMs;
164 document.getElementById("minDelayMsDisplay").textContent =
165 GAME_SETTINGS.minDelayMs;
166 document.getElementById("maxDelayMs").value = GAME_SETTINGS.maxDelayMs;
167 document.getElementById("maxDelayMsDisplay").textContent =
168 GAME_SETTINGS.maxDelayMs;
169 document.getElementById("autoClickPlay").checked =
170 GAME_SETTINGS.autoClickPlay;
171 }
172 settingsMenu.appendChild(
173 createSettingElement(
174 "Flower Skip (%)",
175 "flowerSkipPercentage",
176 "range",
177 0,
178 100,
179 1,
180 "Percentage probability of missing a flower"
181 )
182 );
183 settingsMenu.appendChild(
184 createSettingElement(
185 "Min Freeze Hits",
186 "minIceHits",
187 "range",
188 1,
189 10,
190 1,
191 "Minimum number of clicks per freeze"
192 )
193 );
194 settingsMenu.appendChild(
195 createSettingElement(
196 "Min Bomb Hits",
197 "minBombHits",
198 "range",
199 0,
200 10,
201 1,
202 "Minimum number of clicks per bomb"
203 )
204 );
205 settingsMenu.appendChild(
206 createSettingElement(
207 "Min Delay (ms)",
208 "minDelayMs",
209 "range",
210 10,
211 10000,
212 10,
213 "Minimum delay between clicks"
214 )
215 );
216 settingsMenu.appendChild(
217 createSettingElement(
218 "Max Delay (ms)",
219 "maxDelayMs",
220 "range",
221 10,
222 10000,
223 10,
224 "Maximum delay between clicks"
225 )
226 );
227 settingsMenu.appendChild(
228 createSettingElement(
229 "Auto Click Play",
230 "autoClickPlay",
231 "checkbox",
232 null,
233 null,
234 null,
235 "Automatically start the next game"
236 )
237 );
238 const pauseResumeButton = document.createElement("button");
239 pauseResumeButton.textContent = "Pause";
240 pauseResumeButton.className = "pause-resume-btn";
241 pauseResumeButton.onclick = toggleGamePause;
242 settingsMenu.appendChild(pauseResumeButton);
243 const socialButtons = document.createElement("div");
244 socialButtons.className = "social-buttons";
245 const twitterButton = document.createElement("a");
246 twitterButton.href = "https://twitter.com/CryptoNobler";
247 twitterButton.target = "_blank";
248 twitterButton.className = "social-button";
249 twitterButton.innerHTML =
250 '<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMjQgMjQiPgogIDxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0iTTE4LjkwMSAxLjE1M2gzLjY4bC04LjA0IDkuMTlMMjQgMjIuODQ2aC03LjQwNmwtNS44LTcuNTg0bC02LjYzOCA3LjU4NEguNDc0bDguNi05LjgzTDAgMS4xNTRoNy41OTRsNS4yNDMgNi45MzJaTTE3LjYxIDIwLjY0NGgyLjAzOUw2LjQ4NiAzLjI0SDQuMjk4WiIvPgo8L3N2Zz4=">Twitter';
251 socialButtons.appendChild(twitterButton);
252 const telegramButton = document.createElement("a");
253 telegramButton.href = "https://t.me/shopalenka";
254 telegramButton.target = "_blank";
255 telegramButton.className = "social-button";
256 telegramButton.innerHTML =
257 '<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+CiAgPGRlZnM+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImxvZ29zVGVsZWdyYW0wIiB4MT0iNTAlIiB4Mj0iNTAlIiB5MT0iMCUiIHkyPSIxMDAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzJBQUJFRSIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMyMjlFRDkiLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgPC9kZWZzPgogIDxwYXRoIGZpbGw9InVybCgjbG9nb3NUZWxlZ3JhbTApIiBkPSJNMTI4IDBDOTQuMDYgMCA2MS40OCAxMy40OTQgMzcuNSAzNy40OUExMjguMDM4IDEyOC4wMzggMCAwIDAgMCAxMjhjMCAzMy45MzQgMTMuNSA2Ni41MTQgMzcuNSA5MC41MUM2MS40OCAyNDIuNTA2IDk0LjA2IDI1NiAxMjggMjU2czY2LjUyLTEzLjQ5NCA5MC41LTM3LjQ5YzI0LTIzLjk5NiAzNy41LTU2LjU3NiAzNy41LTkwLjUxYzAtMzMuOTM0LTEzLjUtNjYuNTE0LTM3LjUtOTAuNTFDMTk0LjUyIDEzLjQ5NCAxNjEuOTQgMCAxMjggMFoiLz4KICA8cGF0aCBmaWxsPSIjRkZGIiBkPSJNNTcuOTQgMTI2LjY0OGMzNy4zMi0xNi4yNTYgNjIuMi0yNi45NzQgNzQuNjQtMzIuMTUyYzM1LjU2LTE0Ljc4NiA0Mi45NC0xNy4zNTQgNDcuNzYtMTcuNDQxYzEuMDYtLjAxNyAzLjQyLjI0NSA0Ljk2IDEuNDljMS4yOCAxLjA1IDEuNjQgMi40NyAxLjgyIDMuNDY3Yy4xNi45OTYuMzggMy4yNjYuMiA1LjAzOGMtMS45MiAyMC4yNC0xMC4yNiA2OS4zNTYtMTQuNSA5Mi4wMjZjLTEuNzggOS41OTItNS4zMiAxMi44MDgtOC43NCAxMy4xMjJjLTcuNDQuNjg0LTEzLjA4LTQuOTEyLTIwLjI4LTkuNjNjLTExLjI2LTcuMzg2LTE3LjYyLTExLjk4Mi0yOC41Ni0xOS4xODhjLTEyLjY0LTguMzI4LTQuNDQtMTIuOTA2IDIuNzYtMjAuMzg2YzEuODgtMS45NTggMzQuNjQtMzEuNzQ4IDM1LjI2LTM0LjQ1Yy4wOC0uMzM4LjE2LTEuNTk4LS42LTIuMjYyYy0uNzQtLjY2Ni0xLjg0LS40MzgtMi42NC0uMjU4Yy0xLjE0LjI1Ni0xOS4xMiAxMi4xNTItNTQgMzUuNjg2Yy01LjEgMy41MDgtOS43MiA1LjIxOC0xMy44OCA1LjEyOGMtNC41Ni0uMDk4LTEzLjM2LTIuNTg0LTE5LjktNC43MDhjLTgtMi42MDYtMTQuMzgtMy45ODQtMTMuODItOC40MWMuMjgtMi4zMDQgMy40Ni00LjY2MiA5LjUyLTcuMDcyWiIvPgo8L3N2Zz4=">Telegram Channel';
258 socialButtons.appendChild(telegramButton);
259 settingsMenu.appendChild(socialButtons);
260 document.body.appendChild(settingsMenu);
261 const settingsButton = document.createElement("button");
262 settingsButton.className = "settings-button";
263 settingsButton.textContent = "⚙️";
264 settingsButton.onclick = () => {
265 settingsMenu.style.display =
266 settingsMenu.style.display === "block" ? "none" : "block";
267 };
268 document.body.appendChild(settingsButton);
269 const style = document.createElement("style");
270 style.textContent = ` .settings-menu { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(40, 44, 52, 0.95); border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); color: #abb2bf; font-family: 'Arial', sans-serif; z-index: 10000; padding: 20px; width: 300px; } .settings-title { color: #61afef; font-size: 18px; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; justify-content: space-between; } .settings-close-button { background: none; border: none; color: #e06c75; font-size: 20px; cursor: pointer; padding: 0; } .setting-item { margin-bottom: 12px; } .setting-label { display: flex; align-items: center; margin-bottom: 4px; } .setting-label-text { color: #e5c07b; margin-right: 5px; } .help-icon { cursor: help; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; background-color: #61afef; color: #282c34; font-size: 10px; font-weight: bold; } .setting-input { display: flex; align-items: center; } .setting-slider { flex-grow: 1; margin-right: 8px; } .setting-value { min-width: 30px; text-align: right; font-size: 11px; } .tooltip { position: relative; } .tooltip .tooltiptext { visibility: hidden; width: 200px; background-color: #4b5263; color: #fff; text-align: center; border-radius: 6px; padding: 5px; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -100px; opacity: 0; transition: opacity 0.3s; font-size: 11px; box-shadow: 0 2px 4px rgba(0,0,0,0.2); } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; } .pause-resume-btn { display: block; width: calc(100% - 10px); padding: 8px; margin: 15px 5px; background-color: #98c379; color: #282c34; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 14px; transition: background-color 0.3s; } .pause-resume-btn:hover { background-color: #7cb668; } .social-buttons { margin-top: 15px; display: flex; justify-content: space-between; white-space: nowrap; } .social-button { display: inline-flex; align-items: center; padding: 5px 8px; border-radius: 4px; background-color: #282c34; color: #abb2bf; text-decoration: none; font-size: 12px; transition: background-color 0.3s; } .social-button:hover { background-color: #4b5263; } .social-button img { width: 16px; height: 16px; margin-right: 5px; } .settings-button { position: fixed; bottom: 20px; right: 20px; background-color: rgba(36, 146, 255, 0.8); color: #fff; border: none; border-radius: 50%; width: 40px; height: 40px; font-size: 18px; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); z-index: 9999; } `;
271 document.head.appendChild(style);
272 function createSettingElement(label, id, type, min, max, step, tooltipText) {
273 const container = document.createElement("div");
274 container.className = "setting-item";
275 const labelContainer = document.createElement("div");
276 labelContainer.className = "setting-label";
277 const labelElement = document.createElement("span");
278 labelElement.className = "setting-label-text";
279 labelElement.textContent = label;
280 const helpIcon = document.createElement("span");
281 helpIcon.textContent = "?";
282 helpIcon.className = "help-icon tooltip";
283 const tooltipSpan = document.createElement("span");
284 tooltipSpan.className = "tooltiptext";
285 tooltipSpan.innerHTML = tooltipText;
286 helpIcon.appendChild(tooltipSpan);
287 labelContainer.appendChild(labelElement);
288 labelContainer.appendChild(helpIcon);
289 const inputContainer = document.createElement("div");
290 inputContainer.className = "setting-input";
291 setInterval(() => {
292 const claimButton = document.querySelector(
293 "button.kit-button.is-large.is-drop.is-fill.button.is-done"
294 );
295 const startFarmingButton = document.querySelector(
296 "button.kit-button.is-large.is-primary.is-fill.button"
297 );
298 if (claimButton) {
299 claimButton.click();
300 } else if (startFarmingButton) {
301 startFarmingButton.click();
302 }
303 }, Math.floor(Math.random() * 5000) + 5000);
304 let input;
305 if (type === "checkbox") {
306 input = document.createElement("input");
307 input.type = "checkbox";
308 input.id = id;
309 input.checked = GAME_SETTINGS[id];
310 input.addEventListener("change", (e) => {
311 GAME_SETTINGS[id] = e.target.checked;
312 saveSettings();
313 });
314 inputContainer.appendChild(input);
315 } else {
316 input = document.createElement("input");
317 input.type = type;
318 input.id = id;
319 input.min = min;
320 input.max = max;
321 input.step = step;
322 input.value = GAME_SETTINGS[id];
323 input.className = "setting-slider";
324 const valueDisplay = document.createElement("span");
325 valueDisplay.id = `${id}Display`;
326 valueDisplay.textContent = GAME_SETTINGS[id];
327 valueDisplay.className = "setting-value";
328 input.addEventListener("input", (e) => {
329 GAME_SETTINGS[id] = parseFloat(e.target.value);
330 valueDisplay.textContent = e.target.value;
331 saveSettings();
332 });
333 inputContainer.appendChild(input);
334 inputContainer.appendChild(valueDisplay);
335 }
336 container.appendChild(labelContainer);
337 container.appendChild(inputContainer);
338 return container;
339 }
340 function saveSettings() {
341 localStorage.setItem(
342 "BlumAutoclickerSettings",
343 JSON.stringify(GAME_SETTINGS)
344 );
345 }
346 function loadSettings() {
347 const savedSettings = localStorage.getItem("BlumAutoclickerSettings");
348 if (savedSettings) {
349 const parsedSettings = JSON.parse(savedSettings);
350 GAME_SETTINGS = { ...GAME_SETTINGS, ...parsedSettings };
351 }
352 }
353 loadSettings();
354 updateSettingsMenu();
355 function toggleGamePause() {
356 isGamePaused = !isGamePaused;
357 pauseResumeButton.textContent = isGamePaused ? "Resume" : "Pause";
358 pauseResumeButton.style.backgroundColor = isGamePaused
359 ? "#e5c07b"
360 : "#98c379";
361 }
362} catch (e) {
363 console.error("Blum Autoclicker error:", e);
364}
365