您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Best Chrome Dino Mod Menu
// ==UserScript== // @name Chrome Dino Mod Menu [15.2] // @namespace http://tampermonkey.net/ // @version 15.2 // @description Best Chrome Dino Mod Menu // @author Jadob Lane // @match https://chromedino.com/ // @match https://dino-chrome.com/ // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; // --- Shared state --- let flyHackActive = false; let flying = false; let flyAnimationId = null; let obstacleInterval = null; let rainbowGlowEnabled = false; let glowElement = null; let glowAnimation = null; let originalGravity = null; let rainbowStyleElement = null; let originalBgColor = null; let obsESPOverlay = null; let obsESPContext = null; let obsESPDrawHook = null; let removeCloudsInterval = null; let rainCloudsEnabled = false; let rainCloudsAnimationId = null; let rainCloudCanvas = null; let rainCloudContext = null; let autoPlayEnabled = false; let autoPlayInterval = null; // Obstacle Tracers variables let obsTracerOverlay = null; let obsTracerContext = null; let obsTracerInterval = null; // Teleport Past Obstacles interval let teleportInterval = null; // Air Jump variables let airJumping = false; let airJumpInterval = null; // --- Mod Menu UI --- function createModMenu() { const menu = document.createElement('div'); menu.id = 'modMenu'; menu.style = ` position: fixed; top: 20px; left: 20px; padding: 10px; background-color: rgba(0, 0, 0, 0.7); color: #fff; font-family: Arial, sans-serif; font-size: 14px; border-radius: 8px; z-index: 9999; user-select: none; pointer-events: auto; max-width: 200px; `; const title = document.createElement('div'); title.textContent = '🦖Chrome Dino Mod Menu'; title.style.fontWeight = 'bold'; title.style.marginBottom = '8px'; menu.appendChild(title); function addToggle(labelText, onToggle) { const label = document.createElement('label'); label.style.display = 'block'; label.style.marginBottom = '6px'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.style.marginRight = '6px'; checkbox.addEventListener('click', e => e.stopPropagation()); checkbox.addEventListener('change', function () { onToggle(this.checked); }); label.appendChild(checkbox); label.appendChild(document.createTextNode(labelText)); menu.appendChild(label); } addToggle('God Mode', toggleGodMode); addToggle('Speed Hack', applySpeedHack); addToggle('Super Jump', toggleSuperJump); addToggle('Fly Hack [F]', toggleFlyHack); addToggle('Remove Obstacles', toggleRemoveObstacles); addToggle('Remove Clouds', toggleRemoveClouds); addToggle('Rain Clouds', toggleRainClouds); addToggle('Clone Game', toggleBigDino); addToggle('Rainbow Glow', toggleRainbowGlow); addToggle('Low Gravity', toggleLowGravity); addToggle('Rainbow Background', toggleRainbowBackground); addToggle('Night Mode', toggleNightMode); addToggle('Obstacle ESP', toggleObstacleESP); addToggle('Obstacle Tracers', toggleObsTracers); addToggle('Auto Play', toggleAutoPlay); addToggle('Teleport Past Obstacles', toggleTeleportPastObstacles); // New Air Jump toggle added here addToggle('Air Jump', toggleAirJump); document.body.appendChild(menu); // --- Feature implementations --- function toggleGodMode(enabled) { const proto = Runner.prototype; if (enabled) { if (!proto._origGameOver) proto._origGameOver = proto.gameOver; proto.gameOver = () => {}; } else if (proto._origGameOver) { proto.gameOver = proto._origGameOver; } } function applySpeedHack(enabled) { const inst = Runner.instance_; if (inst?.setSpeed) inst.setSpeed(enabled ? 1000 : 6); } function toggleSuperJump(enabled) { const trex = Runner.instance_?.tRex; if (trex?.setJumpVelocity) trex.setJumpVelocity(enabled ? 100 : -10.5); } function toggleFlyHack(enabled) { const FLY_SPEED = 5; if (enabled && !flyHackActive) { flyHackActive = true; // Key event handlers function onKeyDown(e) { if (e.key.toLowerCase() === 'f') flying = true; } function onKeyUp(e) { if (e.key.toLowerCase() === 'f') flying = false; } document.addEventListener('keydown', onKeyDown); document.addEventListener('keyup', onKeyUp); // Fly animation loop function flyUp() { const trex = window.Runner?.instance_?.tRex; if (flying && trex && trex.yPos > 0) { trex.yPos = Math.max(0, trex.yPos - FLY_SPEED); } flyAnimationId = requestAnimationFrame(flyUp); } flyUp(); // Save handlers so we can remove later toggleFlyHack.onKeyDown = onKeyDown; toggleFlyHack.onKeyUp = onKeyUp; } else if (!enabled && flyHackActive) { flyHackActive = false; flying = false; // Remove event listeners document.removeEventListener('keydown', toggleFlyHack.onKeyDown); document.removeEventListener('keyup', toggleFlyHack.onKeyUp); // Cancel animation frame if (flyAnimationId) { cancelAnimationFrame(flyAnimationId); flyAnimationId = null; } } } function toggleRemoveObstacles(enabled) { const r = Runner.instance_; if (!r) return; if (enabled) { obstacleInterval = setInterval(() => { r.horizon.obstacles = []; }, 30); } else { clearInterval(obstacleInterval); } } function toggleRemoveClouds(enabled) { const r = Runner.instance_; if (!r) return; if (enabled) { removeCloudsInterval = setInterval(() => { r.horizon.clouds = []; }, 30); } else { clearInterval(removeCloudsInterval); } } function toggleRainClouds(enabled) { const runner = Runner.instance_; if (!runner) return; const cloudColor = 'rgba(200,200,200,0.7)'; const cloudCount = 8; const clouds = []; if (enabled) { rainCloudsEnabled = true; rainCloudCanvas = document.createElement('canvas'); rainCloudCanvas.style.cssText = 'position:absolute;pointer-events:none;z-index:10;'; document.body.appendChild(rainCloudCanvas); rainCloudContext = rainCloudCanvas.getContext('2d'); for (let i = 0; i < cloudCount; i++) { clouds.push({ x: Math.random()*window.innerWidth, y: Math.random()*40+10, r: Math.random()*10+10, s: 0.15+Math.random()*0.1 }); } function animate() { if (!rainCloudsEnabled) return; const rect = runner.canvas.getBoundingClientRect(); rainCloudCanvas.width = rect.width; rainCloudCanvas.height = rect.height; rainCloudCanvas.style.top = rect.top+'px'; rainCloudCanvas.style.left = rect.left+'px'; rainCloudContext.clearRect(0,0,rect.width,rect.height); for (const c of clouds) { c.x += c.s; if (c.x - c.r*2 > rect.width) { c.x = -c.r*2; c.y = Math.random()*40+10; } rainCloudContext.beginPath(); rainCloudContext.fillStyle = cloudColor; rainCloudContext.arc(c.x,c.y,c.r,0,2*Math.PI); rainCloudContext.arc(c.x+c.r*0.6,c.y-c.r*0.3,c.r*0.7,0,2*Math.PI); rainCloudContext.arc(c.x+c.r*1.2,c.y,c.r,0,2*Math.PI); rainCloudContext.fill(); } rainCloudsAnimationId = requestAnimationFrame(animate); } animate(); } else { rainCloudsEnabled = false; cancelAnimationFrame(rainCloudsAnimationId); rainCloudCanvas.remove(); } } function toggleBigDino(enabled) { const interval = setInterval(() => { const gameCanvas = document.querySelector('canvas'); const runner = window.Runner?.instance_; if (!gameCanvas || !runner) return; clearInterval(interval); // Create cloned canvas const cloneCanvas = document.createElement('canvas'); cloneCanvas.width = gameCanvas.width; cloneCanvas.height = gameCanvas.height; cloneCanvas.style.position = 'absolute'; cloneCanvas.style.left = gameCanvas.offsetLeft + gameCanvas.width + 20 + 'px'; cloneCanvas.style.top = gameCanvas.offsetTop + 'px'; cloneCanvas.style.zIndex = 1000; document.body.appendChild(cloneCanvas); const cloneCtx = cloneCanvas.getContext('2d'); const originalCtx = gameCanvas.getContext('2d'); // Copy the game canvas to the clone every frame function updateClone() { try { cloneCtx.clearRect(0, 0, cloneCanvas.width, cloneCanvas.height); cloneCtx.drawImage(gameCanvas, 0, 0); } catch (e) { console.warn('Clone draw failed:', e); } requestAnimationFrame(updateClone); } updateClone(); }, 100); } function toggleRainbowGlow(enabled) { const r = Runner.instance_; const canvas = document.querySelector('.runner-canvas'); if (!r || !canvas) return; const container = canvas.parentElement; container.style.position = 'relative'; if (enabled) { if (!glowElement) { glowElement = document.createElement('div'); glowElement.style.cssText = 'position:absolute;pointer-events:none;z-index:9999;'; container.appendChild(glowElement); } rainbowGlowEnabled = true; let hue = 0; glowAnimation = setInterval(() => { hue = (hue + 3) % 360; glowElement.style.boxShadow = `0 0 8px 4px hsl(${hue},100%,60%)`; }, 50); (function update() { if (!rainbowGlowEnabled) return; const d = r.tRex; glowElement.style.left = d.xPos + 'px'; glowElement.style.top = d.yPos + 'px'; glowElement.style.width = d.config.WIDTH + 'px'; glowElement.style.height= d.config.HEIGHT + 'px'; requestAnimationFrame(update); })(); } else { rainbowGlowEnabled = false; clearInterval(glowAnimation); glowElement?.remove(); glowElement = null; } } function toggleLowGravity(enabled) { const t = Runner.instance_?.tRex; if (!t) return; if (enabled) { if (originalGravity === null) originalGravity = t.config.GRAVITY; t.config.GRAVITY = 0.1; } else if (originalGravity !== null) { t.config.GRAVITY = originalGravity; } } function toggleRainbowBackground(enabled) { if (enabled) { rainbowStyleElement = document.createElement('style'); rainbowStyleElement.textContent = ` @keyframes rainbowBackground { 0% { background-color: red; } 16% { background-color: orange; } 33% { background-color: yellow; } 50% { background-color: green; } 66% { background-color: blue; } 83% { background-color: indigo; } 100% { background-color: violet; } } body { animation: rainbowBackground 5s linear infinite !important; } `; document.head.appendChild(rainbowStyleElement); } else { rainbowStyleElement?.remove(); document.body.style.animation = 'none'; } } function toggleNightMode(enabled) { if (enabled) { originalBgColor = document.body.style.backgroundColor; document.body.style.backgroundColor = 'black'; } else { document.body.style.backgroundColor = originalBgColor || ''; } } function toggleObstacleESP(enabled) { const r = Runner.instance_; const base = r?.canvas; if (!base) return; if (enabled) { if (!obsESPOverlay) { obsESPOverlay = document.createElement('canvas'); obsESPOverlay.width = base.width; obsESPOverlay.height = base.height; obsESPOverlay.style.cssText = ` position:absolute; left:${base.offsetLeft}px; top:${base.offsetTop}px; pointer-events:none; z-index:9998; `; base.parentNode.appendChild(obsESPOverlay); obsESPContext = obsESPOverlay.getContext('2d'); } obsESPDrawHook = setInterval(() => { obsESPContext.clearRect(0,0,obsESPOverlay.width,obsESPOverlay.height); for (const o of r.horizon.obstacles) { obsESPContext.strokeStyle = 'blue'; obsESPContext.lineWidth = 2; obsESPContext.strokeRect(o.xPos, o.yPos, o.width, o.typeConfig.height); } }, 16); } else { clearInterval(obsESPDrawHook); obsESPOverlay?.remove(); obsESPOverlay = null; } } // --- Obstacle Tracers: red lines from dino center to obstacles --- function toggleObsTracers(enabled) { const r = Runner.instance_; const base = r?.canvas; if (!base) return; if (enabled) { if (!obsTracerOverlay) { obsTracerOverlay = document.createElement('canvas'); obsTracerOverlay.width = base.width; obsTracerOverlay.height = base.height; obsTracerOverlay.style.cssText = ` position:absolute; left:${base.offsetLeft}px; top:${base.offsetTop}px; pointer-events:none; z-index:9998; `; base.parentNode.appendChild(obsTracerOverlay); obsTracerContext = obsTracerOverlay.getContext('2d'); } obsTracerInterval = setInterval(() => { obsTracerContext.clearRect(0, 0, obsTracerOverlay.width, obsTracerOverlay.height); const dino = r.tRex; if (!dino) return; const dinoCenterX = dino.xPos + dino.config.WIDTH / 2; const dinoCenterY = dino.yPos + dino.config.HEIGHT / 2; for (const o of r.horizon.obstacles) { const obstacleCenterX = o.xPos + o.width / 2; const obstacleCenterY = o.yPos + o.typeConfig.height / 2; obsTracerContext.beginPath(); obsTracerContext.moveTo(dinoCenterX, dinoCenterY); obsTracerContext.lineTo(obstacleCenterX, obstacleCenterY); obsTracerContext.strokeStyle = 'red'; obsTracerContext.lineWidth = 2; obsTracerContext.stroke(); } }, 16); } else { clearInterval(obsTracerInterval); if (obsTracerOverlay) { obsTracerOverlay.remove(); obsTracerOverlay = null; obsTracerContext = null; } } } } // --- Auto Play logic with duck lock and early cactus jump --- function toggleAutoPlay(enabled) { const r = Runner.instance_; if (!r) return; autoPlayEnabled = enabled; let duckLockUntil = 0; // Timestamp until which the dino should stay ducked if (enabled) { autoPlayInterval = setInterval(() => { const t = r.tRex; const obstacles = r.horizon.obstacles; if (!t || !obstacles) return; const now = Date.now(); const upcomingObstacles = obstacles.filter(o => o.xPos > t.xPos); let shouldDuck = false; for (const obs of upcomingObstacles) { const dist = obs.xPos - t.xPos; // Handle pterodactyls if (obs.typeConfig.type === 'PTERODACTYL') { const isLow = obs.yPos > t.yPos; if (dist < 100) { if (isLow && !t.jumping && !t.ducking) { // Jump over low pterodactyl document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 38 })); document.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 38 })); break; } else if (!isLow) { // Duck under high pterodactyl shouldDuck = true; duckLockUntil = now + 400; // Stay ducked for 400ms break; } } } else { // Handle cactus or ground obstacle if (dist < 100 && !t.jumping && !t.ducking) { document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 38 })); // jump document.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 38 })); break; } } } // Apply duck or un-duck with duck lock if ((shouldDuck || now < duckLockUntil) && !t.ducking) { document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 40 })); // duck } else if (!shouldDuck && now >= duckLockUntil && t.ducking) { document.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 40 })); // un-duck } }, 20); } else { clearInterval(autoPlayInterval); document.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 40 })); // stop ducking } } // --- Teleport Past Obstacles feature --- function toggleTeleportPastObstacles(enabled) { const runner = Runner.instance_; if (!runner) return; const dino = runner.tRex; const triggerDistance = 80; // pixels ahead of dino function teleportPastClosestObstacle() { if (!runner.horizon || !runner.horizon.obstacles.length) return false; const obstacles = runner.horizon.obstacles; const dinoX = dino.xPos; let closestObstacle = null; let minDistance = Infinity; for (const obs of obstacles) { const dist = obs.xPos - dinoX; if (dist > 0 && dist < triggerDistance && dist < minDistance) { closestObstacle = obs; minDistance = dist; } } if (!closestObstacle) return false; // Teleport so dino is just past obstacle + buffer const shiftAmount = minDistance + closestObstacle.width + 10; obstacles.forEach(o => { o.xPos -= shiftAmount; }); if (runner.horizon.clouds && runner.horizon.clouds.length) { runner.horizon.clouds.forEach(cloud => { cloud.xPos -= shiftAmount; }); } // Reset dino state to running, cancel jump/duck if any if (dino.jumping || dino.ducking) { dino.jumping = false; dino.ducking = false; dino.update(0, 'RUNNING'); } return true; } function teleportMultipleObstacles() { let teleported; do { teleported = teleportPastClosestObstacle(); } while (teleported); } if (enabled) { teleportInterval = setInterval(() => { teleportMultipleObstacles(); }, 20); } else { clearInterval(teleportInterval); } } // --- Air Jump (Auto Jump on T toggle) --- function toggleAirJump(enabled) { const runner = Runner.instance_; if (!runner || !runner.tRex) return; airJumping = enabled; if (airJumping) { airJumpInterval = setInterval(() => { // Reset jumping state to allow continuous jumping runner.tRex.jumping = false; runner.tRex.startJump(runner.currentSpeed); }, 300); // Adjust interval for speed of auto jump } else { clearInterval(airJumpInterval); airJumpInterval = null; } } // Also listen for 'T' key to toggle Air Jump (independent of mod menu checkbox) document.addEventListener('keydown', function (e) { if (e.key.toLowerCase() === 't') { toggleAirJump(!airJumping); // Update checkbox state in menu if visible const menu = document.getElementById('modMenu'); if (menu) { const labels = menu.getElementsByTagName('label'); for (const label of labels) { if (label.textContent.trim() === 'Air Jump (Auto Jump on T)') { const cb = label.querySelector('input[type="checkbox"]'); if (cb) cb.checked = airJumping; break; } } } } }); // --- Auto Restart & Hats initialization --- const waitForRunner = setInterval(() => { if (Runner.instance_) { clearInterval(waitForRunner); const r = Runner.instance_; const canvas = document.querySelector('canvas'); // Auto-restart setInterval(() => { if (r.crashed) { canvas.focus(); ['keydown','keyup'].forEach(type => { document.dispatchEvent(new KeyboardEvent(type,{ key: ' ', code: 'Space', keyCode: 32, which: 32, bubbles: true })); }); } }, 100); // Hats const hats = ['🎩','👑','⛑️','🧢','🎓']; let idx = 0, hatEl, t=0; function createHat() { hatEl = document.createElement('div'); hatEl.style.cssText = 'position:absolute;font-size:22px;z-index:1000;pointer-events:none;'; document.body.appendChild(hatEl); } function updateHat() { const d = r.tRex; if (!d) return; const rect = r.canvas.getBoundingClientRect(); const x = rect.left + d.xPos + 22; const y = rect.top + d.yPos - 10; const angle = Math.sin(t)*20; t += 0.1; hatEl.style.left = `${x}px`; hatEl.style.top = `${y}px`; hatEl.style.transform = `translate(-50%,-50%) rotate(${angle}deg)`; } function toggleHat() { idx = (idx+1) % hats.length; hatEl.textContent = hats[idx]; } createHat(); document.addEventListener('keydown', e => { if (e.key.toLowerCase()==='h') toggleHat(); }); setInterval(updateHat, 30); } }, 100); // Soccer ball const waitForGame = setInterval(() => { const r = window.Runner?.instance_; if (r && r.tRex && r.canvas) { clearInterval(waitForGame); const canvas = r.canvas; const ball = document.createElement('div'); ball.textContent = '⚽'; ball.style.position = 'absolute'; ball.style.fontSize = '22px'; ball.style.zIndex = 9999; ball.style.pointerEvents = 'none'; document.body.appendChild(ball); let rotation = 0; function updateBallPosition() { const dino = r.tRex; const canvasRect = canvas.getBoundingClientRect(); const dinoX = canvasRect.left + dino.xPos; const dinoY = canvasRect.top + dino.yPos; // 27 pixels higher const ballX = dinoX + 28; const ballY = dinoY + 37; rotation += 10; // Constant rolling ball.style.left = `${ballX}px`; ball.style.top = `${ballY}px`; ball.style.transform = `rotate(${rotation}deg)`; requestAnimationFrame(updateBallPosition); } requestAnimationFrame(updateBallPosition); } }, 100); // --- Canvas Visibility Check & Redirect --- const CHECK_INTERVAL = 1000; const HIDDEN_THRESHOLD = 3; // Number of checks canvas must be missing/hidden before redirect let hiddenCount = 0; function isCanvasVisible(canvas) { if (!canvas) return false; const style = window.getComputedStyle(canvas); if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false; if (canvas.width === 0 || canvas.height === 0) return false; return true; } const interval = setInterval(() => { const canvas = document.querySelector('canvas'); if (!isCanvasVisible(canvas)) { hiddenCount++; if (hiddenCount >= HIDDEN_THRESHOLD) { clearInterval(interval); console.log('[Dino Redirect] Canvas missing or hidden for multiple checks. Redirecting...'); window.location.href = 'https://dino-chrome.com/'; } } else { hiddenCount = 0; // reset if canvas visible again } }, CHECK_INTERVAL); // --- Show Mod Menu --- const checker = setInterval(() => { if (Runner.instance_?.tRex) { clearInterval(checker); createModMenu(); } }, 500); })();