Opacity

A mod to toggle visibility settings in Bonk.io using BonkHUD

  1. // ==UserScript==
  2. // @name Opacity
  3. // @version 2.3.0
  4. // @description A mod to toggle visibility settings in Bonk.io using BonkHUD
  5. // @author FeiFei + Blu
  6. // @match https://bonk.io/gameframe-release.html
  7. // @run-at document-end
  8. // @grant none
  9. // @namespace https://greasyfork.org/users/1366475
  10. // ==/UserScript==
  11.  
  12. "use strict";
  13.  
  14. window.opacity = {};
  15.  
  16. opacity.windowConfigs = {
  17. windowName: "Opacity",
  18. windowId: "opacity_window",
  19. modVersion: "2.3.0",
  20. bonkLIBVersion: "1.1.3",
  21. bonkVersion: "49",
  22. windowContent: null,
  23. };
  24.  
  25. // Initialize default settings
  26. opacity.defaultSettings = {
  27. players: {
  28. skins: true,
  29. visible: true,
  30. alpha: 1,
  31. usernames: {
  32. visible: true,
  33. alpha: 1,
  34. },
  35. teamOutline: {
  36. visible: true,
  37. alpha: 1,
  38. },
  39. },
  40. chat: {
  41. visible: true,
  42. alpha: 1,
  43. },
  44. };
  45.  
  46. // Initialize settings
  47. opacity.settings = JSON.parse(JSON.stringify(opacity.defaultSettings));
  48.  
  49. // Function to save settings to localStorage
  50. opacity.saveSettings = function () {
  51. localStorage.setItem('opacitySettings', JSON.stringify(this.settings));
  52. };
  53.  
  54. // Function to load settings from localStorage
  55. opacity.loadSettings = function () {
  56. const savedSettings = localStorage.getItem('opacitySettings');
  57. if (savedSettings) {
  58. try {
  59. this.settings = JSON.parse(savedSettings);
  60. } catch (e) {
  61. console.error('Failed to parse saved settings:', e);
  62. this.settings = JSON.parse(JSON.stringify(this.defaultSettings));
  63. }
  64. }
  65. };
  66.  
  67. // Create the mod window using BonkHUD
  68. opacity.createWindow = function () {
  69. // Create the window using BonkHUD
  70. const modIndex = bonkHUD.createMod(this.windowConfigs.windowName, this.windowConfigs);
  71.  
  72. let opacityWindow = bonkHUD.getElementByIndex(modIndex);
  73.  
  74. opacityWindow.style.padding = "0"; // Example: set padding
  75. opacityWindow.style.width = "100%"; // Example: set width to match padding
  76. opacityWindow.style.height = "calc(100% - 32px)"; // Example: set height to match padding and header
  77.  
  78. // Load UI settings if available
  79. bonkHUD.loadUISetting(modIndex);
  80. };
  81.  
  82. opacity.setWindowContent = function () {
  83. // Get current settings values
  84. const playersSkinsChecked = this.settings.players.skins ? "checked" : "";
  85. const playersVisibleChecked = this.settings.players.visible ? "checked" : "";
  86. const playersAlphaValue = this.settings.players.alpha * 100;
  87. const usernamesVisibleChecked = this.settings.players.usernames.visible ? "checked" : "";
  88. const usernamesAlphaValue = this.settings.players.usernames.alpha * 100;
  89. const teamOutlineVisibleChecked = this.settings.players.teamOutline.visible ? "checked" : "";
  90. const teamOutlineAlphaValue = this.settings.players.teamOutline.alpha * 100;
  91. const chatVisibleChecked = this.settings.chat.visible ? "checked" : "";
  92. const chatAlphaValue = this.settings.chat.alpha * 100;
  93.  
  94. let windowHTML = document.createElement("div");
  95.  
  96. let playersButtonDiv = document.createElement("div");
  97. playersButtonDiv.classList.add("bonkhud-header-color");
  98. playersButtonDiv.classList.add("bonkhud-title-color");
  99. playersButtonDiv.style.borderBottomLeftRadius = "8px";
  100. playersButtonDiv.style.borderBottomRightRadius = "8px";
  101. playersButtonDiv.style.padding = "5px";
  102.  
  103. let playersLabel = document.createElement("span");
  104. playersLabel.textContent = "Players";
  105.  
  106. playersButtonDiv.appendChild(playersLabel);
  107.  
  108. let playersDropDiv = bonkHUD.generateSection();
  109. playersDropDiv.style.paddingTop = "2px";
  110.  
  111. //----------------------------------------------
  112.  
  113. let playersSkinsDiv = document.createElement("div");
  114. playersSkinsDiv.style.marginTop = "5px";
  115.  
  116. let playersSkinsLabel = document.createElement("label");
  117. playersSkinsLabel.classList.add("bonkhud-text-color");
  118. playersSkinsLabel.classList.add("bonkhud-settings-label");
  119. playersSkinsLabel.style.marginRight = "5px";
  120. playersSkinsLabel.textContent = "Skins";
  121.  
  122. let playersSkinsCheckbox = document.createElement("input");
  123. playersSkinsCheckbox.type = "checkbox";
  124. playersSkinsCheckbox.checked = playersSkinsChecked;
  125. playersSkinsCheckbox.onchange = (e) => {
  126. window.opacity.settings.players.skins = e.target.checked;
  127. window.opacity.saveSettings();
  128. };
  129.  
  130. playersSkinsDiv.appendChild(playersSkinsLabel);
  131. playersSkinsDiv.appendChild(playersSkinsCheckbox);
  132.  
  133. //---------------------------------------------
  134.  
  135. let playersVisibleDiv = document.createElement("div");
  136. playersVisibleDiv.style.marginTop = "5px";
  137.  
  138. let playersVisibleLabel = document.createElement("label");
  139. playersVisibleLabel.classList.add("bonkhud-text-color");
  140. playersVisibleLabel.classList.add("bonkhud-settings-label");
  141. playersVisibleLabel.style.marginRight = "5px";
  142. playersVisibleLabel.textContent = "Visible";
  143.  
  144. let playersVisibleCheckbox = document.createElement("input");
  145. playersVisibleCheckbox.type = "checkbox";
  146. playersVisibleCheckbox.checked = playersVisibleChecked;
  147. playersVisibleCheckbox.onchange = (e) => {
  148. window.opacity.settings.players.visible = e.target.checked;
  149. window.opacity.saveSettings();
  150. };
  151.  
  152. playersVisibleDiv.appendChild(playersVisibleLabel);
  153. playersVisibleDiv.appendChild(playersVisibleCheckbox);
  154.  
  155. //-------------------------------------------------
  156. let playersAlphaDiv = document.createElement("div");
  157. playersAlphaDiv.style.marginTop = "5px";
  158. playersAlphaDiv.style.display = "flex";
  159. playersAlphaDiv.style.alignContent = "center";
  160.  
  161. let playersAlphaLabel = document.createElement("label");
  162. playersAlphaLabel.classList.add("bonkhud-settings-label");
  163. playersAlphaLabel.textContent = "Opacity";
  164.  
  165. let playersAlphaSlider = document.createElement("input");
  166. playersAlphaSlider.type = "range"; // Slider type for range selection
  167. playersAlphaSlider.min = "0"; // Minimum opacity value
  168. playersAlphaSlider.max = "100"; // Maximum opacity value (fully opaque)
  169. playersAlphaSlider.value = playersAlphaValue; // Default value set to fully opaque
  170. playersAlphaSlider.style.minWidth = "0";
  171. playersAlphaSlider.style.flexGrow = "1";
  172. playersAlphaSlider.style.marginLeft = "0.5rem";
  173. playersAlphaSlider.oninput = (e) => {
  174. window.opacity.settings.players.alpha = e.target.value/100;
  175. window.opacity.saveSettings();
  176. };
  177.  
  178. playersAlphaDiv.appendChild(playersAlphaLabel);
  179. playersAlphaDiv.appendChild(playersAlphaSlider);
  180.  
  181. playersDropDiv.appendChild(playersSkinsDiv);
  182. playersDropDiv.appendChild(playersVisibleDiv);
  183. playersDropDiv.appendChild(playersAlphaDiv);
  184.  
  185. let usernamesButtonDiv = document.createElement("div");
  186. usernamesButtonDiv.classList.add("bonkhud-header-color");
  187. usernamesButtonDiv.classList.add("bonkhud-title-color");
  188. usernamesButtonDiv.style.borderBottomLeftRadius = "8px";
  189. usernamesButtonDiv.style.borderBottomRightRadius = "8px";
  190. usernamesButtonDiv.style.padding = "5px";
  191.  
  192. let usernamesLabel = document.createElement("span");
  193. usernamesLabel.textContent = "Usernames";
  194.  
  195. usernamesButtonDiv.appendChild(usernamesLabel);
  196.  
  197. let usernamesDropDiv = bonkHUD.generateSection();
  198. usernamesDropDiv.style.paddingTop = "2px";
  199.  
  200. //----------------------------------------------
  201.  
  202. let usernamesVisDiv = document.createElement("div");
  203. usernamesVisDiv.style.marginTop = "5px";
  204.  
  205. let usernamesVisLabel = document.createElement("label");
  206. usernamesVisLabel.classList.add("bonkhud-text-color");
  207. usernamesVisLabel.classList.add("bonkhud-settings-label");
  208. usernamesVisLabel.style.marginRight = "5px";
  209. usernamesVisLabel.textContent = "Visible";
  210.  
  211. let usernamesVisCheckbox = document.createElement("input");
  212. usernamesVisCheckbox.type = "checkbox";
  213. usernamesVisCheckbox.checked = usernamesVisibleChecked;
  214. usernamesVisCheckbox.onchange = (e) => {
  215. window.opacity.settings.players.usernames.visible = e.target.checked;
  216. window.opacity.saveSettings();
  217. };
  218.  
  219. usernamesVisDiv.appendChild(usernamesVisLabel);
  220. usernamesVisDiv.appendChild(usernamesVisCheckbox);
  221.  
  222. //-------------------------------------------------
  223. let usernamesAlphaDiv = document.createElement("div");
  224. usernamesAlphaDiv.style.marginTop = "5px";
  225. usernamesAlphaDiv.style.display = "flex";
  226. usernamesAlphaDiv.style.alignContent = "center";
  227.  
  228. let usernamesAlphaLabel = document.createElement("label");
  229. usernamesAlphaLabel.classList.add("bonkhud-settings-label");
  230. usernamesAlphaLabel.textContent = "Opacity";
  231.  
  232. let usernamesAlphaSlider = document.createElement("input");
  233. usernamesAlphaSlider.type = "range"; // Slider type for range selection
  234. usernamesAlphaSlider.min = "0"; // Minimum opacity value
  235. usernamesAlphaSlider.max = "100"; // Maximum opacity value (fully opaque)
  236. usernamesAlphaSlider.value = usernamesAlphaValue; // Default value set to fully opaque
  237. usernamesAlphaSlider.style.minWidth = "0";
  238. usernamesAlphaSlider.style.flexGrow = "1";
  239. usernamesAlphaSlider.style.marginLeft = "0.5rem";
  240. usernamesAlphaSlider.oninput = (e) => {
  241. window.opacity.settings.players.usernames.alpha = e.target.value/100;
  242. window.opacity.saveSettings();
  243. };
  244.  
  245. usernamesAlphaDiv.appendChild(usernamesAlphaLabel);
  246. usernamesAlphaDiv.appendChild(usernamesAlphaSlider);
  247.  
  248. usernamesDropDiv.appendChild(usernamesVisDiv);
  249. usernamesDropDiv.appendChild(usernamesAlphaDiv);
  250.  
  251. //:::::::::::::::::::::::::::::::::::::::::::::::::
  252.  
  253. let teamButtonDiv = document.createElement("div");
  254. teamButtonDiv.classList.add("bonkhud-header-color");
  255. teamButtonDiv.classList.add("bonkhud-title-color");
  256. teamButtonDiv.style.borderBottomLeftRadius = "8px";
  257. teamButtonDiv.style.borderBottomRightRadius = "8px";
  258. teamButtonDiv.style.padding = "5px";
  259.  
  260. let teamLabel = document.createElement("span");
  261. teamLabel.textContent = "Team Outline";
  262.  
  263. teamButtonDiv.appendChild(teamLabel);
  264.  
  265. let teamDropDiv = bonkHUD.generateSection();
  266. teamDropDiv.style.paddingTop = "2px";
  267.  
  268. //----------------------------------------------
  269.  
  270. let teamVisDiv = document.createElement("div");
  271. teamVisDiv.style.marginTop = "5px";
  272.  
  273. let teamVisLabel = document.createElement("label");
  274. teamVisLabel.classList.add("bonkhud-text-color");
  275. teamVisLabel.classList.add("bonkhud-settings-label");
  276. teamVisLabel.style.marginRight = "5px";
  277. teamVisLabel.textContent = "Visible";
  278.  
  279. let teamVisCheckbox = document.createElement("input");
  280. teamVisCheckbox.type = "checkbox";
  281. teamVisCheckbox.checked = teamOutlineVisibleChecked;
  282. teamVisCheckbox.onchange = (e) => {
  283. window.opacity.settings.players.teamOutline.visible = e.target.checked;
  284. window.opacity.saveSettings();
  285. };
  286.  
  287. teamVisDiv.appendChild(teamVisLabel);
  288. teamVisDiv.appendChild(teamVisCheckbox);
  289.  
  290. //-------------------------------------------------
  291. let teamAlphaDiv = document.createElement("div");
  292. teamAlphaDiv.style.marginTop = "5px";
  293. teamAlphaDiv.style.display = "flex";
  294. teamAlphaDiv.style.alignContent = "center";
  295.  
  296. let teamAlphaLabel = document.createElement("label");
  297. teamAlphaLabel.classList.add("bonkhud-settings-label");
  298. teamAlphaLabel.textContent = "Opacity";
  299.  
  300. let teamAlphaSlider = document.createElement("input");
  301. teamAlphaSlider.type = "range"; // Slider type for range selection
  302. teamAlphaSlider.min = "0"; // Minimum opacity value
  303. teamAlphaSlider.max = "100"; // Maximum opacity value (fully opaque)
  304. teamAlphaSlider.value = teamOutlineAlphaValue; // Default value set to fully opaque
  305. teamAlphaSlider.style.minWidth = "0";
  306. teamAlphaSlider.style.flexGrow = "1";
  307. teamAlphaSlider.style.marginLeft = "0.5rem";
  308. teamAlphaSlider.oninput = (e) => {
  309. window.opacity.settings.players.teamOutline.alpha = e.target.value/100;
  310. window.opacity.saveSettings();
  311. };
  312.  
  313. teamAlphaDiv.appendChild(teamAlphaLabel);
  314. teamAlphaDiv.appendChild(teamAlphaSlider);
  315.  
  316. teamDropDiv.appendChild(teamVisDiv);
  317. teamDropDiv.appendChild(teamAlphaDiv);
  318.  
  319. //:::::::::::::::::::::::::::::::::::::::::::::::::
  320.  
  321. let chatButtonDiv = document.createElement("div");
  322. chatButtonDiv.classList.add("bonkhud-header-color");
  323. chatButtonDiv.classList.add("bonkhud-title-color");
  324. chatButtonDiv.style.borderBottomLeftRadius = "8px";
  325. chatButtonDiv.style.borderBottomRightRadius = "8px";
  326. chatButtonDiv.style.padding = "5px";
  327.  
  328. let chatLabel = document.createElement("span");
  329. chatLabel.textContent = "Chat";
  330.  
  331. chatButtonDiv.appendChild(chatLabel);
  332.  
  333. let chatDropDiv = bonkHUD.generateSection();
  334. chatDropDiv.style.paddingTop = "2px";
  335.  
  336. //----------------------------------------------
  337.  
  338. let chatVisDiv = document.createElement("div");
  339. chatVisDiv.style.marginTop = "5px";
  340.  
  341. let chatVisLabel = document.createElement("label");
  342. chatVisLabel.classList.add("bonkhud-text-color");
  343. chatVisLabel.classList.add("bonkhud-settings-label");
  344. chatVisLabel.style.marginRight = "5px";
  345. chatVisLabel.textContent = "Visible";
  346.  
  347. let chatVisCheckbox = document.createElement("input");
  348. chatVisCheckbox.type = "checkbox";
  349. chatVisCheckbox.checked = chatVisibleChecked;
  350. chatVisCheckbox.onchange = (e) => {
  351. window.opacity.settings.chat.visible = e.target.checked;
  352. if (window.opacity.chatWindow) {
  353. window.opacity.chatWindow.style.opacity = window.opacity.settings.chat.visible ? 1 : 0;
  354. }
  355. window.opacity.saveSettings();
  356. };
  357.  
  358. chatVisDiv.appendChild(chatVisLabel);
  359. chatVisDiv.appendChild(chatVisCheckbox);
  360.  
  361. //-------------------------------------------------
  362. let chatAlphaDiv = document.createElement("div");
  363. chatAlphaDiv.style.marginTop = "5px";
  364. chatAlphaDiv.style.display = "flex";
  365. chatAlphaDiv.style.alignContent = "center";
  366.  
  367. let chatAlphaLabel = document.createElement("label");
  368. chatAlphaLabel.classList.add("bonkhud-settings-label");
  369. chatAlphaLabel.textContent = "Opacity";
  370.  
  371. let chatAlphaSlider = document.createElement("input");
  372. chatAlphaSlider.type = "range"; // Slider type for range selection
  373. chatAlphaSlider.min = "0"; // Minimum opacity value
  374. chatAlphaSlider.max = "100"; // Maximum opacity value (fully opaque)
  375. chatAlphaSlider.value = chatAlphaValue; // Default value set to fully opaque
  376. chatAlphaSlider.style.minWidth = "0";
  377. chatAlphaSlider.style.flexGrow = "1";
  378. chatAlphaSlider.style.marginLeft = "0.5rem";
  379. chatAlphaSlider.oninput = (e) => {
  380. window.opacity.settings.chat.alpha = e.target.value/100;
  381. if (window.opacity.chatWindow) {
  382. window.opacity.chatWindow.style.opacity = window.opacity.settings.chat.alpha;
  383. }
  384. window.opacity.saveSettings();
  385. };
  386.  
  387. chatAlphaDiv.appendChild(chatAlphaLabel);
  388. chatAlphaDiv.appendChild(chatAlphaSlider);
  389.  
  390. chatDropDiv.appendChild(chatVisDiv);
  391. chatDropDiv.appendChild(chatAlphaDiv);
  392.  
  393. windowHTML.appendChild(playersButtonDiv);
  394. windowHTML.appendChild(playersDropDiv);
  395. windowHTML.appendChild(usernamesButtonDiv);
  396. windowHTML.appendChild(usernamesDropDiv);
  397. windowHTML.appendChild(teamButtonDiv);
  398. windowHTML.appendChild(teamDropDiv);
  399. windowHTML.appendChild(chatButtonDiv);
  400. windowHTML.appendChild(chatDropDiv);
  401.  
  402. // Set the windowContent to the container
  403. this.windowConfigs.windowContent = windowHTML;
  404. };
  405.  
  406. // Injector function to inject code into the game code
  407. opacity.injector = function (src) {
  408. let newSrc = src;
  409.  
  410. // Control player and username visibility
  411. let discID = newSrc.match(/this\.discGraphics\[([\w$]{2,4})\]=null;\}/)[1];
  412. newSrc = newSrc.replace(
  413. `this.discGraphics[${discID}]=null;}`,
  414. `this.discGraphics[${discID}]=null;
  415. } else {
  416. if(this.discGraphics[${discID}]){
  417. if(this.discGraphics[${discID}].sfwSkin){
  418. // control skin visibility
  419. this.discGraphics[${discID}].playerGraphic.alpha = window.opacity.settings.players.skins ? 1 : 0;
  420. this.discGraphics[${discID}].sfwSkin.visible = !window.opacity.settings.players.skins;
  421. // gotta wait for avatar to be created
  422. } else if(this.discGraphics[${discID}].avatar?.bc != undefined){
  423. // create sfwSkin
  424. this.discGraphics[${discID}].sfwSkin = new PIXI.Graphics;
  425. this.discGraphics[${discID}].sfwSkin.beginFill(this.discGraphics[${discID}].teamify(this.discGraphics[${discID}].avatar.bc, this.discGraphics[${discID}].team));
  426. this.discGraphics[${discID}].sfwSkin.drawCircle(0,0,this.discGraphics[${discID}].radius);
  427. this.discGraphics[${discID}].sfwSkin.endFill();
  428. this.discGraphics[${discID}].container.addChildAt(this.discGraphics[${discID}].sfwSkin, 3);
  429. }
  430.  
  431. // everything else
  432. this.discGraphics[${discID}].nameText.alpha = window.opacity.settings.players.usernames.visible ? window.opacity.settings.players.usernames.alpha : 0;
  433. // Team outline
  434. if (this.discGraphics[${discID}].teamOutline != null) {
  435. this.discGraphics[${discID}].teamOutline.visible = window.opacity.settings.players.teamOutline.visible;
  436. this.discGraphics[${discID}].teamOutline.alpha = window.opacity.settings.players.teamOutline.alpha;
  437. }
  438. if(this.discGraphics[${discID}].playerID != this.localPlayerID){
  439. this.discGraphics[${discID}].container.visible = window.opacity.settings.players.visible;
  440. this.discGraphics[${discID}].container.alpha = window.opacity.settings.players.alpha;
  441. }
  442. }
  443. }`
  444. );
  445.  
  446. // Get chat window when building renderer
  447. let buildRendererFunction = newSrc.match(
  448. /(build\([\w$]{2,4},[\w$]{2,4}\)) \{.{30,150}=new [\w$]{2,4}\[[0-9]+\]\(/
  449. )[1];
  450.  
  451. newSrc = newSrc.replace(
  452. `${buildRendererFunction} {`,
  453. `${buildRendererFunction} {
  454. window.opacity.chatWindow = document.querySelector('#ingamechatbox');`
  455. );
  456.  
  457. if (src === newSrc) throw "Injection failed!";
  458. return newSrc;
  459. };
  460.  
  461. // Initialize the mod (run when document is ready)
  462. opacity.initMod = function () {
  463. // Ensure BonkHUD is available
  464. if (!window.bonkHUD) {
  465. console.error("BonkHUD is not loaded. Please make sure BonkHUD is installed.");
  466. return;
  467. }
  468.  
  469. // Load settings from localStorage
  470. this.loadSettings();
  471. this.setWindowContent();
  472. this.createWindow();
  473.  
  474. console.log(this.windowConfigs.windowName + " initialized");
  475. };
  476.  
  477. // Function to handle document readiness and initialize the mod
  478. opacity.onDocumentReady = function () {
  479. if (document.readyState === "complete" || document.readyState === "interactive") {
  480. this.initMod();
  481. } else {
  482. document.addEventListener("DOMContentLoaded", () => {
  483. this.initMod();
  484. });
  485. }
  486. };
  487.  
  488. // Compatibility with Excigma's code injector userscript
  489. if (!window.bonkCodeInjectors) window.bonkCodeInjectors = [];
  490. window.bonkCodeInjectors.push((bonkCode) => {
  491. try {
  492. return opacity.injector(bonkCode);
  493. } catch (error) {
  494. throw error;
  495. }
  496. });
  497.  
  498. console.log("Opacity injector loaded");
  499.  
  500. // Call the function to check document readiness and initialize the mod
  501. opacity.onDocumentReady();