// ==UserScript== // @name Cocos Unity WebGL 速度修改器 // @name:en Cocos Unity WebGL Speed Controller // @namespace Violentmonkey Scripts // @match *://*/* // @run-at document-start // @grant none // @version 1.2 // @author BigWater // @license MIT // @description 为 Cocos2dx 和 Unity WebGL 页面启用速度控制功能, 帮你跳过太长的动画. // @description:en Enable speed control for Cocos2dx and Unity WebGL pages to help you skip overly long animations. // @downloadURL https://update.greasyfork.icu/scripts/556741/Cocos%20Unity%20WebGL%20%E9%80%9F%E5%BA%A6%E4%BF%AE%E6%94%B9%E5%99%A8.user.js // @updateURL https://update.greasyfork.icu/scripts/556741/Cocos%20Unity%20WebGL%20%E9%80%9F%E5%BA%A6%E4%BF%AE%E6%94%B9%E5%99%A8.meta.js // ==/UserScript== (function() { 'use strict'; // =============================== // Cocos and Unity detection // =============================== function isCocos() { // Global namespace if (window.cc || window.cocos2d || window.__ccGlobal) return true; // Script name patterns const scripts = [...document.scripts].map(s => s.src); if (scripts.some(src => /cocos2d|cocos|project\.js|settings\.js/i.test(src))) { return true; } return false; } function isUnity() { if (window.createUnityInstance || window.UnityLoader) return true; const scripts = [...document.scripts].map(s => s.src); if (scripts.some(src => /UnityLoader|\.framework\.js|\.data|\.wasm|build\.json/i.test(src))) { return true; } // Canvas detection if (document.querySelector('#unity-container, #unity-canvas')) return true; return false; } // =============================== // Configuration // =============================== let speedMultiplier = 1.0; const MIN = 0.1; const MAX = 32.0; // =============================== // Hook requestAnimationFrame // =============================== const originalRAF = window.requestAnimationFrame.bind(window); const callbackMap = new Map(); let nextId = 1; window.requestAnimationFrame = function(callback) { const id = nextId++; const wrapped = function(timestamp) { const scaled = timestamp * speedMultiplier; callback(scaled); callbackMap.delete(id); }; callbackMap.set(id, wrapped); return originalRAF(wrapped); }; // =============================== // Hook performance.now // =============================== if (performance && typeof performance.now === 'function') { const originalNow = performance.now.bind(performance); const baseReal = originalNow(); const baseFake = baseReal; performance.now = function() { const real = originalNow(); return baseFake + (real - baseReal) * speedMultiplier; }; } // =============================== // Create Floating UI Panel // =============================== function createUI() { // skip if not cocos or unity if (!isCocos() && !isUnity()) return; const panel = document.createElement('div'); panel.id = 'speedhack-panel'; panel.style.cssText = ` position: fixed; top: 20px; left: 20px; z-index: 999999; background: rgba(0,0,0,0.75); color: #fff; padding: 10px; border-radius: 8px; font-family: sans-serif; font-size: 14px; user-select: none; width: 160px; cursor: move; `; panel.innerHTML = `