您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Controls FPS and lessens Delay
// ==UserScript== // @name Evades.io FPS Cap Controller // @namespace http://tampermonkey.net/ // @version 1.0 // @description Controls FPS and lessens Delay // @author JimmyJimmy // @match *://*.evades.io/* // @match *://evades.io/* // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; // Configuration const DEFAULT_FPS = 60; // Default FPS cap const FPS_PRESETS = [30, 60, 120, 144, 240, 0]; // 0 means uncapped // Wait for game to load const checkGameLoaded = setInterval(function() { if (typeof window.requestAnimationFrame !== 'undefined') { clearInterval(checkGameLoaded); initFPSController(); } }, 1000); function initFPSController() { // Variables to control FPS let targetFPS = DEFAULT_FPS; let fpsCapEnabled = true; let lastFrameTime = 0; let frameDelay = 1000 / targetFPS; // Store the original requestAnimationFrame const originalRAF = window.requestAnimationFrame; // Create UI for FPS control createFPSControlUI(); // Override requestAnimationFrame window.requestAnimationFrame = function(callback) { if (!fpsCapEnabled || targetFPS === 0) { // If cap is disabled or set to 0 (uncapped), use original RAF return originalRAF(callback); } const currentTime = performance.now(); const timeUntilNextFrame = Math.max(0, frameDelay - (currentTime - lastFrameTime)); return setTimeout(function() { lastFrameTime = performance.now(); callback(lastFrameTime); }, timeUntilNextFrame); }; // Functions to update FPS settings function setFPS(fps) { targetFPS = fps; frameDelay = targetFPS > 0 ? 1000 / targetFPS : 0; updateFPSDisplay(); // Save to localStorage localStorage.setItem('evades_custom_fps', fps); } function toggleFPSCap() { fpsCapEnabled = !fpsCapEnabled; updateFPSDisplay(); // Save to localStorage localStorage.setItem('evades_fps_cap_enabled', fpsCapEnabled ? '1' : '0'); } // Load saved settings const savedFPS = localStorage.getItem('evades_custom_fps'); const savedCapEnabled = localStorage.getItem('evades_fps_cap_enabled'); if (savedFPS) setFPS(parseInt(savedFPS)); if (savedCapEnabled) fpsCapEnabled = savedCapEnabled === '1'; // Create UI elements function createFPSControlUI() { const controlPanel = document.createElement('div'); controlPanel.id = 'fps-control-panel'; controlPanel.style.cssText = ` position: fixed; top: 10px; right: 10px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 10px; border-radius: 5px; z-index: 10000; font-family: Arial, sans-serif; user-select: none; display: flex; flex-direction: column; gap: 5px; `; const fpsDisplay = document.createElement('div'); fpsDisplay.id = 'fps-display'; controlPanel.appendChild(fpsDisplay); const toggleButton = document.createElement('button'); toggleButton.textContent = 'Toggle FPS Cap'; toggleButton.onclick = toggleFPSCap; toggleButton.style.cssText = ` padding: 5px; margin-top: 5px; cursor: pointer; `; controlPanel.appendChild(toggleButton); const customFpsInput = document.createElement('input'); customFpsInput.type = 'number'; customFpsInput.min = '1'; customFpsInput.placeholder = 'Custom FPS'; customFpsInput.style.cssText = ` width: 100%; padding: 5px; margin-top: 5px; `; customFpsInput.onchange = function() { const customFps = parseInt(this.value); if (customFps > 0) setFPS(customFps); }; controlPanel.appendChild(customFpsInput); const presetContainer = document.createElement('div'); presetContainer.style.cssText = ` display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; `; FPS_PRESETS.forEach(fps => { const presetButton = document.createElement('button'); presetButton.textContent = fps === 0 ? 'Uncap' : fps + ' FPS'; presetButton.onclick = function() { setFPS(fps); }; presetButton.style.cssText = ` flex: 1; min-width: 60px; padding: 3px; cursor: pointer; `; presetContainer.appendChild(presetButton); }); controlPanel.appendChild(presetContainer); // Add minimize button const minimizeBtn = document.createElement('button'); minimizeBtn.textContent = '−'; minimizeBtn.style.cssText = ` position: absolute; top: 5px; right: 5px; width: 20px; height: 20px; padding: 0; display: flex; align-items: center; justify-content: center; cursor: pointer; background: none; border: none; color: white; font-size: 16px; `; let minimized = false; const contentElements = [fpsDisplay, toggleButton, customFpsInput, presetContainer]; minimizeBtn.onclick = function() { minimized = !minimized; minimizeBtn.textContent = minimized ? '+' : '−'; contentElements.forEach(el => { el.style.display = minimized ? 'none' : ''; }); if (minimized) { controlPanel.style.padding = '5px 25px 5px 10px'; } else { controlPanel.style.padding = '10px'; } }; controlPanel.appendChild(minimizeBtn); document.body.appendChild(controlPanel); // Initial update updateFPSDisplay(); } function updateFPSDisplay() { const display = document.getElementById('fps-display'); if (display) { display.textContent = `FPS Cap: ${fpsCapEnabled ? (targetFPS === 0 ? 'Uncapped' : targetFPS) : 'Disabled'}`; display.style.color = fpsCapEnabled ? '#8ff' : '#f88'; } } // Add accurate actual FPS counter using game loop detection let frameTimestamps = []; let actualFps = 0; // Create FPS display element const fpsCounter = document.createElement('div'); fpsCounter.id = 'actual-fps-display'; fpsCounter.style.cssText = ` position: fixed; top: 0px; left: 0px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 0px 0px; border-radius: 0px; z-index: 10000; font-family: Arial, sans-serif; `; fpsCounter.textContent = `Actual FPS: 0`; document.body.appendChild(fpsCounter); // Hook into the game's rendering cycle const originalDate = Date.now; const originalPerformanceNow = performance.now; // Create a more accurate frame counter by intercepting game loop timing functions function monitorGameFrames() { // Track canvas drawing operations const originalGetContext = HTMLCanvasElement.prototype.getContext; HTMLCanvasElement.prototype.getContext = function() { const context = originalGetContext.apply(this, arguments); if (arguments[0] === '2d' && context) { const originalDrawImage = context.drawImage; context.drawImage = function() { recordFrame(); return originalDrawImage.apply(this, arguments); }; const originalFillRect = context.fillRect; context.fillRect = function() { recordFrame(); return originalFillRect.apply(this, arguments); }; const originalClearRect = context.clearRect; context.clearRect = function() { recordFrame(); return originalClearRect.apply(this, arguments); }; } return context; }; // Monitor WebGL rendering too const originalRenderingContextClear = WebGLRenderingContext.prototype.clear; WebGLRenderingContext.prototype.clear = function() { recordFrame(); return originalRenderingContextClear.apply(this, arguments); }; if (typeof WebGL2RenderingContext !== 'undefined') { const originalWebGL2ContextClear = WebGL2RenderingContext.prototype.clear; WebGL2RenderingContext.prototype.clear = function() { recordFrame(); return originalWebGL2ContextClear.apply(this, arguments); }; } } // Record frame and calculate FPS function recordFrame() { const now = originalPerformanceNow.call(performance); frameTimestamps.push(now); // Keep only frames from the last second while (frameTimestamps.length > 0 && now - frameTimestamps[0] > 1000) { frameTimestamps.shift(); } // Calculate FPS based on number of frames in the last second actualFps = frameTimestamps.length; // Update display at most 10 times per second to avoid performance issues if (Math.floor(now / 100) !== Math.floor((now - 16) / 100)) { fpsCounter.textContent = `Actual FPS: ${actualFps}`; } } // Start monitoring monitorGameFrames(); console.log('[Evades.io FPS Cap Controller] Initialized'); } })();