Last active 1726118709

cryptonobler revised this gist 1726118708. Go to revision

1 file changed, 364 insertions

blum.js(file created)

@@ -0,0 +1,364 @@
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 +
14 + let 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 + };
22 + let isGamePaused = false;
23 + try {
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 + }
Newer Older