Bonk.io Auto Colour Switching

Automatically rotate through bonk icon colours/teams

  1. // ==UserScript==
  2. // @name Bonk.io Auto Colour Switching
  3. // @author Figurative Lag
  4. // @description Automatically rotate through bonk icon colours/teams
  5. // @match https://bonk.io/*
  6. // @version 1.9.8
  7. // @run-at document-idle
  8. // @grant none
  9. // @license Apache 2.0
  10. // @namespace https://greasyfork.org/en/scripts/455254-bonk-io-auto-colour-switching
  11. // ==/UserScript==
  12.  
  13. // Index 0 is actually supposed to be Spectate, which we're not going to use
  14. // So, we have to add 1 to our index when submitting data to the web socket
  15. const coloursList = [
  16. "FFA",
  17. "Red",
  18. "Blue",
  19. "Green",
  20. "Yellow"
  21. ]
  22. const enabled = [
  23. true,
  24. true,
  25. true,
  26. true,
  27. true
  28. ]
  29. let currentColour = 0
  30.  
  31. const RNG = (min, max) => Math.round(Math.random() * (max - min)) + min
  32. const getFrame = () => document.getElementById("maingameframe").contentWindow
  33. const getDoc = () => getFrame().document
  34. const getId = id => getDoc().getElementById(id)
  35.  
  36. let websocket = null
  37. const originalSend = getFrame().WebSocket.prototype.send
  38.  
  39. getFrame().WebSocket.prototype.send = function(args) {
  40. const invalidSocket = websocket == null || websocket.readState != websocket.OPEN
  41. const validURL = this.url.includes(".bonk.io/socket.io/?EIO=3&transport=websocket&sid=")
  42.  
  43. if (validURL && invalidSocket)
  44. websocket = this
  45.  
  46. originalSend.call(this, args)
  47. }
  48.  
  49. const setColour = colour => {
  50. currentColour = colour
  51.  
  52. const inCustomGame = getDoc().getElementsByClassName("newbonklobby_playerentry").length > 0
  53.  
  54. // We have to add +1 because we removed "spectate" from index 0
  55. if (websocket && inCustomGame)
  56. websocket.send('42[6,{"targetTeam":' + (colour+1) + '}]')
  57. }
  58.  
  59. let menu = document.getElementById("descriptioninner")
  60. menu.style.cssText = "background-color: black !important;"
  61.  
  62. // Clear old screen
  63. Array.from(menu.children).forEach(el => el.remove())
  64.  
  65. const createCheckbox = (colour, i) => {
  66. let id = `${colour}Checkbox`
  67. let label = document.createElement("label")
  68. label.innerHTML = colour
  69. label.htmlFor = id
  70. menu.appendChild(label)
  71.  
  72. let checkbox = document.createElement("input")
  73. checkbox.type = "checkbox"
  74. checkbox.id = id
  75. checkbox.checked = true
  76.  
  77. checkbox.onchange = function() {
  78. enabled[i] = this.checked
  79. }
  80.  
  81. menu.appendChild(checkbox)
  82. menu.appendChild(document.createElement("br"))
  83. }
  84.  
  85. const setCheckbox = (colour, value) => {
  86. let checkbox = document.getElementById(`${colour}Checkbox`)
  87. checkbox.checked = !value
  88. checkbox.click()
  89. }
  90.  
  91. let h3 = document.createElement("h3")
  92. h3.innerHTML = "Automatic Colour (Team) Switching"
  93. h3.style.margin = 0
  94. menu.appendChild(h3)
  95.  
  96. let p = document.createElement("p")
  97. p.innerHTML = "Made by Figurative Lag"
  98. p.style.margin = 0
  99. menu.appendChild(p)
  100.  
  101. menu.appendChild(document.createElement("hr"))
  102.  
  103. coloursList.forEach((colour, i) => {
  104. createCheckbox(colour, i)
  105. })
  106.  
  107. let disable = document.createElement("input")
  108. disable.type = "button"
  109. disable.value = "Quick Disable"
  110. disable.style.marginTop = "0.5em"
  111. disable.onclick = () => {
  112. coloursList.forEach(colour => {
  113. setCheckbox(colour, false)
  114. })
  115. setCheckbox("FFA", true)
  116. }
  117. menu.appendChild(disable)
  118.  
  119. let enable = document.createElement("input")
  120. enable.type = "button"
  121. enable.value = "Quick Enable"
  122. enable.onclick = () => {
  123. coloursList.forEach(colour => {
  124. setCheckbox(colour, true)
  125. })
  126. }
  127. menu.appendChild(enable)
  128.  
  129. menu.appendChild(document.createElement("hr"))
  130. p = document.createElement("p")
  131. p.innerHTML = "<strong>Switch Interval Modification</strong><br>Warning: bonk.io will quickly rate limit you, making it switch even slower than before you reduced the delay. So, I recommend leaving it at 1000 ms for consistency."
  132. menu.appendChild(p)
  133.  
  134. let intervalInput = document.createElement("input")
  135. intervalInput.type = "number"
  136. intervalInput.value = 1000
  137. intervalInput.placeholder = "Interval (ms)"
  138. menu.appendChild(intervalInput)
  139.  
  140. let intervalSubmit = document.createElement("input")
  141. intervalSubmit.type = "button"
  142. intervalSubmit.value = "Submit"
  143. intervalSubmit.onclick = () => {
  144. clearInterval(interval)
  145. interval = setInterval(timeout, parseInt(intervalInput.value))
  146. }
  147. menu.appendChild(intervalSubmit)
  148.  
  149. function timeout() {
  150. const listChecked = []
  151. for (let i = 0; i < enabled.length; i++) {
  152. if (enabled[i])
  153. listChecked.push(i)
  154. }
  155.  
  156. if (listChecked.length == 0)
  157. return
  158. if (listChecked.length == 1 && currentColour == listChecked[0])
  159. return
  160.  
  161. // Don't set the colour that is already set
  162. let colour = currentColour
  163. while (colour == currentColour) {
  164. colour = listChecked[RNG(0, listChecked.length-1)]
  165. }
  166.  
  167. setColour(colour)
  168. }
  169. let interval = setInterval(timeout, 1000)