HTML5 Universal Speed Hack PLUS với menu vuông kéo thả
// ==UserScript==
// @name HUSH+ Control Panel
// @namespace http://tampermonkey.net/
// @version 2.0
// @description HTML5 Universal Speed Hack PLUS với menu vuông kéo thả
// @author Dựa trên HUSH+
// @match *://88bet.hiphop/*
// @match *://rt.ccvgame.mobi/*
// @match *://*/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
// --- Cấu hình mặc định ---
const defaultConfig = {
speed: GM_getValue("hush-speed", 1.0),
cbSetIntervalChecked: GM_getValue("hush-si", true),
cbSetTimeoutChecked: GM_getValue("hush-st", true),
cbPerformanceNowChecked: GM_getValue("hush-pn", true),
cbDateNowChecked: GM_getValue("hush-dn", true),
cbRequestAnimationFrameChecked: GM_getValue("hush-raf", false)
};
// ==================== PHẦN 1: CORE LOGIC (TỪ contentScript.js) ====================
function pageScript() {
let speedConfig = {
speed: 1.0,
cbSetIntervalChecked: true,
cbSetTimeoutChecked: true,
cbPerformanceNowChecked: true,
cbDateNowChecked: true,
cbRequestAnimationFrameChecked: false,
};
const emptyFunction = () => {};
const originalClearInterval = window.clearInterval;
const originalclearTimeout = window.clearTimeout;
const originalSetInterval = window.setInterval;
const originalSetTimeout = window.setTimeout;
const originalPerformanceNow = window.performance.now.bind(
window.performance
);
const originalDateNow = Date.now;
const originalRequestAnimationFrame = window.requestAnimationFrame;
let timers = [];
const reloadTimers = () => {
console.log(timers);
const newtimers = [];
timers.forEach((timer) => {
originalClearInterval(timer.id);
if (timer.customTimerId) {
originalClearInterval(timer.customTimerId);
}
if (!timer.finished) {
const newTimerId = originalSetInterval(
timer.handler,
speedConfig.cbSetIntervalChecked
? timer.timeout / speedConfig.speed
: timer.timeout,
...timer.args
);
timer.customTimerId = newTimerId;
newtimers.push(timer);
}
});
timers = newtimers;
};
window.addEventListener("message", (e) => {
if (e.data.command === "setSpeedConfig") {
speedConfig = e.data.config;
reloadTimers();
}
});
window.postMessage({ command: "getSpeedConfig" });
window.clearInterval = (id) => {
originalClearInterval(id);
timers.forEach((timer) => {
if (timer.id == id) {
timer.finished = true;
if (timer.customTimerId) {
originalClearInterval(timer.customTimerId);
}
}
});
};
window.clearTimeout = (id) => {
originalclearTimeout(id);
timers.forEach((timer) => {
if (timer.id == id) {
timer.finished = true;
if (timer.customTimerId) {
originalclearTimeout(timer.customTimerId);
}
}
});
};
window.setInterval = (handler, timeout, ...args) => {
console.log("timeout ", timeout);
if (!timeout) timeout = 0;
const id = originalSetInterval(
handler,
speedConfig.cbSetIntervalChecked ? timeout / speedConfig.speed : timeout,
...args
);
timers.push({
id: id,
handler: handler,
timeout: timeout,
args: args,
finished: false,
customTimerId: null,
});
return id;
};
window.setTimeout = (handler, timeout, ...args) => {
if (!timeout) timeout = 0;
return originalSetTimeout(
handler,
speedConfig.cbSetTimeoutChecked ? timeout / speedConfig.speed : timeout,
...args
);
};
// performance.now
(function () {
let performanceNowValue = null;
let previusPerformanceNowValue = null;
window.performance.now = () => {
const originalValue = originalPerformanceNow();
if (performanceNowValue) {
performanceNowValue +=
(originalValue - previusPerformanceNowValue) *
(speedConfig.cbPerformanceNowChecked ? speedConfig.speed : 1);
} else {
performanceNowValue = originalValue;
}
previusPerformanceNowValue = originalValue;
return Math.floor(performanceNowValue);
};
})();
// Date.now
(function () {
let dateNowValue = null;
let previusDateNowValue = null;
Date.now = () => {
const originalValue = originalDateNow();
if (dateNowValue) {
dateNowValue +=
(originalValue - previusDateNowValue) *
(speedConfig.cbDateNowChecked ? speedConfig.speed : 1);
} else {
dateNowValue = originalValue;
}
previusDateNowValue = originalValue;
return Math.floor(dateNowValue);
};
})();
// requestAnimationFrame
(function () {
let dateNowValue = null;
let previusDateNowValue = null;
const callbackFunctions = [];
const callbackTick = [];
const newRequestAnimationFrame = (callback) => {
return originalRequestAnimationFrame((timestamp) => {
const originalValue = originalDateNow();
if (dateNowValue) {
dateNowValue +=
(originalValue - previusDateNowValue) *
(speedConfig.cbRequestAnimationFrameChecked
? speedConfig.speed
: 1);
} else {
dateNowValue = originalValue;
}
previusDateNowValue = originalValue;
const dateNowValue_MathFloor = Math.floor(dateNowValue);
const index = callbackFunctions.indexOf(callback);
let tickFrame = null;
if (index == -1) {
callbackFunctions.push(callback);
callbackTick.push(0);
callback(dateNowValue_MathFloor);
} else if (speedConfig.cbRequestAnimationFrameChecked) {
tickFrame = callbackTick[index];
tickFrame += speedConfig.speed;
if (tickFrame >= 1) {
while (tickFrame >= 1) {
callback(dateNowValue_MathFloor);
window.requestAnimationFrame = emptyFunction;
tickFrame -= 1;
}
window.requestAnimationFrame = newRequestAnimationFrame;
} else {
window.requestAnimationFrame(callback);
}
callbackTick[index] = tickFrame;
} else {
callback(dateNowValue_MathFloor);
}
});
};
window.requestAnimationFrame = newRequestAnimationFrame;
})();
}
// Hàm chèn pageScript vào trang web
function injectScript() {
const script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.textContent = `!${pageScript.toString()}()\n//# sourceURL=pageScript.js`;
document.documentElement.appendChild(script);
}
// ==================== KẾT THÚC PHẦN 1 ====================
// Chạy injectScript ngay lập tức
injectScript();
// --- Cấu hình và lưu trữ ---
let speedConfig = {
speed: GM_getValue("hush-speed", 1.0),
cbSetIntervalChecked: GM_getValue("hush-si", true),
cbSetTimeoutChecked: GM_getValue("hush-st", true),
cbPerformanceNowChecked: GM_getValue("hush-pn", true),
cbDateNowChecked: GM_getValue("hush-dn", true),
cbRequestAnimationFrameChecked: GM_getValue("hush-raf", false)
};
// Lắng nghe yêu cầu cấu hình từ pageScript
window.addEventListener("message", (e) => {
if (e.data.command === "getSpeedConfig") {
window.postMessage({
command: "setSpeedConfig",
config: speedConfig,
}, "*");
}
});
// Gửi cấu hình mới đến pageScript và lưu lại
function updateConfig(newConfig) {
for (let key in newConfig) {
if (newConfig.hasOwnProperty(key)) {
speedConfig[key] = newConfig[key];
}
}
window.postMessage({
command: "setSpeedConfig",
config: speedConfig,
}, "*");
GM_setValue("hush-speed", speedConfig.speed);
GM_setValue("hush-si", speedConfig.cbSetIntervalChecked);
GM_setValue("hush-st", speedConfig.cbSetTimeoutChecked);
GM_setValue("hush-pn", speedConfig.cbPerformanceNowChecked);
GM_setValue("hush-dn", speedConfig.cbDateNowChecked);
GM_setValue("hush-raf", speedConfig.cbRequestAnimationFrameChecked);
}
// ==================== TẠO GIAO DIỆN MENU VUÔNG ====================
// Thêm CSS
GM_addStyle(`
/* Menu vuông nhỏ */
#hush-square-menu {
position: fixed;
top: 20px;
right: 20px;
width: 50px;
height: 50px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0,0,0,0.3);
cursor: move;
z-index: 999998;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
font-weight: bold;
transition: transform 0.2s;
user-select: none;
border: 2px solid rgba(255,255,255,0.2);
}
#hush-square-menu:hover {
transform: scale(1.05);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}
/* Bảng điều khiển chính */
#hush-control-panel {
position: fixed;
top: 80px;
right: 20px;
width: 300px;
background: white;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
z-index: 999999;
display: none;
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
border: 1px solid #e0e0e0;
backdrop-filter: blur(10px);
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
#hush-control-panel.show {
display: block;
}
/* Header của bảng */
.hush-panel-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px;
font-weight: bold;
font-size: 16px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: move;
}
.hush-panel-header span {
display: flex;
align-items: center;
gap: 8px;
}
.hush-close-btn {
background: rgba(255,255,255,0.2);
border: none;
color: white;
width: 24px;
height: 24px;
border-radius: 6px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
transition: background 0.2s;
}
.hush-close-btn:hover {
background: rgba(255,255,255,0.3);
}
/* Nội dung bảng */
.hush-panel-content {
padding: 20px;
background: white;
}
/* Slider */
.hush-slider-container {
margin-bottom: 20px;
}
.hush-slider-label {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
color: #333;
font-weight: 500;
}
.hush-speed-value {
color: #667eea;
font-weight: bold;
}
.hush-slider {
width: 100%;
height: 6px;
border-radius: 3px;
background: #e0e0e0;
outline: none;
-webkit-appearance: none;
}
.hush-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #667eea;
cursor: pointer;
box-shadow: 0 2px 6px rgba(102,126,234,0.4);
transition: transform 0.1s;
}
.hush-slider::-webkit-slider-thumb:hover {
transform: scale(1.1);
}
.hush-minimap {
display: flex;
justify-content: space-between;
margin-top: 6px;
color: #999;
font-size: 10px;
padding: 0 2px;
}
/* Checkbox group */
.hush-checkbox-group {
display: flex;
flex-direction: column;
gap: 12px;
}
.hush-checkbox-group label {
display: flex;
align-items: center;
gap: 10px;
color: #444;
cursor: pointer;
font-size: 14px;
padding: 4px 0;
}
.hush-checkbox-group input[type="checkbox"] {
width: 18px;
height: 18px;
cursor: pointer;
accent-color: #667eea;
}
/* Footer */
.hush-panel-footer {
padding: 15px 20px;
background: #f8f9fa;
border-top: 1px solid #e0e0e0;
font-size: 12px;
color: #666;
text-align: center;
}
/* Trạng thái active cho menu */
#hush-square-menu.active {
background: linear-gradient(135deg, #5a67d8 0%, #6b46a1 100%);
box-shadow: 0 0 20px rgba(102,126,234,0.6);
}
`);
// Tạo menu vuông
const squareMenu = document.createElement('div');
squareMenu.id = 'hush-square-menu';
squareMenu.innerHTML = '⚡';
squareMenu.title = 'HUSH+ Speed Control';
// Tạo bảng điều khiển
const controlPanel = document.createElement('div');
controlPanel.id = 'hush-control-panel';
controlPanel.innerHTML = `
<div class="hush-panel-header" id="hush-panel-header">
<span>
<span>⚡</span>
HUSH+ Speed Control
</span>
<button class="hush-close-btn" id="hush-close-btn">✕</button>
</div>
<div class="hush-panel-content">
<div class="hush-slider-container">
<div class="hush-slider-label">
<span>Tốc độ</span>
<span class="hush-speed-value" id="hush-speed-display">${speedConfig.speed.toFixed(2)}x</span>
</div>
<input type="range" class="hush-slider" id="hush-speed-slider"
min="0.05" max="25" step="0.05" value="${speedConfig.speed}">
<div class="hush-minimap">
<span>0x</span><span>5x</span><span>10x</span><span>15x</span><span>20x</span><span>25x</span>
</div>
</div>
<div class="hush-checkbox-group">
<label>
<input type="checkbox" id="cb-si" ${speedConfig.cbSetIntervalChecked ? 'checked' : ''}>
<span>Override setInterval</span>
</label>
<label>
<input type="checkbox" id="cb-st" ${speedConfig.cbSetTimeoutChecked ? 'checked' : ''}>
<span>Override setTimeout</span>
</label>
<label>
<input type="checkbox" id="cb-pn" ${speedConfig.cbPerformanceNowChecked ? 'checked' : ''}>
<span>Override performance.now</span>
</label>
<label>
<input type="checkbox" id="cb-dn" ${speedConfig.cbDateNowChecked ? 'checked' : ''}>
<span>Override Date.now</span>
</label>
<label>
<input type="checkbox" id="cb-raf" ${speedConfig.cbRequestAnimationFrameChecked ? 'checked' : ''}>
<span>Override requestAnimationFrame</span>
</label>
</div>
</div>
<div class="hush-panel-footer">
Click ⚡ để mở/đóng • Kéo để di chuyển
</div>
`;
// Thêm vào body khi trang đã sẵn sàng
if (document.body) {
document.body.appendChild(squareMenu);
document.body.appendChild(controlPanel);
} else {
window.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(squareMenu);
document.body.appendChild(controlPanel);
});
}
// ==================== KẾT NỐI SỰ KIỆN ====================
const speedSlider = document.getElementById('hush-speed-slider');
const speedDisplay = document.getElementById('hush-speed-display');
const cbSi = document.getElementById('cb-si');
const cbSt = document.getElementById('cb-st');
const cbPn = document.getElementById('cb-pn');
const cbDn = document.getElementById('cb-dn');
const cbRaf = document.getElementById('cb-raf');
const closeBtn = document.getElementById('hush-close-btn');
// Xử lý mở/đóng bảng
squareMenu.addEventListener('click', (e) => {
e.stopPropagation();
controlPanel.classList.toggle('show');
squareMenu.classList.toggle('active');
});
// Nút đóng
closeBtn.addEventListener('click', (e) => {
e.stopPropagation();
controlPanel.classList.remove('show');
squareMenu.classList.remove('active');
});
// Click outside để đóng
document.addEventListener('click', (e) => {
if (!controlPanel.contains(e.target) && !squareMenu.contains(e.target)) {
controlPanel.classList.remove('show');
squareMenu.classList.remove('active');
}
});
// Hàm gửi cập nhật từ UI
function sendUpdateFromUI() {
const newConfig = {
speed: parseFloat(speedSlider.value),
cbSetIntervalChecked: cbSi.checked,
cbSetTimeoutChecked: cbSt.checked,
cbPerformanceNowChecked: cbPn.checked,
cbDateNowChecked: cbDn.checked,
cbRequestAnimationFrameChecked: cbRaf.checked,
};
speedDisplay.textContent = newConfig.speed.toFixed(2) + 'x';
updateConfig(newConfig);
}
speedSlider.addEventListener('input', sendUpdateFromUI);
cbSi.addEventListener('change', sendUpdateFromUI);
cbSt.addEventListener('change', sendUpdateFromUI);
cbPn.addEventListener('change', sendUpdateFromUI);
cbDn.addEventListener('change', sendUpdateFromUI);
cbRaf.addEventListener('change', sendUpdateFromUI);
// ==================== TÍNH NĂNG KÉO THẢ ====================
// Kéo menu vuông
let isDraggingSquare = false;
let squareOffsetX, squareOffsetY;
squareMenu.addEventListener('mousedown', (e) => {
if (e.target === squareMenu) {
isDraggingSquare = true;
squareOffsetX = e.clientX - squareMenu.offsetLeft;
squareOffsetY = e.clientY - squareMenu.offsetTop;
squareMenu.style.cursor = 'grabbing';
e.preventDefault();
}
});
// Kéo bảng điều khiển (qua header)
let isDraggingPanel = false;
let panelOffsetX, panelOffsetY;
const panelHeader = document.getElementById('hush-panel-header');
panelHeader.addEventListener('mousedown', (e) => {
isDraggingPanel = true;
panelOffsetX = e.clientX - controlPanel.offsetLeft;
panelOffsetY = e.clientY - controlPanel.offsetTop;
panelHeader.style.cursor = 'grabbing';
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (isDraggingSquare) {
const newLeft = e.clientX - squareOffsetX;
const newTop = e.clientY - squareOffsetY;
// Giới hạn trong viewport
squareMenu.style.left = Math.max(0, Math.min(window.innerWidth - squareMenu.offsetWidth, newLeft)) + 'px';
squareMenu.style.top = Math.max(0, Math.min(window.innerHeight - squareMenu.offsetHeight, newTop)) + 'px';
squareMenu.style.right = 'auto';
}
if (isDraggingPanel) {
const newLeft = e.clientX - panelOffsetX;
const newTop = e.clientY - panelOffsetY;
controlPanel.style.left = Math.max(0, Math.min(window.innerWidth - controlPanel.offsetWidth, newLeft)) + 'px';
controlPanel.style.top = Math.max(0, Math.min(window.innerHeight - controlPanel.offsetHeight, newTop)) + 'px';
controlPanel.style.right = 'auto';
}
});
document.addEventListener('mouseup', () => {
if (isDraggingSquare) {
isDraggingSquare = false;
squareMenu.style.cursor = 'move';
}
if (isDraggingPanel) {
isDraggingPanel = false;
panelHeader.style.cursor = 'move';
}
});
// Chặn kéo thả ảnh hưởng đến các sự kiện khác
squareMenu.addEventListener('dragstart', (e) => e.preventDefault());
panelHeader.addEventListener('dragstart', (e) => e.preventDefault());
})();