您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Overrides the default game speed and improves reliability of mid and long tick fire rates
// ==UserScript== // @name Evolve-Scab-Worker // @namespace solistus.xyz // @description Overrides the default game speed and improves reliability of mid and long tick fire rates // @match https://pmotschmann.github.io/Evolve* // @version 0.2.1 // @inject-into page // @license MIT // @run-at document-start // ==/UserScript== // TO DO: // (for 1.0) add UI to allow tick speed to be set without using console commands // (for 1.0) clean up debug output and implement debugging flag to toggle on/off easily // (for 1.1?) add option to use vanilla worker messages to set the baseDelay to match vanilla speeds more accurately // (maybe?) add support for a message to alter Ticker ratios, and/or to allow a separate interval to be toggled for just one message type // (maybe?) test other options for the scab script body e.g. a separate included file [mainly for maintainability as editing code stored in a string literal can be a hassle] let baseDelay = 190, scabScript = `let debug = console.debug.bind(console); //replace with ()=>{} to turn off debug output, or e.g. an array's push method to redirect output elsewhere debug('scab worker started') function /* Generator for messages to send from worker to page for game ticks * default params for standard ratios of fast/mid/long. 1 long, (midratio) mids, (midratio*fastratio) fasts per cycle (1/5/20 default). */ * Ticker(fastratio=4, midratio=5) { while(true) { yield "long"; let a = midratio; while(a--){ let b = fastratio; yield "mid"; while(b--) yield "fast"; } }} function pause() { clearInterval(self.messenger); self.messenger = null; debug("worker paused ticks.") } function resume() { clearInterval(self.messenger); self.messenger = setInterval(()=>{self.postMessage(self.ticker.next().value)}, self.delay); debug('worker is now sending ticks.'); } function setDelay(del) { self.delay = del; if(self.messenger) self.resume(); debug('worker delay set to ' + self.delay + (self.messenger ? "ms." : "ms. (game is paused)")); } self.delay = ${baseDelay}, self.ticker = Ticker(), self.messenger = 0; resume(); self.addEventListener('message', ((e)=>{ let loop = e.data.loop ?? e.data, period = Number.parseInt(e.data.period) ?? 0; switch(loop){ case 'clear': case 'pause': pause(); break; case 'short': case 'resume': case 'unpause': case 'play': resume(); break; case 'delay': if(period) setDelay(period); else console.log("worker delay is " + self.delay + (self.messenger?"ms.":"ms (PAUSED).")); break; case 'mid': case 'long': break; default: if(typeof loop == 'number' || loop == Number.parseInt(loop)) setDelay(Number.parseInt(loop)); else { try { debug("worker received unsupported message: ", JSON.stringify(e.data)); } catch { debug("worker received unsupported message, string conversion failed: ", e.data)} } } }));`, scabURL = URL.createObjectURL(new Blob([scabScript], {type:'application/javascript'})); window._Worker = window.Worker; window.scab = { delay: baseDelay, help: function(){ console.info('Supported message contents for scab.worker.postMessage(contents): '); console.info('Vanilla game messages: {loop: <string>, period: <number>}, except loop: mid and loop: long (all three loops are controlled together on loop: short; mid and long messages are ignored). Period is ignored for all vanilla messages; use delay messages (see below) or this.speed() to alter tickrate.'); console.info('String messages (can also send as {loop: <str>}): clear/pause to pause game, short/resume/play to resume, delay to check current delay.'); console.info('Delay setters: {loop: "delay", period: <new delay>}, or simply send the delay as a string/number e.g. scab.worker.postMessage(50). Or, use scab.speed()'); }, speed: function(spd, asmult = true) { if(asmult) spd = Math.ceil(this.delay/spd); window.scab?.worker?.postMessage(spd); } }; window.Worker = class Worker extends window._Worker { constructor(...args) { let isScab = false; if (args[0] == 'evolve/evolve.js') { args[0] = scabURL; isScab = true;} super(...args); if(isScab) window.scab.worker = this; console.debug('Worker(): ', args, this); } }; console.info('Scab worker injected. Access worker at window.scab.worker, set speed with window.scab.speed(delay), or set to a multiple of default rate with *.speed(mult, true)'); console.debug('To see all supported messages for manual sending, call window.scab.help().');