您需要先安装一个扩展,例如 篡改猴、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(); })();