// ==UserScript==
// @name Hammer Senpa.io Mod - UI Tweaks & Enhancements v2.2
// @namespace http://tampermonkey.net/
// @version 2.2
// @description UI Enhancements for Senpa.io: Draggable UI, Optimization, FX, Blur, Freeze, and Help Button
// @author Hammer
// @match https://senpa.io/*
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
// Global variables
let optimizationEnabled = true;
let fxOn = true;
let isFrozen = false;
let isBlurred = false;
let isDragging = false;
let offsetX, offsetY;
// Default position (bottom-right corner)
const defaultPosition = { top: 'auto', left: 'auto', bottom: '20px', right: '20px' };
// Create the small GUI container (button to show/hide the menu)
const smallGui = document.createElement('div');
smallGui.id = 'small-gui';
Object.assign(smallGui.style, {
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '70px',
height: '50px',
backgroundColor: 'rgba(0, 0, 0, 0.7)',
color: 'white',
textAlign: 'center',
fontSize: '14px',
borderRadius: '5px',
cursor: 'pointer',
zIndex: '9999',
border: '2px solid red'
});
smallGui.innerText = 'Mods';
document.body.appendChild(smallGui);
// Create the GUI menu (hidden by default)
const guiContainer = document.createElement('div');
guiContainer.id = 'gui-container';
Object.assign(guiContainer.style, {
position: 'fixed',
top: '60%',
left: '50%',
transform: 'translateX(-50%)',
width: '250px',
backgroundColor: 'rgba(0, 0, 0, 0.8)',
color: 'white',
padding: '20px',
borderRadius: '10px',
zIndex: '9999',
display: 'none',
fontFamily: 'Arial, sans-serif',
border: '2px solid red'
});
// Create the close button for the menu
const closeButton = document.createElement('button');
closeButton.innerText = 'X';
Object.assign(closeButton.style, {
backgroundColor: '#dc3545',
color: 'white',
border: 'none',
padding: '5px',
borderRadius: '50%',
cursor: 'pointer',
position: 'absolute',
top: '10px',
right: '10px'
});
closeButton.addEventListener('click', () => {
guiContainer.style.display = 'none';
});
// Create the "made by hammer" text
const hammerText = document.createElement('div');
hammerText.innerText = 'made by hammer <3';
Object.assign(hammerText.style, {
color: '#fff',
fontSize: '14px',
textAlign: 'center',
marginTop: '20px',
display: 'none'
});
// Function to create toggle buttons
function createToggleButton(textOn, textOff, initialState, callback) {
const btn = document.createElement('button');
btn.innerText = initialState ? textOff : textOn;
btn.style.backgroundColor = initialState ? '#28a745' : '#dc3545';
btn.style.color = 'white';
btn.style.border = 'none';
btn.style.padding = '10px';
btn.style.borderRadius = '5px';
btn.style.cursor = 'pointer';
btn.style.marginBottom = '10px';
btn.addEventListener('click', () => {
const newState = callback();
btn.innerText = newState ? textOff : textOn;
btn.style.backgroundColor = newState ? '#28a745' : '#dc3545';
});
return btn;
}
// Append elements to the GUI container
guiContainer.appendChild(closeButton);
guiContainer.appendChild(createToggleButton('Enable FPS Optimization', 'Disable FPS Optimization', optimizationEnabled, () => {
optimizationEnabled = !optimizationEnabled;
optimizationEnabled ? enableOptimization() : disableOptimization();
return optimizationEnabled;
}));
guiContainer.appendChild(createToggleButton('Enable FX', 'Disable FX', fxOn, () => {
fxOn = !fxOn;
applyVisualEffects();
return fxOn;
}));
guiContainer.appendChild(createToggleButton('Freeze on Death', 'Unfreeze on Death', isFrozen, () => {
isFrozen = !isFrozen;
return isFrozen;
}));
guiContainer.appendChild(createToggleButton('Enable Background Blur', 'Disable Background Blur', isBlurred, () => {
isBlurred = !isBlurred;
const canvas = document.querySelector('canvas');
if (canvas) {
canvas.style.filter = isBlurred ? 'blur(3px)' : 'none';
}
document.body.style.backdropFilter = isBlurred ? 'blur(2px)' : 'none';
return isBlurred;
}));
guiContainer.appendChild(hammerText);
document.body.appendChild(guiContainer);
// Event to toggle the menu visibility
smallGui.addEventListener('click', () => {
const isHidden = guiContainer.style.display === 'none';
guiContainer.style.display = isHidden ? 'block' : 'none';
hammerText.style.display = isHidden ? 'block' : 'none';
});
// Draggable feature for the small GUI
smallGui.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - parseInt(window.getComputedStyle(smallGui).left);
offsetY = e.clientY - parseInt(window.getComputedStyle(smallGui).top);
smallGui.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
smallGui.style.left = `${e.clientX - offsetX}px`;
smallGui.style.top = `${e.clientY - offsetY}px`;
}
});
document.addEventListener('mouseup', () => {
isDragging = false;
smallGui.style.cursor = 'grab';
savePosition();
});
// Save position of the small GUI box
function savePosition() {
localStorage.setItem('gui-position', JSON.stringify({
left: smallGui.style.left,
top: smallGui.style.top
}));
}
// Restore position from localStorage or set default
function restorePosition() {
const position = JSON.parse(localStorage.getItem('gui-position'));
if (position) {
smallGui.style.left = position.left;
smallGui.style.top = position.top;
} else {
smallGui.style.top = defaultPosition.top;
smallGui.style.left = defaultPosition.left;
smallGui.style.bottom = defaultPosition.bottom;
smallGui.style.right = defaultPosition.right;
}
}
// Apply visual effects like brightness, contrast, etc.
function applyVisualEffects() {
const canvas = document.querySelector('canvas');
if (canvas) {
canvas.style.filter = fxOn ? 'brightness(1.1) contrast(1.2) saturate(1.1)' : 'none';
}
}
// Enable FPS optimization
function enableOptimization() {
document.body.style.backgroundImage = 'none';
document.querySelectorAll('img').forEach(img => img.src = '');
const style = document.createElement('style');
style.innerHTML = `
* {
animation: none !important;
transition: none !important;
box-shadow: none !important;
}
canvas {
image-rendering: optimizeSpeed;
will-change: transform;
}
body, html {
background: #000 !important;
overflow: hidden;
margin: 0;
padding: 0;
}
`;
document.head.appendChild(style);
document.querySelectorAll('audio').forEach(audio => audio.pause());
document.querySelectorAll('.ad, .sidebar, .popup').forEach(ad => ad.remove());
}
// Disable FPS optimization
function disableOptimization() {
const style = document.createElement('style');
style.innerHTML = `
* {
animation: initial !important;
transition: initial !important;
}
`;
document.head.appendChild(style);
}
// Freeze player on death (optional)
function freezeOnDeath() {
if (!isFrozen) return;
const player = document.querySelector('.player');
if (!player) return;
isFrozen = true;
const preventMovement = e => { e.preventDefault(); e.stopPropagation(); };
document.addEventListener('keydown', preventMovement);
document.addEventListener('mousemove', preventMovement);
document.addEventListener('mousedown', preventMovement);
setTimeout(() => {
isFrozen = false;
document.removeEventListener('keydown', preventMovement);
document.removeEventListener('mousemove', preventMovement);
document.removeEventListener('mousedown', preventMovement);
}, 3000);
}
// Observer to reset position after death or when returning to the main menu
const observer = new MutationObserver(() => {
const middleAd = document.querySelector('.middle, .middle-panel, .ad-middle');
if (middleAd) {
middleAd.remove();
}
const inGame = document.querySelector('.player');
if (inGame) {
restorePosition();
}
});
observer.observe(document.body, { childList: true, subtree: true });
// Check for death/game start and adjust UI accordingly
setInterval(() => {
const deathState = document.querySelector('.dead');
if (deathState && isFrozen) {
freezeOnDeath();
}
}, 1000);
// Apply optimization and visual effects on load
if (optimizationEnabled) enableOptimization();
if (fxOn) applyVisualEffects();
})();