Blubbled's UI Mod v2

Adds some QoL features, such as always showing kill count, green health bar, etc

当前为 2024-05-05 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Blubbled's UI Mod v2
  3. // @namespace http://tampermonkey.net/
  4. // @version 2
  5. // @description Adds some QoL features, such as always showing kill count, green health bar, etc
  6. // @author Blubbled
  7. // @match https://suroi.io/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12.  
  13.  
  14. (function() {
  15.  
  16. 'use strict';
  17.  
  18. function periodicallyShowKillCounter() {
  19. showKillCounter();
  20. setTimeout(periodicallyShowKillCounter, 100);
  21. }
  22.  
  23. function showKillCounter() {
  24. var killCounter = document.getElementById('kill-counter');
  25. if (killCounter) {
  26. killCounter.style.display = 'flex';
  27. killCounter.style.alignItems = 'center';
  28. var skullIcon = killCounter.querySelector('img');
  29. if (skullIcon) {
  30. skullIcon.style.marginRight = '5px';
  31. }
  32. var counterText = killCounter.querySelector('.counter-text');
  33. if (counterText) {
  34. counterText.style.minWidth = '30px';
  35. }
  36. }
  37. }
  38. var actionTimer;
  39. var countdownElement;
  40.  
  41. function startActionTimer() {
  42. var countdownValue = 4;
  43. countdownElement = document.createElement('div');
  44. countdownElement.id = 'action-countdown';
  45. countdownElement.textContent = countdownValue;
  46. countdownElement.style.position = 'fixed';
  47. countdownElement.style.top = '50%';
  48. countdownElement.style.left = '50%';
  49. countdownElement.style.transform = 'translate(-50%, -170%)';
  50. countdownElement.style.fontSize = '24px';
  51. countdownElement.style.fontWeight = 'bold';
  52. countdownElement.style.color = 'white';
  53. countdownElement.style.zIndex = '9999';
  54. document.body.appendChild(countdownElement);
  55.  
  56. actionTimer = setInterval(function() {
  57. countdownValue -= 0.1;
  58. countdownElement.textContent = countdownValue.toFixed(1);
  59. if (countdownValue <= 0) {
  60. clearInterval(actionTimer);
  61. actionTimer = null;
  62.  
  63. countdownElement.parentNode.removeChild(countdownElement);
  64. }
  65. }, 100);
  66. }
  67.  
  68.  
  69.  
  70.  
  71. //function handleMouseDown(event) {
  72. // console.log('Mouse down event detected');
  73. //
  74. // if (event.button === 0){
  75. // var weaponSlot = document.getElementById('weapon-slot-4');
  76. // if (weaponSlot.classList.contains('active')) {
  77. // console.log('Starting action timer');
  78. // startActionTimer();
  79. // }
  80. // }
  81. // }
  82.  
  83.  
  84. // function handleMouseUp(event) {
  85. // console.log('Mouse up event detected');
  86.  
  87. // if (event.button === 0) {
  88.  
  89. // if (actionTimer) {
  90. // console.log('Clearing action timer');
  91. // clearInterval(actionTimer);
  92. // actionTimer = null;
  93.  
  94. // if (countdownElement) {
  95. // countdownElement.parentNode.removeChild(countdownElement);
  96. // countdownElement = null;
  97. // }
  98. // }
  99. // }
  100.  
  101. // window.addEventListener('mousedown', handleMouseDown);
  102. //window.addEventListener('mouseup', handleMouseUp);
  103.  
  104.  
  105. function addAdditionalUI() {
  106. var additionalText = document.createElement('h1');
  107. additionalText.textContent = "Technical UI pack by Blubbled ";
  108. var joinLink = document.createElement('a');
  109. joinLink.textContent = "[JOIN ZESK]";
  110. joinLink.href = "https://discord.gg/msNbP9Nt2r";
  111. joinLink.style.color = 'blue';
  112. joinLink.style.textDecoration = 'underline';
  113. joinLink.style.marginLeft = '5px';
  114. additionalText.appendChild(joinLink);
  115. additionalText.style.position = 'fixed';
  116. additionalText.style.top = '10px';
  117. additionalText.style.right = '10px';
  118. additionalText.style.color = '#ffffff';
  119. additionalText.style.zIndex = '9999';
  120. additionalText.style.display = 'none';
  121. document.body.appendChild(additionalText);
  122.  
  123. var masterVolumeSlider = document.getElementById('slider-master-volume');
  124. var sfxVolumeSlider = document.getElementById('slider-sfx-volume');
  125. var musicVolumeSlider = document.getElementById('slider-music-volume');
  126. var uiScaleSlider = document.getElementById('slider-ui-scale');
  127. var minimapTransparencySlider = document.getElementById('slider-minimap-transparency');
  128. var bigMapTransparencySlider = document.getElementById('slider-big-map-transparency');
  129.  
  130. if (masterVolumeSlider && sfxVolumeSlider && musicVolumeSlider && uiScaleSlider && minimapTransparencySlider && bigMapTransparencySlider) {
  131. masterVolumeSlider.step = 0.01;
  132. sfxVolumeSlider.step = 0.01;
  133. musicVolumeSlider.step = 0.01;
  134. uiScaleSlider.step = 0.01;
  135. minimapTransparencySlider.step = 0.01;
  136. bigMapTransparencySlider.step = 0.01;
  137. }
  138. }
  139.  
  140. function replaceWithHeader() {
  141. var customHeader = document.createElement('h1');
  142. customHeader.textContent = "Technical UI pack by Blubbled ";
  143. var joinLink = document.createElement('a');
  144. joinLink.textContent = "[JOIN ZESK]";
  145. joinLink.href = "https://discord.gg/msNbP9Nt2r";
  146. joinLink.style.color = 'blue';
  147. joinLink.style.textDecoration = 'underline';
  148. joinLink.style.marginLeft = '5px';
  149. customHeader.appendChild(joinLink);
  150. customHeader.style.position = 'fixed';
  151. customHeader.style.top = '10px';
  152. customHeader.style.right = '10px';
  153. customHeader.style.color = '#ffffff';
  154. customHeader.style.zIndex = '9999';
  155. var elementToReplace = document.querySelector('a[href="./changelog/"][target="_blank"][rel="noopener noreferrer"]');
  156. if (elementToReplace) {
  157. elementToReplace.parentNode.replaceChild(customHeader, elementToReplace);
  158. }
  159. }
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166. var settingsTabsContainer = document.getElementById('settings-tabs-container');
  167. var modSettingsTabButton = document.createElement('button');
  168. modSettingsTabButton.className = 'tab';
  169. modSettingsTabButton.id = 'tab-mod-settings';
  170. modSettingsTabButton.innerHTML = '<i class="fa-solid fa-gear"></i>Mod Settings';
  171. settingsTabsContainer.querySelector('#settings-tab-bar').appendChild(modSettingsTabButton);
  172.  
  173. var modSettingsTabContent = document.createElement('div');
  174. modSettingsTabContent.className = 'tab-content';
  175. modSettingsTabContent.id = 'tab-mod-settings-content';
  176. modSettingsTabContent.style.display = 'none';
  177.  
  178. var modSettingsContent = document.createElement('div');
  179.  
  180.  
  181.  
  182.  
  183. modSettingsTabContent.appendChild(modSettingsContent);
  184. settingsTabsContainer.querySelector('#settings-tabs').appendChild(modSettingsTabContent);
  185.  
  186.  
  187.  
  188. //player info
  189. function togglePlayerInfo(enabled) {
  190. if (enabled) {
  191. var healthBarPercentageCopy = document.createElement('span');
  192. healthBarPercentageCopy.id = 'health-bar-percentage-copy';
  193. healthBarPercentageCopy.classList.add('unselectable');
  194. healthBarPercentageCopy.style.position = 'fixed';
  195. healthBarPercentageCopy.style.top = '50%';
  196. healthBarPercentageCopy.style.left = '46.2%';
  197. healthBarPercentageCopy.style.transform = 'translate(-50%, -50%)';
  198. healthBarPercentageCopy.style.fontSize = '20px';
  199. healthBarPercentageCopy.style.fontWeight = 'bold';
  200.  
  201. function updateHealthBarPercentageCopy() {
  202. var healthBarPercentageValue = document.getElementById('health-bar-percentage').textContent;
  203. var healthBarColor = document.getElementById('health-bar').style.backgroundColor;
  204.  
  205. healthBarPercentageCopy.textContent = healthBarPercentageValue + "➕";
  206. healthBarPercentageCopy.style.color = healthBarColor;
  207. }
  208.  
  209. healthBarPercentageCopy.style.webkitTouchCallout = 'none'; /* iOS Safari */
  210. healthBarPercentageCopy.style.webkitUserSelect = 'none'; /* Safari */
  211. healthBarPercentageCopy.style.userSelect = 'none'; /* Standard syntax */
  212.  
  213. updateHealthBarPercentageCopy();
  214. document.body.appendChild(healthBarPercentageCopy);
  215.  
  216. var observer1 = new MutationObserver(updateHealthBarPercentageCopy);
  217. var targetNode1 = document.getElementById('health-bar-percentage');
  218. observer1.observe(targetNode1, { childList: true, subtree: true });
  219.  
  220. var adrenalineBarPercentageCopy = document.createElement('span');
  221. adrenalineBarPercentageCopy.id = 'adrenaline-bar-percentage-copy';
  222. adrenalineBarPercentageCopy.classList.add('unselectable');
  223. adrenalineBarPercentageCopy.style.position = 'fixed';
  224. adrenalineBarPercentageCopy.style.top = '50%';
  225. adrenalineBarPercentageCopy.style.right = '46.2%';
  226. adrenalineBarPercentageCopy.style.transform = 'translate(50%, -50%)';
  227. adrenalineBarPercentageCopy.style.fontSize = '20px';
  228. adrenalineBarPercentageCopy.style.fontWeight = 'bold';
  229.  
  230. function updateAdrenalineBarPercentageCopy() {
  231. var adrenalineBarPercentageValue = document.getElementById('adrenaline-bar-percentage').textContent;
  232. var adrenalineBarColor = document.getElementById('adrenaline-bar').style.backgroundColor;
  233.  
  234. adrenalineBarPercentageCopy.textContent = adrenalineBarPercentageValue + "⚡";
  235. adrenalineBarPercentageCopy.style.color = adrenalineBarColor;
  236. }
  237.  
  238. adrenalineBarPercentageCopy.style.webkitTouchCallout = 'none'; /* iOS Safari */
  239. adrenalineBarPercentageCopy.style.webkitUserSelect = 'none'; /* Safari */
  240. adrenalineBarPercentageCopy.style.userSelect = 'none'; /* Standard syntax */
  241.  
  242. updateAdrenalineBarPercentageCopy();
  243. document.body.appendChild(adrenalineBarPercentageCopy);
  244.  
  245. var observer2 = new MutationObserver(updateAdrenalineBarPercentageCopy);
  246. var targetNode2 = document.getElementById('adrenaline-bar-percentage');
  247. observer2.observe(targetNode2, { childList: true, subtree: true });
  248. } else {
  249. var healthBarPercentageCopy = document.getElementById('health-bar-percentage-copy');
  250. if (healthBarPercentageCopy) {
  251. healthBarPercentageCopy.parentNode.removeChild(healthBarPercentageCopy);
  252. }
  253.  
  254. var adrenalineBarPercentageCopy = document.getElementById('adrenaline-bar-percentage-copy');
  255. if (adrenalineBarPercentageCopy) {
  256. adrenalineBarPercentageCopy.parentNode.removeChild(adrenalineBarPercentageCopy);
  257. }
  258. }
  259. }
  260.  
  261.  
  262. function createTextDistanceSlider() {
  263. var slider = document.createElement('input');
  264. slider.type = 'range';
  265. slider.min = '-100';
  266. slider.max = '100';
  267. slider.value = '0';
  268. slider.id = 'textDistanceSlider';
  269. slider.style.position = 'fixed';
  270. slider.style.top = '26.2%';
  271. slider.style.left = 'auto';
  272. slider.style.right = '28.5%';
  273. slider.style.transform = 'translate(50%, -50%)';
  274. slider.style.width = '180px';
  275. slider.addEventListener('input', function() {
  276. var distance = this.value;
  277. var healthBarPercentageCopy = document.getElementById('health-bar-percentage-copy');
  278. var adrenalineBarPercentageCopy = document.getElementById('adrenaline-bar-percentage-copy');
  279. if (healthBarPercentageCopy && adrenalineBarPercentageCopy) {
  280. healthBarPercentageCopy.style.left = (46.2 + parseInt(distance)) + '%';
  281. adrenalineBarPercentageCopy.style.right = (46.2 + parseInt(distance)) + '%';
  282. }
  283. });
  284.  
  285. return slider;
  286. }
  287.  
  288. var modSettingsContent = document.getElementById('tab-mod-settings-content');
  289. if (modSettingsContent) {
  290. var slider = createTextDistanceSlider();
  291. modSettingsContent.appendChild(slider);
  292. }
  293.  
  294.  
  295. //text colors
  296. function createToggleCustomTextColorSetting() {
  297. var toggleSetting = document.createElement('div');
  298. toggleSetting.className = 'modal-item';
  299. toggleSetting.style.marginBottom = '10px';
  300. toggleSetting.innerHTML = `
  301. <input type="checkbox" id="toggle-custom-text-color" ${localStorage.getItem('customTextColorEnabled') === 'true' ? 'checked' : ''}>
  302. <label for="text-color-picker" style="font-weight: bold; margin-left: 0px;">Text Color</label>
  303. <input type="color" id="text-color-picker" value="${localStorage.getItem('textColor') || '#ffffff'}" style="margin-left: -100px;">
  304.  
  305. `;
  306. toggleSetting.querySelector('#toggle-custom-text-color').addEventListener('change', function() {
  307. updateCustomTextColorSetting(this.checked);
  308. });
  309. toggleSetting.querySelector('#text-color-picker').addEventListener('input', function() {
  310. updateTextColorSetting(this.value);
  311. });
  312. return toggleSetting;
  313. }
  314.  
  315. function updateCustomTextColorSetting(enabled) {
  316. localStorage.setItem('customTextColorEnabled', enabled);
  317. if (enabled) {
  318. applyCustomTextColor();
  319. } else {
  320. disableCustomTextColor();
  321. }
  322. }
  323.  
  324. function applyCustomTextColor() {
  325. var customTextColor = localStorage.getItem('textColor') || '#ffffff';
  326. applyTextColor(customTextColor);
  327. }
  328.  
  329. function disableCustomTextColor() {
  330. var countElements = document.querySelectorAll('.item-count, #fps-counter, #coordinates-hud, #ping-counter');
  331. countElements.forEach(function(element) {
  332. element.style.color = '';
  333. });
  334. }
  335.  
  336. function updateTextColorSetting(color) {
  337. localStorage.setItem('textColor', color);
  338. if (localStorage.getItem('customTextColorEnabled') === 'true') {
  339. applyCustomTextColor();
  340. }
  341. }
  342.  
  343. function applyTextColor(color) {
  344. var countElements = document.querySelectorAll('.item-count');
  345. countElements.forEach(function(element) {
  346. element.style.color = color;
  347. });
  348.  
  349. var fpsElement = document.getElementById('fps-counter');
  350. var coordsElement = document.getElementById('coordinates-hud');
  351. var pingElement = document.getElementById('ping-counter');
  352.  
  353. if (fpsElement) {
  354. fpsElement.style.color = color;
  355. }
  356.  
  357. if (coordsElement) {
  358. coordsElement.style.color = color;
  359. }
  360.  
  361. if (pingElement) {
  362. pingElement.style.color = color;
  363. }
  364. }
  365.  
  366. modSettingsContent.appendChild(createToggleCustomTextColorSetting());
  367. if (localStorage.getItem('customTextColorEnabled') === 'true') {
  368. applyCustomTextColor();
  369. }
  370.  
  371.  
  372. var playerInfoEnabled = localStorage.getItem('playerInfoEnabled') === 'true';
  373. togglePlayerInfo(playerInfoEnabled);
  374.  
  375. function updatePlayerInfoSetting(enabled) {
  376. localStorage.setItem('playerInfoEnabled', enabled);
  377. togglePlayerInfo(enabled);
  378. }
  379.  
  380.  
  381. function createPlayerInfoSetting() {
  382. var playerInfoSetting = document.createElement('div');
  383. playerInfoSetting.className = 'modal-item checkbox-setting';
  384. playerInfoSetting.style.marginBottom = '10px';
  385. playerInfoSetting.innerHTML = `
  386. <label>
  387. <span class="setting-title" style="margin-right: 10px;">Info on Player</span>
  388. <input type="checkbox" id="toggle-player-info" ${playerInfoEnabled ? 'checked' : ''} style="margin-left: auto; margin-right: -0px; ">
  389. </label>
  390. `;
  391. playerInfoSetting.querySelector('#toggle-player-info').addEventListener('change', function() {
  392. updatePlayerInfoSetting(this.checked);
  393. });
  394. return playerInfoSetting;
  395. }
  396.  
  397. modSettingsContent.appendChild(createPlayerInfoSetting());
  398.  
  399. //uncap fps
  400. function toggleUncappedFPS(enabled) {
  401. if (enabled) {
  402. window.requestAnimationFrame = function(callback) {
  403. return setTimeout(callback, 1);
  404. };
  405. } else {
  406. window.requestAnimationFrame = function(callback) {
  407. return setTimeout(callback, 1000 / 60);
  408. };
  409. }
  410. }
  411.  
  412.  
  413. var uncappedFPSEnabled = localStorage.getItem('uncappedFPSEnabled') === 'true';
  414. toggleUncappedFPS(uncappedFPSEnabled);
  415.  
  416.  
  417. function updateUncappedFPSSetting(enabled) {
  418. localStorage.setItem('uncappedFPSEnabled', enabled);
  419. toggleUncappedFPS(enabled);
  420. }
  421.  
  422.  
  423. function createUncappedFPSSetting() {
  424. var uncappedFPSSetting = document.createElement('div');
  425. uncappedFPSSetting.className = 'modal-item checkbox-setting';
  426. uncappedFPSSetting.style.marginBottom = '10px';
  427. uncappedFPSSetting.innerHTML = `
  428. <label>
  429. <span class="setting-title" style="margin-right: 10px;">Uncapped FPS</span>
  430. <input type="checkbox" id="toggle-uncapped-fps" ${uncappedFPSEnabled ? 'checked' : ''} style="margin-left: auto; margin-right: -0px; ">
  431. </label>
  432. `;
  433. uncappedFPSSetting.querySelector('#toggle-uncapped-fps').addEventListener('change', function() {
  434. updateUncappedFPSSetting(this.checked);
  435. });
  436. return uncappedFPSSetting;
  437. }
  438.  
  439. var gunSwitchDelayMap = {
  440. "AK-47": 400,
  441. "ARX-160": 400,
  442. "AUG": 400,
  443. "ACR": 400,
  444. "M3K": 700,
  445. "Model 37": 900,
  446. "HP18": 400,
  447. "Flues": 250,
  448. "Vepr-12": 650,
  449. "Mosin-Nagant": 900,
  450. "Tango 51": 900,
  451. "CZ-600": 600,
  452. "Barrett M95": 900,
  453. "M1895": 250,
  454. "G19": 250,
  455. "Radio": 250,
  456. "CZ-75A": 250,
  457. "SAF-200": 300,
  458. "M16A4": 400,
  459. "Micro Uzi": 300,
  460. "Vector": 300,
  461. "PP-19": 300,
  462. "MP40": 300,
  463. "MCX Spear": 400,
  464. "Lewis Gun": 400,
  465. "Stoner 63": 400,
  466. "MG5": 400,
  467. "Negev": 400,
  468. "MG36": 400,
  469. "M1 Garand": 400,
  470. "VSS": 400,
  471. "SR-25": 400,
  472. "Mini-14": 400,
  473. "Model 89": 400,
  474. "USAS-12": 400,
  475. "G17 (scoped)": 250,
  476. "Death Ray": 500,
  477. "Destroyer Of Worlds": 100
  478. };
  479.  
  480.  
  481.  
  482. function startCountdownAbovePlayer(countdownValue) {
  483. var countdownElement = document.createElement('div');
  484. countdownElement.id = 'weapon-switch-countdown';
  485. countdownElement.textContent = countdownValue.toFixed(1);
  486. countdownElement.style.position = 'fixed';
  487. countdownElement.style.top = '45%';
  488. countdownElement.style.left = '50%';
  489. countdownElement.style.transform = 'translate(-50%, -170%)';
  490. countdownElement.style.fontSize = '24px';
  491. countdownElement.style.fontWeight = 'bold';
  492. countdownElement.style.color = 'white';
  493. countdownElement.style.zIndex = '9999';
  494. document.body.appendChild(countdownElement);
  495.  
  496. var countdownTimer = setInterval(function() {
  497. countdownValue -= 0.1;
  498. countdownElement.textContent = countdownValue.toFixed(1);
  499. if (countdownValue <= 0) {
  500. clearInterval(countdownTimer);
  501. countdownElement.parentNode.removeChild(countdownElement);
  502. }
  503. }, 100);
  504. }
  505.  
  506. var countdownActive1 = false;
  507. var countdownActive2 = false;
  508. var countdownInterval1;
  509. var countdownInterval2;
  510. var lastDetectionTimestamp = 0;
  511.  
  512. function detectActiveWeaponAndStartCountdown() {
  513.  
  514. var currentTimestamp = Date.now();
  515.  
  516. if (currentTimestamp - lastDetectionTimestamp < 10) {
  517. return;
  518. }
  519.  
  520. lastDetectionTimestamp = currentTimestamp;
  521.  
  522. var weaponSlot1 = document.getElementById('weapon-slot-1');
  523. var weaponSlot2 = document.getElementById('weapon-slot-2');
  524.  
  525. if (weaponSlot1 && weaponSlot1.classList.contains('active')) {
  526. var itemNameElement = weaponSlot1.querySelector('.item-name');
  527. if (itemNameElement) {
  528. var itemName = itemNameElement.textContent.trim();
  529. var switchDelay = gunSwitchDelayMap[itemName];
  530. if (switchDelay !== undefined) {
  531. if (!countdownActive1) {
  532. var countdownValue = switchDelay / 1000;
  533. startCountdownAbovePlayer(countdownValue);
  534. countdownActive1 = true;
  535. } else {
  536. }
  537. } else {
  538. }
  539. } else {
  540. }
  541. } else {
  542. countdownActive1 = false;
  543. clearInterval(countdownInterval1);
  544. }
  545.  
  546. if (weaponSlot2 && weaponSlot2.classList.contains('active')) {
  547. var itemNameElement = weaponSlot2.querySelector('.item-name');
  548. if (itemNameElement) {
  549. var itemName = itemNameElement.textContent.trim();
  550. var switchDelay = gunSwitchDelayMap[itemName];
  551. if (switchDelay !== undefined) {
  552. if (!countdownActive2) {
  553. var countdownValue = switchDelay / 1000;
  554. startCountdownAbovePlayer(countdownValue);
  555. countdownActive2 = true;
  556. } else {
  557. }
  558. } else {
  559. }
  560. } else {
  561. }
  562. } else {
  563. countdownActive2 = false;
  564. clearInterval(countdownInterval2);
  565. }
  566. }
  567.  
  568. setInterval(detectActiveWeaponAndStartCountdown, 1);
  569.  
  570. function toggleSwitchDelay(enabled) {
  571. if (enabled) {
  572. document.addEventListener('click', detectActiveWeaponAndStartCountdown);
  573. } else {
  574.  
  575. document.removeEventListener('click', detectActiveWeaponAndStartCountdown);
  576. var existingCountdownElement = document.getElementById('weapon-switch-countdown');
  577. if (existingCountdownElement) {
  578. existingCountdownElement.parentNode.removeChild(existingCountdownElement);
  579. }
  580. }
  581. }
  582.  
  583. var switchDelayEnabled = localStorage.getItem('switchDelayEnabled') === 'true';
  584.  
  585.  
  586. toggleSwitchDelay(switchDelayEnabled);
  587.  
  588.  
  589. function updateSwitchDelaySetting(enabled) {
  590. localStorage.setItem('switchDelayEnabled', enabled);
  591. toggleSwitchDelay(enabled);
  592. }
  593.  
  594.  
  595. function createSwitchDelaySetting() {
  596. var switchDelaySetting = document.createElement('div');
  597. switchDelaySetting.className = 'modal-item checkbox-setting';
  598. switchDelaySetting.style.marginBottom = '10px';
  599. switchDelaySetting.innerHTML = `
  600. <label>
  601. <span class="setting-title" style="margin-right: 10px;">Enable switchDelay</span>
  602. <input type="checkbox" id="toggle-switch-delay" ${switchDelayEnabled ? 'checked' : ''} style="margin-left: auto; margin-right: -0px; ">
  603. </label>
  604. `;
  605. switchDelaySetting.querySelector('#toggle-switch-delay').addEventListener('change', function() {
  606. updateSwitchDelaySetting(this.checked);
  607. });
  608. return switchDelaySetting;
  609. }
  610.  
  611. var modSettingsContent = document.getElementById('tab-mod-settings-content');
  612. if (modSettingsContent) {
  613. modSettingsContent.appendChild(createSwitchDelaySetting());
  614. }
  615.  
  616.  
  617.  
  618. modSettingsContent.appendChild(createUncappedFPSSetting());
  619.  
  620. showKillCounter();
  621. addAdditionalUI();
  622.  
  623. createUncappedFPSSetting()
  624.  
  625.  
  626.  
  627.  
  628.  
  629. periodicallyShowKillCounter();
  630. document.addEventListener('DOMContentLoaded', addAdditionalUI);
  631. window.addEventListener('popstate', showKillCounter);
  632. replaceWithHeader();
  633. })();