Uses a Web Worker to ensure high-precision timing for setInterval and setTimeout.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.org/scripts/552983/1679761/HackTimer%20V1.js
// ==UserScript==
// @license MIT
// @name HackTimer V1
// @namespace HackTimer
// @version 1.0.4.2
// @description Uses a Web Worker to ensure high-precision timing for setInterval and setTimeout.
// @grant none
// ==/UserScript==
(function (workerScript) {
if (!/MSIE 10/i.test(navigator.userAgent)) {
try {
var blob = new Blob([`
var fakeIdToId = {};
onmessage = function (event) {
var data = event.data,
name = data.name,
fakeId = data.fakeId,
time;
if (data.hasOwnProperty('time')) {
time = data.time;
}
switch (name) {
case 'setInterval':
fakeIdToId[fakeId] = setInterval(function () {
postMessage({fakeId: fakeId});
}, time);
break;
case 'clearInterval':
if (fakeIdToId.hasOwnProperty(fakeId)) {
clearInterval(fakeIdToId[fakeId]);
delete fakeIdToId[fakeId];
}
break;
case 'setTimeout':
fakeIdToId[fakeId] = setTimeout(function () {
postMessage({fakeId: fakeId});
if (fakeIdToId.hasOwnProperty(fakeId)) {
delete fakeIdToId[fakeId];
}
}, time);
break;
case 'clearTimeout':
if (fakeIdToId.hasOwnProperty(fakeId)) {
clearTimeout(fakeIdToId[fakeId]);
delete fakeIdToId[fakeId];
}
break;
}
}
`], { type: 'application/javascript' });
workerScript = window.URL.createObjectURL(blob);
} catch (error) {
console.warn('HackTimer: Blob not supported, using external script');
}
}
var worker,
fakeIdToCallback = new Map(),
lastFakeId = 0,
maxFakeId = 0x25FFFFFFFFFFFF, // 64-bit maximum
logPrefix = 'HackTimer: ';
if (typeof Worker !== 'undefined') {
function getFakeId() {
do {
lastFakeId = (lastFakeId === maxFakeId) ? 0 : lastFakeId + 1;
} while (fakeIdToCallback.has(lastFakeId));
return lastFakeId;
}
function executeCallback(fakeId) {
const request = fakeIdToCallback.get(fakeId);
if (!request) return;
const { callback, parameters, isTimeout } = request;
if (isTimeout) {
fakeIdToCallback.delete(fakeId);
}
let callbackFunc = callback;
if (typeof callback === 'string') {
try {
callbackFunc = new Function(callback);
} catch (error) {
console.error(logPrefix + 'Error parsing callback:', error);
return;
}
}
if (typeof callbackFunc === 'function') {
try {
callbackFunc.apply(window, parameters);
} catch (error) {
console.error(logPrefix + 'Error executing callback:', error);
}
}
}
try {
worker = new Worker(workerScript);
const originalSetInterval = window.setInterval;
const originalClearInterval = window.clearInterval;
const originalSetTimeout = window.setTimeout;
const originalClearTimeout = window.clearTimeout;
window.setInterval = function (callback, time, ...parameters) {
const fakeId = getFakeId();
fakeIdToCallback.set(fakeId, {
callback: callback,
parameters: parameters,
isTimeout: false
});
worker.postMessage({
name: 'setInterval',
fakeId: fakeId,
time: Math.max(0, time || 0)
});
return fakeId;
};
window.clearInterval = function (fakeId) {
if (fakeIdToCallback.has(fakeId)) {
fakeIdToCallback.delete(fakeId);
worker.postMessage({
name: 'clearInterval',
fakeId: fakeId
});
}
};
window.setTimeout = function (callback, time, ...parameters) {
const fakeId = getFakeId();
fakeIdToCallback.set(fakeId, {
callback: callback,
parameters: parameters,
isTimeout: true
});
worker.postMessage({
name: 'setTimeout',
fakeId: fakeId,
time: Math.max(0, time || 0)
});
return fakeId;
};
window.clearTimeout = function (fakeId) {
if (fakeIdToCallback.has(fakeId)) {
fakeIdToCallback.delete(fakeId);
worker.postMessage({
name: 'clearTimeout',
fakeId: fakeId
});
}
};
worker.onmessage = function (event) {
const { fakeId } = event.data;
executeCallback(fakeId);
};
worker.onerror = function (event) {
console.error(logPrefix + 'Worker error:', event);
};
} catch (error) {
console.error(logPrefix + 'Initialisation failed:', error);
}
} else {
console.warn(logPrefix + 'Web Workers not supported');
}
})('HackTimerWorker.js');