// ==UserScript== // @name 通用时间加速器(修复倍率修改) // @namespace http://tampermonkey.net/ // @version 1.7 // @description 修复倍率无法修改问题,确保配置同步 // @author ZMM // @match *://*/* // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; /* ========== 配置持久化 ========== */ const CFG_KEY = '__time_cheat_cfg__'; const defaultCfg = { enabled: false, multiplier: 2 // 默认2倍速 }; let cfg = Object.assign({}, defaultCfg); try { cfg = Object.assign(cfg, JSON.parse(localStorage.getItem(CFG_KEY) || '{}')); } catch (e) { localStorage.removeItem(CFG_KEY); } function saveCfg() { localStorage.setItem(CFG_KEY, JSON.stringify(cfg)); } /* ========== 核心:绝对稳定的时间加速引擎 ========== */ // 1. 保存原始函数(关键:Date.now 必须恢复原始行为) const OrigPerfNow = performance.now.bind(performance); const OrigDateNow = Date.now; // 2. 初始化时间引擎变量 let lastRealPerfTime = OrigPerfNow(); let fakePerfTime = lastRealPerfTime; let timeEngineEnabled = false; // 3. 劫持 performance.now(仅用于游戏逻辑加速) function safePerfNow() { const realNow = OrigPerfNow(); const delta = realNow - lastRealPerfTime; lastRealPerfTime = realNow; // 防止时间跳跃过大(如切后台再切回来) if (delta > 0 && delta < 10000) { // 允许10秒内的跳跃,避免异常重置 if (timeEngineEnabled) { const multiplier = Number(cfg.multiplier) || 1; fakePerfTime += delta * multiplier; } else { fakePerfTime += delta; // 即使没开启,也要让 fakePerfTime 跟上真实时间,避免停滞 } } else { // 跳跃过大,直接对齐真实时间,避免负数 fakePerfTime = realNow; } return fakePerfTime; } // 4. 劫持 Date.now(关键修复:恢复原始行为,不再依赖 performance.now) Date.now = OrigDateNow; // 直接使用原始 Date.now,返回系统当前时间 // 5. 启用/禁用时间引擎 function enableTimeEngine() { timeEngineEnabled = true; performance.now = safePerfNow; // 启用加速 } function disableTimeEngine() { timeEngineEnabled = false; performance.now = OrigPerfNow; // 恢复原始 performance.now } /* ========== 注入 UI:可移动浮窗(彻底修复) ========== */ function injectUI() { try { // 1. 注入CSS样式(确保样式正确加载) const css = document.createElement('style'); css.textContent = ` #time-cheat-btn{ position:fixed; z-index:2147483647; width:42px; height:42px; border-radius:50%; border:2px solid #4CAF50; background:linear-gradient(135deg,#2E7D32 0%,#4CAF50 100%); color:#fff; font:bold 18px/42px sans-serif; text-align:center; cursor:pointer; user-select:none; box-shadow:0 2px 12px rgba(0,0,0,.6); transition:transform .15s,box-shadow .15s; right:16px; top:16px; touch-action:none; } #time-cheat-btn:hover{ transform:scale(1.12); box-shadow:0 0 18px rgba(76,175,80,.5); } #time-cheat-panel{ position:fixed; z-index:2147483646; right:70px; top:16px; width:280px; max-height:90vh; overflow-y:auto; background:rgba(30,30,30,.95); border:1.5px solid #4CAF50; border-radius:10px; box-shadow:0 4px 30px rgba(0,0,0,.7); font:13px/1.5 'Segoe UI',sans-serif; color:#e0e0e0; transition:opacity .2s,transform .2s; transform-origin:top right; } #time-cheat-panel.tc-hidden{ opacity:0; transform:scale(.92); pointer-events:none; } .tc-hd{ display:flex; align-items:center; justify-content:space-between; padding:10px 14px; background:rgba(76,175,80,.12); border-bottom:1px solid rgba(76,175,80,.25); cursor:move; border-radius:10px 10px 0 0; user-select:none; } .tc-hd span{ color:#4CAF50; font-weight:700; font-size:14px; letter-spacing:.5px; } .tc-close{ background:none; border:none; color:#4CAF50; font-size:20px; cursor:pointer; line-height:1; } .tc-close:hover{ color:#fff; } .tc-body{ padding:12px 14px 16px; } .tc-row{ display:flex; align-items:center; justify-content:space-between; margin-bottom:8px; } .tc-row label{ flex:1; color:#bbb; font-size:12px; } .tc-row input[type=number]{ width:100px; padding:4px 8px; border:1px solid rgba(76,175,80,.35); border-radius:5px; background:rgba(0,0,0,.35); color:#e0e0e0; font:13px monospace; outline:none; text-align:right; } .tc-row input[type=number]:focus{ border-color:#4CAF50; box-shadow:0 0 0 2px rgba(76,175,80,.2); } .tc-toggle{ display:flex; align-items:center; gap:8px; margin-bottom:10px; cursor:pointer; } .tc-toggle input{ display:none; } .tc-sw{ position:relative; width:36px; height:20px; border-radius:10px; background:rgba(255,255,255,.12); transition:background .2s; flex-shrink:0; } .tc-sw::after{ content:''; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:#888; transition:transform .2s,background .2s; } .tc-toggle input:checked+.tc-sw{ background:rgba(76,175,80,.35); } .tc-toggle input:checked+.tc-sw::after{ transform:translateX(16px); background:#4CAF50; } .tc-toggle span:last-child{ font-size:12px; color:#bbb; } .tc-sep{ height:1px; background:rgba(76,175,80,.18); margin:10px 0; } .tc-apply{ display:block; width:100%; padding:9px 0; margin-top:6px; border:none; border-radius:6px; cursor:pointer; background:linear-gradient(135deg,#4CAF50,#388E3C); color:#1a1a1a; font:bold 13px sans-serif; letter-spacing:.5px; transition:filter .15s,transform .1s; } .tc-apply:hover{ filter:brightness(1.15); } .tc-apply:active{ transform:scale(.97); } .tc-hint{ text-align:center; font-size:11px; color:#776; margin-top:6px; transition:color .2s; min-height: 16px; } `; document.head.appendChild(css); // 2. 创建浮窗按钮(确保元素正确创建) const btn = document.createElement('div'); btn.id = 'time-cheat-btn'; btn.textContent = '⏩'; btn.title = '时间加速器'; btn.style.cssText = 'position:fixed; z-index:2147483647; width:42px; height:42px; border-radius:50%; border:2px solid #4CAF50; background:linear-gradient(135deg,#2E7D32 0%,#4CAF50 100%); color:#fff; font:bold 18px/42px sans-serif; text-align:center; cursor:pointer; user-select:none; box-shadow:0 2px 12px rgba(0,0,0,.6); transition:transform .15s,box-shadow .15s; right:16px; top:16px; touch-action:none;'; document.body.appendChild(btn); // 3. 创建浮窗面板(确保元素正确创建) const panel = document.createElement('div'); panel.id = 'time-cheat-panel'; panel.classList.add('tc-hidden'); panel.style.cssText = 'position:fixed; z-index:2147483646; right:70px; top:16px; width:280px; max-height:90vh; overflow-y:auto; background:rgba(30,30,30,.95); border:1.5px solid #4CAF50; border-radius:10px; box-shadow:0 4px 30px rgba(0,0,0,.7); font:13px/1.5 \'Segoe UI\',sans-serif; color:#e0e0e0; transition:opacity .2s,transform .2s; transform-origin:top right;'; panel.innerHTML = `