+26
-1
@@ -5,8 +5,33 @@ 'use strict'; | ||
| chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { | ||
| // 1. Open final link safely in a new tab | ||
| if (message.action === "openNewTab" && message.url) { | ||
| chrome.tabs.create({ | ||
| url: message.url, | ||
| active: true // Set to false if you want tabs to open silently in the background | ||
| active: true | ||
| }, (tab) => { | ||
| if (chrome.runtime.lastError) { | ||
| console.error("[ZeroGate Background] Failed to open tab:", chrome.runtime.lastError.message); | ||
| sendResponse({ success: false, error: chrome.runtime.lastError.message }); | ||
| } else { | ||
| console.log("[ZeroGate Background] Opened tab ID:", tab.id); | ||
| sendResponse({ success: true, tabId: tab.id }); | ||
| } | ||
| }); | ||
| return true; // Keep message channel open for async response | ||
| } | ||
| // 2. Broadcast mod menu state changes (if toggled from popup) | ||
| if (message.modMenuDisabled !== undefined) { | ||
| chrome.storage.local.set({ modMenuDisabled: message.modMenuDisabled }, () => { | ||
| chrome.tabs.query({}, (tabs) => { | ||
| tabs.forEach((tab) => { | ||
| chrome.tabs.sendMessage(tab.id, { modMenuDisabled: message.modMenuDisabled }).catch(() => { | ||
| // Ignore tabs without main.js injected | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
| sendResponse({ success: true }); | ||
| return true; | ||
| } | ||
| }); |
+1
-1
| { | ||
| "manifest_version": 3, | ||
| "name": "ZeroGate", | ||
| "version": "2.8.0", | ||
| "version": "2.9.0", | ||
| "description": "Modular automation & link extraction toolkit with category-based control.", | ||
@@ -6,0 +6,0 @@ "permissions": [ |
+12
-29
@@ -167,3 +167,3 @@ <!DOCTYPE html> | ||
| .category-icon.pink { background: rgba(236,72,153,0.12); } | ||
| .category-icon.red { background: rgba(92, 4, 13, 0.72); } | ||
| .category-icon.red { background: rgba(92, 4, 13, 0.72); } | ||
@@ -226,3 +226,3 @@ .category-name { | ||
| .category.open .category-body { | ||
| max-height: 250px; | ||
| max-height: 300px; | ||
| padding: 0 18px 10px; | ||
@@ -357,3 +357,3 @@ } | ||
| </div> | ||
| <div class="category-count">2 modules</div> | ||
| <div class="category-count">3 modules</div> | ||
| </div> | ||
@@ -381,2 +381,9 @@ </div> | ||
| </div> | ||
| <div class="toggle-row"> | ||
| <span class="toggle-label">Mini-Game Overlay</span> | ||
| <label class="toggle"> | ||
| <input type="checkbox" id="toggleGame" checked> | ||
| <span class="toggle-track"></span> | ||
| </label> | ||
| </div> | ||
| <div class="note-box"> | ||
@@ -452,2 +459,3 @@ Have an issue or need an update? Get the solution here: <br> | ||
| </div> | ||
| <!-- Pwthor Category --> | ||
@@ -477,27 +485,2 @@ <div class="category" data-category="Pwthor"> | ||
| <!-- Placeholder: Future Categories --> | ||
| <!-- | ||
| <div class="category" data-category="example"> | ||
| <div class="category-header"> | ||
| <div class="category-left"> | ||
| <div class="category-icon blue">🔒</div> | ||
| <div> | ||
| <div class="category-name">Example Site</div> | ||
| <div class="category-count">3 modules</div> | ||
| </div> | ||
| </div> | ||
| <span class="category-chevron">▶</span> | ||
| </div> | ||
| <div class="category-body"> | ||
| <div class="toggle-row"> | ||
| <span class="toggle-label">Module One</span> | ||
| <label class="toggle"> | ||
| <input type="checkbox" data-key="example_module1" checked> | ||
| <span class="toggle-track"></span> | ||
| </label> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| --> | ||
| </div> | ||
@@ -515,2 +498,2 @@ | ||
| </body> | ||
| </html> | ||
| </html> |
+87
-58
@@ -6,2 +6,3 @@ document.addEventListener('DOMContentLoaded', () => { | ||
| const toggleCopy = document.getElementById('toggleCopy'); | ||
| const toggleGame = document.getElementById('toggleGame'); | ||
| const toggleAutomationSpark = document.getElementById('toggleAutomationSpark'); | ||
@@ -25,3 +26,2 @@ const toggleCopySpark = document.getElementById('toggleCopySpark'); | ||
| // Overall status is paused only if both are paused (or based on preference) | ||
| liveStatus.textContent = (off && offSpark) ? 'Paused' : 'Active'; | ||
@@ -42,12 +42,14 @@ liveStatus.className = 'live-badge ' + ((off && offSpark) ? 'paused' : 'active'); | ||
| // ââ Init toggles from storage ââ | ||
| chrome.storage.local.get(['modMenuDisabled', 'copyDisabled', 'modMenuDisabledSpark', 'copyDisabledSpark'], (result) => { | ||
| chrome.storage.local.get(['modMenuDisabled', 'copyDisabled', 'gameDisabled', 'modMenuDisabledSpark', 'copyDisabledSpark'], (result) => { | ||
| const modOff = result.modMenuDisabled === undefined ? false : result.modMenuDisabled; | ||
| const copyOff = result.copyDisabled === undefined ? false : result.copyDisabled; | ||
| const gameOff = result.gameDisabled === undefined ? false : result.gameDisabled; | ||
| const modOffSpark = result.modMenuDisabledSpark === undefined ? false : result.modMenuDisabledSpark; | ||
| const copyOffSpark = result.copyDisabledSpark === undefined ? false : result.copyDisabledSpark; | ||
| toggleAutomation.checked = !modOff; | ||
| toggleCopy.checked = !copyOff; | ||
| toggleAutomationSpark.checked = !modOffSpark; | ||
| toggleCopySpark.checked = !copyOffSpark; | ||
| if (toggleAutomation) toggleAutomation.checked = !modOff; | ||
| if (toggleCopy) toggleCopy.checked = !copyOff; | ||
| if (toggleGame) toggleGame.checked = !gameOff; | ||
| if (toggleAutomationSpark) toggleAutomationSpark.checked = !modOffSpark; | ||
| if (toggleCopySpark) toggleCopySpark.checked = !copyOffSpark; | ||
@@ -67,72 +69,99 @@ updateBadge(); | ||
| // ââ Toggle: Automation ââ | ||
| toggleAutomation.addEventListener('change', (e) => { | ||
| const modMenuDisabled = !e.target.checked; | ||
| chrome.storage.local.set({ modMenuDisabled }); | ||
| updateBadge(); | ||
| notifyTab({ modMenuDisabled }); | ||
| }); | ||
| if (toggleAutomation) { | ||
| toggleAutomation.addEventListener('change', (e) => { | ||
| const modMenuDisabled = !e.target.checked; | ||
| chrome.storage.local.set({ modMenuDisabled }); | ||
| updateBadge(); | ||
| notifyTab({ modMenuDisabled }); | ||
| }); | ||
| } | ||
| // ââ Toggle: Clipboard ââ | ||
| toggleCopy.addEventListener('change', (e) => { | ||
| const copyDisabled = !e.target.checked; | ||
| chrome.storage.local.set({ copyDisabled }); | ||
| notifyTab({ copyDisabled }); | ||
| }); | ||
| if (toggleCopy) { | ||
| toggleCopy.addEventListener('change', (e) => { | ||
| const copyDisabled = !e.target.checked; | ||
| chrome.storage.local.set({ copyDisabled }); | ||
| notifyTab({ copyDisabled }); | ||
| }); | ||
| } | ||
| // ââ Toggle: Mini-Game ââ | ||
| if (toggleGame) { | ||
| toggleGame.addEventListener('change', (e) => { | ||
| const gameDisabled = !e.target.checked; | ||
| chrome.storage.local.set({ gameDisabled }); | ||
| notifyTab({ gameDisabled }); | ||
| }); | ||
| } | ||
| // ââ Toggle: Automation Spark ââ | ||
| toggleAutomationSpark.addEventListener('change', (e) => { | ||
| const modMenuDisabledSpark = !e.target.checked; | ||
| chrome.storage.local.set({ modMenuDisabledSpark }); | ||
| updateBadge(); | ||
| notifyTab({ modMenuDisabledSpark }); | ||
| }); | ||
| if (toggleAutomationSpark) { | ||
| toggleAutomationSpark.addEventListener('change', (e) => { | ||
| const modMenuDisabledSpark = !e.target.checked; | ||
| chrome.storage.local.set({ modMenuDisabledSpark }); | ||
| updateBadge(); | ||
| notifyTab({ modMenuDisabledSpark }); | ||
| }); | ||
| } | ||
| // ââ Toggle: Clipboard Spark ââ | ||
| toggleCopySpark.addEventListener('change', (e) => { | ||
| const copyDisabledSpark = !e.target.checked; | ||
| chrome.storage.local.set({ copyDisabledSpark }); | ||
| notifyTab({ copyDisabledSpark }); | ||
| }); | ||
| if (toggleCopySpark) { | ||
| toggleCopySpark.addEventListener('change', (e) => { | ||
| const copyDisabledSpark = !e.target.checked; | ||
| chrome.storage.local.set({ copyDisabledSpark }); | ||
| notifyTab({ copyDisabledSpark }); | ||
| }); | ||
| } | ||
| // ââ Visit Site buttons ââ | ||
| const btnVisitStudyrays = document.getElementById('btnVisitStudyrays'); | ||
| btnVisitStudyrays.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://studyrays.cc' }); | ||
| }); | ||
| if (btnVisitStudyrays) { | ||
| btnVisitStudyrays.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://studyrays.cc' }); | ||
| }); | ||
| } | ||
| const btnVisitStudyspark = document.getElementById('btnVisitStudyspark'); | ||
| btnVisitStudyspark.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://studyspark.study' }); | ||
| }); | ||
| if (btnVisitStudyspark) { | ||
| btnVisitStudyspark.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://studyspark.study' }); | ||
| }); | ||
| } | ||
| const btnVisitStudystark = document.getElementById('btnVisitStudystark'); | ||
| btnVisitStudystark.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://studystark.in/' }); | ||
| }); | ||
| if (btnVisitStudystark) { | ||
| btnVisitStudystark.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://studystark.in/' }); | ||
| }); | ||
| } | ||
| const btnVisitPwThor = document.getElementById('btnVisitPwThor'); | ||
| btnVisitPwThor.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://pwthor.live/' }); | ||
| }); | ||
| if (btnVisitPwThor) { | ||
| btnVisitPwThor.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| chrome.tabs.create({ url: 'https://pwthor.live/' }); | ||
| }); | ||
| } | ||
| // ââ Hard Refresh ââ | ||
| btnRefresh.addEventListener('click', () => { | ||
| btnRefresh.textContent = 'Reloading...'; | ||
| btnRefresh.classList.add('reloading'); | ||
| if (btnRefresh) { | ||
| btnRefresh.addEventListener('click', () => { | ||
| btnRefresh.textContent = 'Reloading...'; | ||
| btnRefresh.classList.add('reloading'); | ||
| chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { | ||
| if (tabs && tabs[0]) { | ||
| chrome.tabs.reload(tabs[0].id, { bypassCache: true }); | ||
| } | ||
| chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { | ||
| if (tabs && tabs[0]) { | ||
| chrome.tabs.reload(tabs[0].id, { bypassCache: true }); | ||
| } | ||
| }); | ||
| setTimeout(() => { | ||
| btnRefresh.innerHTML = '⚡ Force Hard Refresh'; | ||
| btnRefresh.classList.remove('reloading'); | ||
| }, 300); | ||
| }); | ||
| setTimeout(() => { | ||
| btnRefresh.innerHTML = '⚡ Force Hard Refresh'; | ||
| btnRefresh.classList.remove('reloading'); | ||
| }, 300); | ||
| }); | ||
| }); | ||
| } | ||
| }); |
| // bypass.js - Runs in MAIN world | ||
| window.prolinkVerified = true; | ||
| // 1. Prevent visibility and focus detection (Stops site from detecting if you left the page/tab) | ||
| Object.defineProperty(document, 'visibilityState', { get: () => 'visible', configurable: true }); | ||
| Object.defineProperty(document, 'hidden', { get: () => false, configurable: true }); | ||
| Object.defineProperty(document, 'hasFocus', { value: () => true, configurable: true }); | ||
| // 1. Prevent background tab throttling & focus detection on Prototype level | ||
| try { | ||
| Object.defineProperty(Document.prototype, 'visibilityState', { get: () => 'visible', configurable: true }); | ||
| Object.defineProperty(Document.prototype, 'hidden', { get: () => false, configurable: true }); | ||
| Object.defineProperty(Document.prototype, 'hasFocus', { value: () => true, configurable: true }); | ||
| Object.defineProperty(window, 'onblur', { get: () => null, set: () => {}, configurable: true }); | ||
| Object.defineProperty(window, 'onfocus', { get: () => null, set: () => {}, configurable: true }); | ||
| } catch (e) {} | ||
| // Intercept page focus/blur event handlers to prevent tracking | ||
| ['visibilitychange', 'webkitvisibilitychange', 'blur', 'focus', 'mouseleave', 'pagehide'].forEach(eventName => { | ||
| window.addEventListener(eventName, (e) => { | ||
| e.stopImmediatePropagation(); | ||
| }, true); | ||
| document.addEventListener(eventName, (e) => { | ||
| e.stopImmediatePropagation(); | ||
| }, true); | ||
| // 2. Intercept and block window/tab switch detection events | ||
| const eventsToBlock = [ | ||
| 'visibilitychange', 'webkitvisibilitychange', 'mozvisibilitychange', | ||
| 'msvisibilitychange', 'blur', 'focus', 'mouseleave', 'pagehide' | ||
| ]; | ||
| eventsToBlock.forEach(eventName => { | ||
| window.addEventListener(eventName, e => e.stopImmediatePropagation(), true); | ||
| document.addEventListener(eventName, e => e.stopImmediatePropagation(), true); | ||
| }); | ||
| // 2. Block Alerts (Prevents "Please wait for timer" popups) | ||
| window.alert = function() { console.log("[ZeroGate] Blocked site alert:", arguments[0]); return true; }; | ||
| // 3. Keep requestAnimationFrame ticking even when tab is backgrounded/hidden | ||
| const originalRAF = window.requestAnimationFrame; | ||
| window.requestAnimationFrame = function(callback) { | ||
| if (document.hidden || document.visibilityState === 'hidden') { | ||
| return setTimeout(() => callback(performance.now()), 1000 / 60); | ||
| } | ||
| return originalRAF(callback); | ||
| }; | ||
| // 3. Speed up internal timers | ||
| // 4. Speed up interval countdown timers | ||
| const originalSetInterval = window.setInterval; | ||
| window.setInterval = function(fn, delay) { | ||
| if (delay === 100 || delay === 1000) delay = 50; | ||
| return originalSetInterval(fn, delay); | ||
| if (delay === 100 || delay === 1000) delay = 50; | ||
| return originalSetInterval(fn, delay); | ||
| }; | ||
| // 4. Stop site from blocking right-click or keys | ||
| // 5. Block site alerts and key/context-menu locks | ||
| window.alert = function() { console.log("[ZeroGate] Blocked site alert:", arguments[0]); return true; }; | ||
| document.addEventListener('contextmenu', e => e.stopPropagation(), true); | ||
| document.addEventListener('keydown', e => e.stopPropagation(), true); |
+332
-75
| // main.js - Runs in ISOLATED world | ||
| (() => { | ||
| let modMenuDisabled = false; | ||
| let gameDisabled = false; | ||
| let copied = false; | ||
| let isProcessing = false; // Lock to prevent spamming actions every second | ||
| let isProcessing = false; | ||
| let gameClosedByUser = false; | ||
| chrome.storage.local.get(['modMenuDisabled'], (result) => { | ||
| chrome.storage.local.get(['modMenuDisabled', 'gameDisabled'], (result) => { | ||
| modMenuDisabled = result.modMenuDisabled === undefined ? false : result.modMenuDisabled; | ||
| gameDisabled = result.gameDisabled === undefined ? false : result.gameDisabled; | ||
| }); | ||
@@ -15,18 +18,11 @@ | ||
| } | ||
| }); | ||
| window.addEventListener('message', (event) => { | ||
| if (event.source !== window) return; | ||
| if (!event.data || event.data.source !== 'SkipKey_ModMenu') return; | ||
| if (event.data.action === 'disableAutomation') { | ||
| modMenuDisabled = true; | ||
| chrome.storage.local.set({ modMenuDisabled: true }); | ||
| } else if (event.data.action === 'enableAutomation') { | ||
| modMenuDisabled = false; | ||
| chrome.storage.local.set({ modMenuDisabled: false }); | ||
| if (message.gameDisabled !== undefined) { | ||
| gameDisabled = message.gameDisabled; | ||
| if (gameDisabled) { | ||
| destroyMiniGame(); | ||
| } | ||
| } | ||
| }); | ||
| const sleep = (ms) => new Promise(res => setTimeout(res, ms + Math.random() * 200)); | ||
| const sleep = (ms) => new Promise(res => setTimeout(res, ms + Math.random() * 300)); | ||
@@ -46,11 +42,264 @@ // Remove annoying Ads, Overlays, and the AdBlock popup (#AdbModel) | ||
| // Advanced Mouse click simulation | ||
| // Helper function to remove the mini-game UI permanently for the session | ||
| function destroyMiniGame() { | ||
| const gameContainer = document.getElementById('zg-game-container'); | ||
| if (gameContainer) { | ||
| gameContainer.remove(); | ||
| } | ||
| gameClosedByUser = true; | ||
| } | ||
| // đšī¸ CENTERED BIG-SCREEN MINI-GAME OVERLAY (Flappy Bird & Chrome Dino) đšī¸ | ||
| function spawnMiniGame() { | ||
| if (document.getElementById('zg-game-container') || gameClosedByUser || gameDisabled) return; | ||
| const container = document.createElement('div'); | ||
| container.id = 'zg-game-container'; | ||
| container.style.cssText = ` | ||
| position: fixed; | ||
| top: 50%; | ||
| left: 50%; | ||
| transform: translate(-50%, -50%); | ||
| z-index: 9999999; | ||
| width: 620px; | ||
| height: 440px; | ||
| background: #1e1e2e; | ||
| border: 3px solid #45475a; | ||
| border-radius: 16px; | ||
| box-shadow: 0 20px 50px rgba(0,0,0,0.8); | ||
| overflow: hidden; | ||
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| `; | ||
| // Header Controls | ||
| const header = document.createElement('div'); | ||
| header.style.cssText = 'width:100%; height:45px; background:#181825; display:flex; align-items:center; justify-content:space-between; padding:0 15px; box-sizing:border-box; border-bottom:2px solid #313244;'; | ||
| const tabContainer = document.createElement('div'); | ||
| tabContainer.style.cssText = 'display:flex; gap:10px;'; | ||
| const btnFlappy = document.createElement('button'); | ||
| btnFlappy.innerText = 'đ¤ Flappy Bird'; | ||
| btnFlappy.style.cssText = 'background:#fab387; color:#11111b; border:none; border-radius:6px; padding:6px 12px; font-weight:bold; cursor:pointer; font-size:13px;'; | ||
| const btnDino = document.createElement('button'); | ||
| btnDino.innerText = 'đĻ Chrome Dino'; | ||
| btnDino.style.cssText = 'background:#313244; color:#cdd6f4; border:none; border-radius:6px; padding:6px 12px; font-weight:bold; cursor:pointer; font-size:13px;'; | ||
| tabContainer.appendChild(btnFlappy); | ||
| tabContainer.appendChild(btnDino); | ||
| header.appendChild(tabContainer); | ||
| const closeBtn = document.createElement('button'); | ||
| closeBtn.innerText = 'â Close'; | ||
| closeBtn.style.cssText = 'background:#f38ba8; color:#11111b; border:none; border-radius:6px; cursor:pointer; font-weight:bold; padding:6px 12px; font-size:12px;'; | ||
| closeBtn.onclick = () => destroyMiniGame(); | ||
| header.appendChild(closeBtn); | ||
| container.appendChild(header); | ||
| const canvas = document.createElement('canvas'); | ||
| canvas.width = 600; | ||
| canvas.height = 380; | ||
| canvas.style.cssText = 'margin-top:5px; background:#70c5ce; border-radius:8px; cursor:pointer;'; | ||
| container.appendChild(canvas); | ||
| document.body.appendChild(container); | ||
| const ctx = canvas.getContext('2d'); | ||
| // Persistent State across step changes | ||
| let currentGame = 'flappy'; // 'flappy' or 'dino' | ||
| let highScore = 0; | ||
| chrome.storage.local.get(['zg_saved_game', 'zg_high_score'], (res) => { | ||
| if (res.zg_saved_game) { | ||
| currentGame = res.zg_saved_game; | ||
| updateTabStyles(); | ||
| } | ||
| if (res.zg_high_score) highScore = res.zg_high_score; | ||
| }); | ||
| function updateTabStyles() { | ||
| if (currentGame === 'flappy') { | ||
| btnFlappy.style.background = '#fab387'; btnFlappy.style.color = '#11111b'; | ||
| btnDino.style.background = '#313244'; btnDino.style.color = '#cdd6f4'; | ||
| canvas.style.background = '#70c5ce'; | ||
| } else { | ||
| btnDino.style.background = '#a6e3a1'; btnDino.style.color = '#11111b'; | ||
| btnFlappy.style.background = '#313244'; btnFlappy.style.color = '#cdd6f4'; | ||
| canvas.style.background = '#f7f7f7'; | ||
| } | ||
| } | ||
| btnFlappy.onclick = () => { currentGame = 'flappy'; resetGame(); updateTabStyles(); chrome.storage.local.set({ zg_saved_game: 'flappy' }); }; | ||
| btnDino.onclick = () => { currentGame = 'dino'; resetGame(); updateTabStyles(); chrome.storage.local.set({ zg_saved_game: 'dino' }); }; | ||
| // --- GAME ENGINES --- | ||
| let frames = 0, score = 0, state = 0; // 0: Ready, 1: Playing, 2: GameOver | ||
| let bird = { x: 80, y: 180, v: 0, g: 0.3, jump: -5.5 }; | ||
| let pipes = []; | ||
| let dino = { x: 60, y: 300, v: 0, g: 0.6, jump: -11, grounded: true }; | ||
| let cacti = []; | ||
| function resetGame() { | ||
| frames = 0; score = 0; state = 0; | ||
| bird = { x: 80, y: 180, v: 0, g: 0.3, jump: -5.5 }; | ||
| pipes = []; | ||
| dino = { x: 60, y: 300, v: 0, g: 0.6, jump: -11, grounded: true }; | ||
| cacti = []; | ||
| } | ||
| function triggerAction() { | ||
| if (state === 0) state = 1; | ||
| else if (state === 1) { | ||
| if (currentGame === 'flappy') bird.v = bird.jump; | ||
| else if (currentGame === 'dino' && dino.grounded) { dino.v = dino.jump; dino.grounded = false; } | ||
| } else if (state === 2) { | ||
| resetGame(); | ||
| } | ||
| } | ||
| const handleKeyDown = (e) => { | ||
| if (!document.getElementById('zg-game-container')) return; | ||
| if (e.code === 'Space' || e.code === 'ArrowUp') { | ||
| e.preventDefault(); | ||
| triggerAction(); | ||
| } | ||
| }; | ||
| window.addEventListener('keydown', handleKeyDown); | ||
| canvas.addEventListener('mousedown', (e) => { e.preventDefault(); triggerAction(); }); | ||
| function update() { | ||
| if (state !== 1) return; | ||
| if (score > highScore) { | ||
| highScore = score; | ||
| chrome.storage.local.set({ zg_high_score: highScore }); | ||
| } | ||
| if (currentGame === 'flappy') { | ||
| bird.v += bird.g; | ||
| bird.y += bird.v; | ||
| if (frames % 90 === 0) { | ||
| let topH = Math.random() * 180 + 40; | ||
| pipes.push({ x: 600, top: topH, bottom: 380 - (topH + 120) }); | ||
| } | ||
| pipes.forEach(p => { | ||
| p.x -= 3; | ||
| if (p.x === 81) score++; | ||
| if (bird.x + 12 > p.x && bird.x - 12 < p.x + 45 && (bird.y - 12 < p.top || bird.y + 12 > 380 - p.bottom)) state = 2; | ||
| }); | ||
| pipes = pipes.filter(p => p.x > -50); | ||
| if (bird.y + 12 > 380 || bird.y - 12 < 0) state = 2; | ||
| } else if (currentGame === 'dino') { | ||
| dino.v += dino.g; | ||
| dino.y += dino.v; | ||
| if (dino.y >= 300) { dino.y = 300; dino.v = 0; dino.grounded = true; } | ||
| if (frames % Math.floor(80 + Math.random() * 40) === 0) { | ||
| cacti.push({ x: 600, w: 20 + Math.random() * 15, h: 35 + Math.random() * 20 }); | ||
| } | ||
| cacti.forEach(c => { | ||
| c.x -= 5.5; | ||
| if (c.x + c.w < dino.x && !c.passed) { c.passed = true; score++; } | ||
| if (dino.x + 20 > c.x && dino.x < c.x + c.w && dino.y + 35 > 335 - c.h) state = 2; | ||
| }); | ||
| cacti = cacti.filter(c => c.x > -40); | ||
| } | ||
| } | ||
| function draw() { | ||
| if (currentGame === 'flappy') { | ||
| ctx.fillStyle = '#70c5ce'; ctx.fillRect(0, 0, 600, 380); | ||
| ctx.fillStyle = '#2ed573'; | ||
| pipes.forEach(p => { | ||
| ctx.fillRect(p.x, 0, 45, p.top); | ||
| ctx.fillRect(p.x, 380 - p.bottom, 45, p.bottom); | ||
| }); | ||
| ctx.fillStyle = '#ffa502'; | ||
| ctx.beginPath(); ctx.arc(bird.x, bird.y, 12, 0, Math.PI * 2); ctx.fill(); | ||
| ctx.fillStyle = '#ffffff'; ctx.font = 'bold 20px Arial'; | ||
| ctx.fillText(`Score: ${score} | Best: ${highScore}`, 20, 35); | ||
| if (state === 0) { ctx.fillStyle = '#fff'; ctx.fillText('Click or Press Space to Jump', 170, 190); } | ||
| if (state === 2) { ctx.fillStyle = '#ff4757'; ctx.fillText('Game Over! Click to Restart', 170, 190); } | ||
| } else if (currentGame === 'dino') { | ||
| ctx.fillStyle = '#f7f7f7'; ctx.fillRect(0, 0, 600, 380); | ||
| // Ground | ||
| ctx.strokeStyle = '#535353'; ctx.lineWidth = 2; | ||
| ctx.beginPath(); ctx.moveTo(0, 335); ctx.lineTo(600, 335); ctx.stroke(); | ||
| // Dino | ||
| ctx.fillStyle = '#535353'; | ||
| ctx.fillRect(dino.x, dino.y, 25, 35); | ||
| // Cacti | ||
| ctx.fillStyle = '#2e7d32'; | ||
| cacti.forEach(c => ctx.fillRect(c.x, 335 - c.h, c.w, c.h)); | ||
| ctx.fillStyle = '#535353'; ctx.font = 'bold 20px Arial'; | ||
| ctx.fillText(`Score: ${score} | Best: ${highScore}`, 20, 35); | ||
| if (state === 0) { ctx.fillText('Press Space or Click to Run & Jump', 130, 180); } | ||
| if (state === 2) { ctx.fillStyle = '#d32f2f'; ctx.fillText('Game Over! Click to Restart', 160, 180); } | ||
| } | ||
| } | ||
| function loop() { | ||
| update(); draw(); frames++; | ||
| if (document.getElementById('zg-game-container')) requestAnimationFrame(loop); | ||
| } | ||
| loop(); | ||
| } | ||
| // --- HUMAN-LIKE AUTOMATION BEHAVIORS --- | ||
| async function humanScrollTo(el) { | ||
| if (!el) return; | ||
| const targetY = el.getBoundingClientRect().top + window.scrollY - 200; | ||
| const startY = window.scrollY; | ||
| const distance = targetY - startY; | ||
| const steps = 30 + Math.floor(Math.random() * 20); | ||
| for (let i = 1; i <= steps; i++) { | ||
| window.scrollTo(0, startY + (distance * (i / steps))); | ||
| await sleep(15 + Math.random() * 25); | ||
| } | ||
| await sleep(400); | ||
| } | ||
| async function humanClick(el) { | ||
| if (!el || window.getComputedStyle(el).display === 'none') return; | ||
| el.scrollIntoView({ behavior: 'smooth', block: 'center' }); | ||
| await sleep(500); | ||
| await humanScrollTo(el); | ||
| const rect = el.getBoundingClientRect(); | ||
| const opts = { bubbles: true, cancelable: true, view: window, clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2 }; | ||
| const offsetX = (Math.random() - 0.5) * (rect.width * 0.6); | ||
| const offsetY = (Math.random() - 0.5) * (rect.height * 0.6); | ||
| const clickX = rect.left + (rect.width / 2) + offsetX; | ||
| const clickY = rect.top + (rect.height / 2) + offsetY; | ||
| const opts = { bubbles: true, cancelable: true, view: window, clientX: clickX, clientY: clickY }; | ||
| el.dispatchEvent(new MouseEvent('mousemove', opts)); | ||
| await sleep(100 + Math.random() * 150); | ||
| el.dispatchEvent(new MouseEvent('mousedown', opts)); | ||
| await sleep(50); | ||
| await sleep(60 + Math.random() * 80); | ||
| el.dispatchEvent(new MouseEvent('mouseup', opts)); | ||
@@ -60,3 +309,3 @@ el.dispatchEvent(new MouseEvent('click', opts)); | ||
| // The Backend API Fetcher for the final step | ||
| // Final Step 6/6 Handler | ||
| async function handleFinalStep() { | ||
@@ -69,34 +318,57 @@ if (copied || modMenuDisabled) return; | ||
| if (stepEl && stepEl.innerText.includes('6/6') && finalBtn) { | ||
| if (finalBtn.disabled || window.getComputedStyle(finalBtn).display === 'none') return; | ||
| copied = true; | ||
| console.log("[ZeroGate Engine] Step 6/6 reached. Triggering API fetch..."); | ||
| console.log("[ZeroGate Engine] Step 6/6 reached."); | ||
| try { | ||
| const response = await fetch('/api.php?action=wppro_get_final_link'); | ||
| const res = await response.json(); | ||
| await humanScrollTo(finalBtn); | ||
| console.log("[ZeroGate Engine] Waiting 45 seconds before opening final link..."); | ||
| await sleep(45000); | ||
| if (res.success && res.finalUrl) { | ||
| const targetUrl = res.finalUrl; | ||
| await window.SkipKeyCopy(targetUrl); | ||
| const randomizedDelay = 5800 + Math.floor(Math.random() * 1600); | ||
| console.log(`[ZeroGate Engine] Simulating human delay for ${randomizedDelay}ms...`); | ||
| await sleep(randomizedDelay); | ||
| console.log("[ZeroGate Engine] Opening Tab 1..."); | ||
| chrome.runtime.sendMessage({ action: "openNewTab", url: targetUrl }); | ||
| if (finalBtn.disabled) finalBtn.disabled = false; | ||
| const intervalDelay = 3100 + Math.floor(Math.random() * 400); | ||
| console.log(`[ZeroGate Engine] Waiting ${intervalDelay}ms interval...`); | ||
| await sleep(intervalDelay); | ||
| let targetUrl = null; | ||
| if (finalBtn.href && !finalBtn.href.startsWith('javascript:')) { | ||
| targetUrl = finalBtn.href; | ||
| } else if (finalBtn.dataset && finalBtn.dataset.url) { | ||
| targetUrl = finalBtn.dataset.url; | ||
| } | ||
| console.log("[ZeroGate Engine] Opening Tab 2..."); | ||
| chrome.runtime.sendMessage({ action: "openNewTab", url: targetUrl }); | ||
| } else { | ||
| copied = false; | ||
| if (!targetUrl) { | ||
| try { | ||
| console.log("[ZeroGate Engine] Fetching link via API endpoint..."); | ||
| const response = await fetch('/api.php?action=wppro_get_final_link'); | ||
| const res = await response.json(); | ||
| if (res.success && res.finalUrl) targetUrl = res.finalUrl; | ||
| } catch (err) { | ||
| console.error("[ZeroGate Engine] Error fetching API link:", err); | ||
| } | ||
| } catch (err) { | ||
| console.error("[ZeroGate Engine] Error fetching final link:", err); | ||
| } | ||
| if (targetUrl) { | ||
| try { | ||
| if (typeof window.SkipKeyCopy === 'function') { | ||
| await window.SkipKeyCopy(targetUrl); | ||
| } else { | ||
| const script = document.createElement('script'); | ||
| script.textContent = `if(window.SkipKeyCopy) window.SkipKeyCopy("${targetUrl}");`; | ||
| document.documentElement.appendChild(script); | ||
| script.remove(); | ||
| } | ||
| } catch(e) { | ||
| console.warn("[ZeroGate Engine] SkipKeyCopy skipped:", e); | ||
| } | ||
| console.log("[ZeroGate Engine] Opening target URL in new tab:", targetUrl); | ||
| chrome.runtime.sendMessage({ action: "openNewTab", url: targetUrl }); | ||
| // đ AUTOMATICALLY CLOSE GAME WINDOW WHEN NEW TAB OPENS | ||
| destroyMiniGame(); | ||
| await sleep(1500); | ||
| } else { | ||
| await humanClick(finalBtn); | ||
| // đ CLOSE GAME WINDOW ON FALLBACK CLICK TOO | ||
| destroyMiniGame(); | ||
| copied = false; | ||
@@ -107,6 +379,11 @@ } | ||
| // Main Loop | ||
| async function autoRun() { | ||
| if (modMenuDisabled || copied || isProcessing) return; | ||
| if (modMenuDisabled || copied) return; | ||
| // --- Google Search Auto-open First Result --- | ||
| // Launch game overlay if user hasn't closed or disabled it | ||
| spawnMiniGame(); | ||
| if (isProcessing) return; | ||
| if (window.location.hostname.includes('google.com') && window.location.pathname === '/search') { | ||
@@ -116,3 +393,2 @@ const firstLink = document.querySelector('a.zReHs'); | ||
| copied = true; | ||
| console.log('[ZeroGate Engine] Auto-opening first Google Search result...'); | ||
| window.location.replace(firstLink.href); | ||
@@ -127,35 +403,21 @@ return; | ||
| await humanClick(vBtn); | ||
| await sleep(1000); | ||
| await sleep(1500); | ||
| } | ||
| // Step 2: Footer "CONTINUE" -> Wait 10s -> Click Proceed -> Wait 25s -> Click Proceed 3 times | ||
| // Step 2: Footer "CONTINUE" | ||
| const fBtn = document.getElementById('footerBtn'); | ||
| if (fBtn && fBtn.innerText.includes('CONTINUE') && !fBtn.classList.contains('verifying')) { | ||
| isProcessing = true; | ||
| console.log('[ZeroGate Engine] Clicking Continue button...'); | ||
| await humanClick(fBtn); | ||
| console.log('[ZeroGate Engine] Waiting 10 seconds...'); | ||
| await sleep(10000); | ||
| // Initial Proceed click | ||
| const pWaitInitial = document.getElementById('pleaseWait'); | ||
| if (pWaitInitial && window.getComputedStyle(pWaitInitial).display !== 'none') { | ||
| console.log('[ZeroGate Engine] Clicking Proceed button...'); | ||
| await humanClick(pWaitInitial); | ||
| } | ||
| console.log('[ZeroGate Engine] Waiting 25 seconds before multi-clicking Proceed...'); | ||
| await sleep(25000); | ||
| // Press the Proceed button 3 times consecutively after 25 seconds | ||
| const pWaitFinal = document.getElementById('pleaseWait'); | ||
| if (pWaitFinal && window.getComputedStyle(pWaitFinal).display !== 'none') { | ||
| for (let i = 1; i <= 3; i++) { | ||
| console.log(`[ZeroGate Engine] Multi-clicking Proceed attempt ${i}/3...`); | ||
| await humanClick(pWaitFinal); | ||
| await sleep(600); // 600ms gap between consecutive clicks | ||
| await sleep(600 + Math.random() * 200); | ||
| } | ||
| } | ||
| isProcessing = false; | ||
@@ -165,3 +427,3 @@ return; | ||
| // Fallback if Proceed appears independently later | ||
| // Fallback step handling | ||
| const pWait = document.getElementById('pleaseWait'); | ||
@@ -171,14 +433,10 @@ if (pWait && window.getComputedStyle(pWait).display !== 'none') { | ||
| isProcessing = true; | ||
| console.log('[ZeroGate Engine] Clicking Proceed button (fallback)...'); | ||
| await humanClick(pWait); | ||
| console.log('[ZeroGate Engine] Waiting 25 seconds before multi-clicking Proceed...'); | ||
| await sleep(25000); | ||
| for (let i = 1; i <= 3; i++) { | ||
| console.log(`[ZeroGate Engine] Multi-clicking Proceed fallback attempt ${i}/3...`); | ||
| await humanClick(pWait); | ||
| await sleep(600); | ||
| await sleep(600 + Math.random() * 200); | ||
| } | ||
| isProcessing = false; | ||
@@ -192,3 +450,2 @@ return; | ||
| // Step 4: Final Link Fetch | ||
| await handleFinalStep(); | ||
@@ -195,0 +452,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet