您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds some QoL features, such as always showing kill count, green health bar, etc
当前为
- // ==UserScript==
- // @name Blubbled's UI Mod v2
- // @namespace http://tampermonkey.net/
- // @version 2
- // @description Adds some QoL features, such as always showing kill count, green health bar, etc
- // @author Blubbled
- // @match https://suroi.io/*
- // @grant none
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- function periodicallyShowKillCounter() {
- showKillCounter();
- setTimeout(periodicallyShowKillCounter, 100);
- }
- function showKillCounter() {
- var killCounter = document.getElementById('kill-counter');
- if (killCounter) {
- killCounter.style.display = 'flex';
- killCounter.style.alignItems = 'center';
- var skullIcon = killCounter.querySelector('img');
- if (skullIcon) {
- skullIcon.style.marginRight = '5px';
- }
- var counterText = killCounter.querySelector('.counter-text');
- if (counterText) {
- counterText.style.minWidth = '30px';
- }
- }
- }
- var actionTimer;
- var countdownElement;
- function startActionTimer() {
- var countdownValue = 4;
- countdownElement = document.createElement('div');
- countdownElement.id = 'action-countdown';
- countdownElement.textContent = countdownValue;
- countdownElement.style.position = 'fixed';
- countdownElement.style.top = '50%';
- countdownElement.style.left = '50%';
- countdownElement.style.transform = 'translate(-50%, -170%)';
- countdownElement.style.fontSize = '24px';
- countdownElement.style.fontWeight = 'bold';
- countdownElement.style.color = 'white';
- countdownElement.style.zIndex = '9999';
- document.body.appendChild(countdownElement);
- actionTimer = setInterval(function() {
- countdownValue -= 0.1;
- countdownElement.textContent = countdownValue.toFixed(1);
- if (countdownValue <= 0) {
- clearInterval(actionTimer);
- actionTimer = null;
- countdownElement.parentNode.removeChild(countdownElement);
- }
- }, 100);
- }
- //function handleMouseDown(event) {
- // console.log('Mouse down event detected');
- //
- // if (event.button === 0){
- // var weaponSlot = document.getElementById('weapon-slot-4');
- // if (weaponSlot.classList.contains('active')) {
- // console.log('Starting action timer');
- // startActionTimer();
- // }
- // }
- // }
- // function handleMouseUp(event) {
- // console.log('Mouse up event detected');
- // if (event.button === 0) {
- // if (actionTimer) {
- // console.log('Clearing action timer');
- // clearInterval(actionTimer);
- // actionTimer = null;
- // if (countdownElement) {
- // countdownElement.parentNode.removeChild(countdownElement);
- // countdownElement = null;
- // }
- // }
- // }
- // window.addEventListener('mousedown', handleMouseDown);
- //window.addEventListener('mouseup', handleMouseUp);
- function addAdditionalUI() {
- var additionalText = document.createElement('h1');
- additionalText.textContent = "Technical UI pack by Blubbled ";
- var joinLink = document.createElement('a');
- joinLink.textContent = "[JOIN ZESK]";
- joinLink.href = "https://discord.gg/msNbP9Nt2r";
- joinLink.style.color = 'blue';
- joinLink.style.textDecoration = 'underline';
- joinLink.style.marginLeft = '5px';
- additionalText.appendChild(joinLink);
- additionalText.style.position = 'fixed';
- additionalText.style.top = '10px';
- additionalText.style.right = '10px';
- additionalText.style.color = '#ffffff';
- additionalText.style.zIndex = '9999';
- additionalText.style.display = 'none';
- document.body.appendChild(additionalText);
- var masterVolumeSlider = document.getElementById('slider-master-volume');
- var sfxVolumeSlider = document.getElementById('slider-sfx-volume');
- var musicVolumeSlider = document.getElementById('slider-music-volume');
- var uiScaleSlider = document.getElementById('slider-ui-scale');
- var minimapTransparencySlider = document.getElementById('slider-minimap-transparency');
- var bigMapTransparencySlider = document.getElementById('slider-big-map-transparency');
- if (masterVolumeSlider && sfxVolumeSlider && musicVolumeSlider && uiScaleSlider && minimapTransparencySlider && bigMapTransparencySlider) {
- masterVolumeSlider.step = 0.01;
- sfxVolumeSlider.step = 0.01;
- musicVolumeSlider.step = 0.01;
- uiScaleSlider.step = 0.01;
- minimapTransparencySlider.step = 0.01;
- bigMapTransparencySlider.step = 0.01;
- }
- }
- function replaceWithHeader() {
- var customHeader = document.createElement('h1');
- customHeader.textContent = "Technical UI pack by Blubbled ";
- var joinLink = document.createElement('a');
- joinLink.textContent = "[JOIN ZESK]";
- joinLink.href = "https://discord.gg/msNbP9Nt2r";
- joinLink.style.color = 'blue';
- joinLink.style.textDecoration = 'underline';
- joinLink.style.marginLeft = '5px';
- customHeader.appendChild(joinLink);
- customHeader.style.position = 'fixed';
- customHeader.style.top = '10px';
- customHeader.style.right = '10px';
- customHeader.style.color = '#ffffff';
- customHeader.style.zIndex = '9999';
- var elementToReplace = document.querySelector('a[href="./changelog/"][target="_blank"][rel="noopener noreferrer"]');
- if (elementToReplace) {
- elementToReplace.parentNode.replaceChild(customHeader, elementToReplace);
- }
- }
- var settingsTabsContainer = document.getElementById('settings-tabs-container');
- var modSettingsTabButton = document.createElement('button');
- modSettingsTabButton.className = 'tab';
- modSettingsTabButton.id = 'tab-mod-settings';
- modSettingsTabButton.innerHTML = '<i class="fa-solid fa-gear"></i>Mod Settings';
- settingsTabsContainer.querySelector('#settings-tab-bar').appendChild(modSettingsTabButton);
- var modSettingsTabContent = document.createElement('div');
- modSettingsTabContent.className = 'tab-content';
- modSettingsTabContent.id = 'tab-mod-settings-content';
- modSettingsTabContent.style.display = 'none';
- var modSettingsContent = document.createElement('div');
- modSettingsTabContent.appendChild(modSettingsContent);
- settingsTabsContainer.querySelector('#settings-tabs').appendChild(modSettingsTabContent);
- //player info
- function togglePlayerInfo(enabled) {
- if (enabled) {
- var healthBarPercentageCopy = document.createElement('span');
- healthBarPercentageCopy.id = 'health-bar-percentage-copy';
- healthBarPercentageCopy.classList.add('unselectable');
- healthBarPercentageCopy.style.position = 'fixed';
- healthBarPercentageCopy.style.top = '50%';
- healthBarPercentageCopy.style.left = '46.2%';
- healthBarPercentageCopy.style.transform = 'translate(-50%, -50%)';
- healthBarPercentageCopy.style.fontSize = '20px';
- healthBarPercentageCopy.style.fontWeight = 'bold';
- function updateHealthBarPercentageCopy() {
- var healthBarPercentageValue = document.getElementById('health-bar-percentage').textContent;
- var healthBarColor = document.getElementById('health-bar').style.backgroundColor;
- healthBarPercentageCopy.textContent = healthBarPercentageValue + "➕";
- healthBarPercentageCopy.style.color = healthBarColor;
- }
- healthBarPercentageCopy.style.webkitTouchCallout = 'none'; /* iOS Safari */
- healthBarPercentageCopy.style.webkitUserSelect = 'none'; /* Safari */
- healthBarPercentageCopy.style.userSelect = 'none'; /* Standard syntax */
- updateHealthBarPercentageCopy();
- document.body.appendChild(healthBarPercentageCopy);
- var observer1 = new MutationObserver(updateHealthBarPercentageCopy);
- var targetNode1 = document.getElementById('health-bar-percentage');
- observer1.observe(targetNode1, { childList: true, subtree: true });
- var adrenalineBarPercentageCopy = document.createElement('span');
- adrenalineBarPercentageCopy.id = 'adrenaline-bar-percentage-copy';
- adrenalineBarPercentageCopy.classList.add('unselectable');
- adrenalineBarPercentageCopy.style.position = 'fixed';
- adrenalineBarPercentageCopy.style.top = '50%';
- adrenalineBarPercentageCopy.style.right = '46.2%';
- adrenalineBarPercentageCopy.style.transform = 'translate(50%, -50%)';
- adrenalineBarPercentageCopy.style.fontSize = '20px';
- adrenalineBarPercentageCopy.style.fontWeight = 'bold';
- function updateAdrenalineBarPercentageCopy() {
- var adrenalineBarPercentageValue = document.getElementById('adrenaline-bar-percentage').textContent;
- var adrenalineBarColor = document.getElementById('adrenaline-bar').style.backgroundColor;
- adrenalineBarPercentageCopy.textContent = adrenalineBarPercentageValue + "⚡";
- adrenalineBarPercentageCopy.style.color = adrenalineBarColor;
- }
- adrenalineBarPercentageCopy.style.webkitTouchCallout = 'none'; /* iOS Safari */
- adrenalineBarPercentageCopy.style.webkitUserSelect = 'none'; /* Safari */
- adrenalineBarPercentageCopy.style.userSelect = 'none'; /* Standard syntax */
- updateAdrenalineBarPercentageCopy();
- document.body.appendChild(adrenalineBarPercentageCopy);
- var observer2 = new MutationObserver(updateAdrenalineBarPercentageCopy);
- var targetNode2 = document.getElementById('adrenaline-bar-percentage');
- observer2.observe(targetNode2, { childList: true, subtree: true });
- } else {
- var healthBarPercentageCopy = document.getElementById('health-bar-percentage-copy');
- if (healthBarPercentageCopy) {
- healthBarPercentageCopy.parentNode.removeChild(healthBarPercentageCopy);
- }
- var adrenalineBarPercentageCopy = document.getElementById('adrenaline-bar-percentage-copy');
- if (adrenalineBarPercentageCopy) {
- adrenalineBarPercentageCopy.parentNode.removeChild(adrenalineBarPercentageCopy);
- }
- }
- }
- function createTextDistanceSlider() {
- var slider = document.createElement('input');
- slider.type = 'range';
- slider.min = '-100';
- slider.max = '100';
- slider.value = '0';
- slider.id = 'textDistanceSlider';
- slider.style.position = 'fixed';
- slider.style.top = '26.2%';
- slider.style.left = 'auto';
- slider.style.right = '28.5%';
- slider.style.transform = 'translate(50%, -50%)';
- slider.style.width = '180px';
- slider.addEventListener('input', function() {
- var distance = this.value;
- var healthBarPercentageCopy = document.getElementById('health-bar-percentage-copy');
- var adrenalineBarPercentageCopy = document.getElementById('adrenaline-bar-percentage-copy');
- if (healthBarPercentageCopy && adrenalineBarPercentageCopy) {
- healthBarPercentageCopy.style.left = (46.2 + parseInt(distance)) + '%';
- adrenalineBarPercentageCopy.style.right = (46.2 + parseInt(distance)) + '%';
- }
- });
- return slider;
- }
- var modSettingsContent = document.getElementById('tab-mod-settings-content');
- if (modSettingsContent) {
- var slider = createTextDistanceSlider();
- modSettingsContent.appendChild(slider);
- }
- //text colors
- function createToggleCustomTextColorSetting() {
- var toggleSetting = document.createElement('div');
- toggleSetting.className = 'modal-item';
- toggleSetting.style.marginBottom = '10px';
- toggleSetting.innerHTML = `
- <input type="checkbox" id="toggle-custom-text-color" ${localStorage.getItem('customTextColorEnabled') === 'true' ? 'checked' : ''}>
- <label for="text-color-picker" style="font-weight: bold; margin-left: 0px;">Text Color</label>
- <input type="color" id="text-color-picker" value="${localStorage.getItem('textColor') || '#ffffff'}" style="margin-left: -100px;">
- `;
- toggleSetting.querySelector('#toggle-custom-text-color').addEventListener('change', function() {
- updateCustomTextColorSetting(this.checked);
- });
- toggleSetting.querySelector('#text-color-picker').addEventListener('input', function() {
- updateTextColorSetting(this.value);
- });
- return toggleSetting;
- }
- function updateCustomTextColorSetting(enabled) {
- localStorage.setItem('customTextColorEnabled', enabled);
- if (enabled) {
- applyCustomTextColor();
- } else {
- disableCustomTextColor();
- }
- }
- function applyCustomTextColor() {
- var customTextColor = localStorage.getItem('textColor') || '#ffffff';
- applyTextColor(customTextColor);
- }
- function disableCustomTextColor() {
- var countElements = document.querySelectorAll('.item-count, #fps-counter, #coordinates-hud, #ping-counter');
- countElements.forEach(function(element) {
- element.style.color = '';
- });
- }
- function updateTextColorSetting(color) {
- localStorage.setItem('textColor', color);
- if (localStorage.getItem('customTextColorEnabled') === 'true') {
- applyCustomTextColor();
- }
- }
- function applyTextColor(color) {
- var countElements = document.querySelectorAll('.item-count');
- countElements.forEach(function(element) {
- element.style.color = color;
- });
- var fpsElement = document.getElementById('fps-counter');
- var coordsElement = document.getElementById('coordinates-hud');
- var pingElement = document.getElementById('ping-counter');
- if (fpsElement) {
- fpsElement.style.color = color;
- }
- if (coordsElement) {
- coordsElement.style.color = color;
- }
- if (pingElement) {
- pingElement.style.color = color;
- }
- }
- modSettingsContent.appendChild(createToggleCustomTextColorSetting());
- if (localStorage.getItem('customTextColorEnabled') === 'true') {
- applyCustomTextColor();
- }
- var playerInfoEnabled = localStorage.getItem('playerInfoEnabled') === 'true';
- togglePlayerInfo(playerInfoEnabled);
- function updatePlayerInfoSetting(enabled) {
- localStorage.setItem('playerInfoEnabled', enabled);
- togglePlayerInfo(enabled);
- }
- function createPlayerInfoSetting() {
- var playerInfoSetting = document.createElement('div');
- playerInfoSetting.className = 'modal-item checkbox-setting';
- playerInfoSetting.style.marginBottom = '10px';
- playerInfoSetting.innerHTML = `
- <label>
- <span class="setting-title" style="margin-right: 10px;">Info on Player</span>
- <input type="checkbox" id="toggle-player-info" ${playerInfoEnabled ? 'checked' : ''} style="margin-left: auto; margin-right: -0px; ">
- </label>
- `;
- playerInfoSetting.querySelector('#toggle-player-info').addEventListener('change', function() {
- updatePlayerInfoSetting(this.checked);
- });
- return playerInfoSetting;
- }
- modSettingsContent.appendChild(createPlayerInfoSetting());
- //uncap fps
- function toggleUncappedFPS(enabled) {
- if (enabled) {
- window.requestAnimationFrame = function(callback) {
- return setTimeout(callback, 1);
- };
- } else {
- window.requestAnimationFrame = function(callback) {
- return setTimeout(callback, 1000 / 60);
- };
- }
- }
- var uncappedFPSEnabled = localStorage.getItem('uncappedFPSEnabled') === 'true';
- toggleUncappedFPS(uncappedFPSEnabled);
- function updateUncappedFPSSetting(enabled) {
- localStorage.setItem('uncappedFPSEnabled', enabled);
- toggleUncappedFPS(enabled);
- }
- function createUncappedFPSSetting() {
- var uncappedFPSSetting = document.createElement('div');
- uncappedFPSSetting.className = 'modal-item checkbox-setting';
- uncappedFPSSetting.style.marginBottom = '10px';
- uncappedFPSSetting.innerHTML = `
- <label>
- <span class="setting-title" style="margin-right: 10px;">Uncapped FPS</span>
- <input type="checkbox" id="toggle-uncapped-fps" ${uncappedFPSEnabled ? 'checked' : ''} style="margin-left: auto; margin-right: -0px; ">
- </label>
- `;
- uncappedFPSSetting.querySelector('#toggle-uncapped-fps').addEventListener('change', function() {
- updateUncappedFPSSetting(this.checked);
- });
- return uncappedFPSSetting;
- }
- var gunSwitchDelayMap = {
- "AK-47": 400,
- "ARX-160": 400,
- "AUG": 400,
- "ACR": 400,
- "M3K": 700,
- "Model 37": 900,
- "HP18": 400,
- "Flues": 250,
- "Vepr-12": 650,
- "Mosin-Nagant": 900,
- "Tango 51": 900,
- "CZ-600": 600,
- "Barrett M95": 900,
- "M1895": 250,
- "G19": 250,
- "Radio": 250,
- "CZ-75A": 250,
- "SAF-200": 300,
- "M16A4": 400,
- "Micro Uzi": 300,
- "Vector": 300,
- "PP-19": 300,
- "MP40": 300,
- "MCX Spear": 400,
- "Lewis Gun": 400,
- "Stoner 63": 400,
- "MG5": 400,
- "Negev": 400,
- "MG36": 400,
- "M1 Garand": 400,
- "VSS": 400,
- "SR-25": 400,
- "Mini-14": 400,
- "Model 89": 400,
- "USAS-12": 400,
- "G17 (scoped)": 250,
- "Death Ray": 500,
- "Destroyer Of Worlds": 100
- };
- function startCountdownAbovePlayer(countdownValue) {
- var countdownElement = document.createElement('div');
- countdownElement.id = 'weapon-switch-countdown';
- countdownElement.textContent = countdownValue.toFixed(1);
- countdownElement.style.position = 'fixed';
- countdownElement.style.top = '45%';
- countdownElement.style.left = '50%';
- countdownElement.style.transform = 'translate(-50%, -170%)';
- countdownElement.style.fontSize = '24px';
- countdownElement.style.fontWeight = 'bold';
- countdownElement.style.color = 'white';
- countdownElement.style.zIndex = '9999';
- document.body.appendChild(countdownElement);
- var countdownTimer = setInterval(function() {
- countdownValue -= 0.1;
- countdownElement.textContent = countdownValue.toFixed(1);
- if (countdownValue <= 0) {
- clearInterval(countdownTimer);
- countdownElement.parentNode.removeChild(countdownElement);
- }
- }, 100);
- }
- var countdownActive1 = false;
- var countdownActive2 = false;
- var countdownInterval1;
- var countdownInterval2;
- var lastDetectionTimestamp = 0;
- function detectActiveWeaponAndStartCountdown() {
- var currentTimestamp = Date.now();
- if (currentTimestamp - lastDetectionTimestamp < 10) {
- return;
- }
- lastDetectionTimestamp = currentTimestamp;
- var weaponSlot1 = document.getElementById('weapon-slot-1');
- var weaponSlot2 = document.getElementById('weapon-slot-2');
- if (weaponSlot1 && weaponSlot1.classList.contains('active')) {
- var itemNameElement = weaponSlot1.querySelector('.item-name');
- if (itemNameElement) {
- var itemName = itemNameElement.textContent.trim();
- var switchDelay = gunSwitchDelayMap[itemName];
- if (switchDelay !== undefined) {
- if (!countdownActive1) {
- var countdownValue = switchDelay / 1000;
- startCountdownAbovePlayer(countdownValue);
- countdownActive1 = true;
- } else {
- }
- } else {
- }
- } else {
- }
- } else {
- countdownActive1 = false;
- clearInterval(countdownInterval1);
- }
- if (weaponSlot2 && weaponSlot2.classList.contains('active')) {
- var itemNameElement = weaponSlot2.querySelector('.item-name');
- if (itemNameElement) {
- var itemName = itemNameElement.textContent.trim();
- var switchDelay = gunSwitchDelayMap[itemName];
- if (switchDelay !== undefined) {
- if (!countdownActive2) {
- var countdownValue = switchDelay / 1000;
- startCountdownAbovePlayer(countdownValue);
- countdownActive2 = true;
- } else {
- }
- } else {
- }
- } else {
- }
- } else {
- countdownActive2 = false;
- clearInterval(countdownInterval2);
- }
- }
- setInterval(detectActiveWeaponAndStartCountdown, 1);
- function toggleSwitchDelay(enabled) {
- if (enabled) {
- document.addEventListener('click', detectActiveWeaponAndStartCountdown);
- } else {
- document.removeEventListener('click', detectActiveWeaponAndStartCountdown);
- var existingCountdownElement = document.getElementById('weapon-switch-countdown');
- if (existingCountdownElement) {
- existingCountdownElement.parentNode.removeChild(existingCountdownElement);
- }
- }
- }
- var switchDelayEnabled = localStorage.getItem('switchDelayEnabled') === 'true';
- toggleSwitchDelay(switchDelayEnabled);
- function updateSwitchDelaySetting(enabled) {
- localStorage.setItem('switchDelayEnabled', enabled);
- toggleSwitchDelay(enabled);
- }
- function createSwitchDelaySetting() {
- var switchDelaySetting = document.createElement('div');
- switchDelaySetting.className = 'modal-item checkbox-setting';
- switchDelaySetting.style.marginBottom = '10px';
- switchDelaySetting.innerHTML = `
- <label>
- <span class="setting-title" style="margin-right: 10px;">Enable switchDelay</span>
- <input type="checkbox" id="toggle-switch-delay" ${switchDelayEnabled ? 'checked' : ''} style="margin-left: auto; margin-right: -0px; ">
- </label>
- `;
- switchDelaySetting.querySelector('#toggle-switch-delay').addEventListener('change', function() {
- updateSwitchDelaySetting(this.checked);
- });
- return switchDelaySetting;
- }
- var modSettingsContent = document.getElementById('tab-mod-settings-content');
- if (modSettingsContent) {
- modSettingsContent.appendChild(createSwitchDelaySetting());
- }
- modSettingsContent.appendChild(createUncappedFPSSetting());
- showKillCounter();
- addAdditionalUI();
- createUncappedFPSSetting()
- periodicallyShowKillCounter();
- document.addEventListener('DOMContentLoaded', addAdditionalUI);
- window.addEventListener('popstate', showKillCounter);
- replaceWithHeader();
- })();