- // ==UserScript==
- // @name Bonk Host
- // @version 1.7
- // @author Salama
- // @description Makes hosting rooms in bonk.io better
- // @match https://bonk.io/gameframe-release.html
- // @run-at document-start
- // @grant none
- // @supportURL https://discord.gg/Dj6usq7ww3
- // @namespace https://greasyfork.org/users/824888
- // ==/UserScript==
-
- // for use as a userscript ensure you have Excigma's code injector userscript
- // https://greasyfork.org/en/scripts/433861-code-injector-bonk-io
-
- let injector = (str) => {
- let newStr = str;
- window.bonkHost = {};
- window.bonkHost.playerManagement = {};
- window.bonkHost.freejoin = false;
- window.bonkHost.playerCount = 0;
- window.bonkHost.scores = [];
- window.bonkHost.startGameFunction = () => {return;};
-
- let hostPlayerMenu = document.createElement('div');
- document.getElementById('pagecontainer').appendChild(hostPlayerMenu);
- hostPlayerMenu.outerHTML = `
- <div class="windowShadow" id="hostPlayerMenu"
- style="
- background-color: #cfd8cd;
- width: calc(35.2vw - 400px);
- min-width: 154px;
- max-width: 260px;
- height: 551px;
- position: absolute;
- left: 1%;
- top: calc(20% + 60px);
- border-radius: 7px;
- display: none">
-
- <div class="newbonklobby_boxtop newbonklobby_boxtop_classic" style="background-color: #009688;">Player List</div>
- <div id="hostPlayerMenuBox" class="newbonklobby_elementcontainer"></div>
- <div id="hostPlayerMenuControls" style="position:absolute;bottom:0;width:100%">
- <table>
- <tbody>
- <tr style="background-color: rgba(58, 58, 58, 0.07);">
- <td style="padding-left: 10px;" class="mapeditor_rightbox_table">
- Teamlock
- </td>
- <td>
- <input type="checkbox" id="hostPlayerMenuTeamlock">
- </td>
- </tr>
- <tr style="background-color: rgba(58, 58, 58, 0.07);">
- <td style="padding-left: 10px;" class="mapeditor_rightbox_table">
- Freejoin
- </td>
- <td>
- <input type="checkbox" id="hostPlayerMenuFreejoin">
- </td>
- </tr>
- <tr style="background-color: rgba(58, 58, 58, 0.07);">
- <td style="padding-left: 10px;" class="mapeditor_rightbox_table">
- Keep scores
- </td>
- <td>
- <input type="checkbox" id="hostPlayerMenuKeepScores">
- </td>
- </tr>
- </tbody>
- </table>
- <div class="newbonklobby_settings_button brownButton brownButton_classic buttonShadow" style="width:100%" id="hostPlayerMenuRestartButton">
- RESTART GAME
- </div>
- </div>
- </div>`;
-
- let CUSTOM_COMMANDS = `
- if(I8H[5][0] == "/hhelp") {
- u6H[29].showStatusMessage("/balance * -100 to 100 -- Balances everyone","#cc3333",false);
- u6H[29].showStatusMessage("/balanceall -100 to 100 -- Balances everyone","#cc3333",false);
- u6H[29].showStatusMessage("/start -- Starts the game","#cc3333",false);
- u6H[29].showStatusMessage("/freejoin on/off -- Lets people join during the game","#cc3333",false);
- }
- else if(I8H[5][0] == "/start") {
- window.bonkHost.startGame();
- }
- else if(I8H[5][0] == "/freejoin") {
- if(["true", "on", "yes", "enable"].includes(I8H[5][1])) {
- window.bonkHost.freejoin = true;
- F5S("* Freejoin on","#cc3333",true);
- }
- else if(["false", "off", "no", "disable"].includes(I8H[5][1])) {
- window.bonkHost.freejoin = false;
- F5S("* Freejoin off","#cc3333",true);
- }
- else if(I8H[5].length == 1) {
- window.bonkHost.freejoin = !window.bonkHost.freejoin;
- F5S("* Freejoin " + (window.bonkHost.freejoin ? "on" : "off"),"#cc3333",true);
- }
- document.getElementById('hostPlayerMenuFreejoin').checked = window.bonkHost.freejoin;
- }
- `;
-
- let BALANCE_ALL_MESSAGE = `
- if(I8H[67] == -2) {
- u6H[29].showStatusMessage("* " + "Everyone" + " has had their buff/nerf set to " + I8H[32], "#cc3333", false);
- }
- else if(I8H[32] == 0)
- `;
-
- let BALANCE_SELECTION = `
-
- u6H[36].bal[I8H[17]] = I8H[32];
- u6H[11].sendBalance(I8H[17], I8H[32]);
- if (u6H[29]) {
- u6H[29].updatePlayers();
- }
- I8H[67]=-2;
- if (u6H[44][I8H[17]].userName.toLowerCase() == I8H[7].toLowerCase()) {
- I8H[67] = I8H[17];
- break;
- }
- `;
-
- let SUGGESTION_MODE_BUTTON = `
- let space = document.createElement("span");
- space.classList.add("newbonklobby_mapsuggest_high");
- space.appendChild(document.createTextNode(" "));
-
- let smb = document.createElement("span");
- smb.classList.add("newbonklobby_mapsuggest_high");
- smb.classList.add("newbonklobby_chat_link");
- smb.style.color="#ff0000";
- v2k[79].setButtonSounds([smb]);
-
- smb.onclick = () => {
- d9G[73].onclick();
- window.bonkSetMode(w3G[2][d9G[73].suggestID].m.mo);
- };
- `;
-
- let APPEND_SUGGESTION_MODE_BUTTON = `
- if(!!v2k[10].modes[w3G[2][d9G[73].suggestID].m.mo]) {
- d9G[8].appendChild(space);
- smb.appendChild(document.createTextNode("[" + v2k[10].modes[w3G[2][d9G[73].suggestID].m.mo].lobbyName + "]"));
- d9G[8].appendChild(smb);
- }
- `;
-
- let modeStuff = newStr.match(
- new RegExp(
- "(var .{2,4}=\\[arguments\\];.{2,4}\\[\\d{1,2}\\]=.{2,5};).{1,300}\
- \\+\\+;\
- if.{5,60}=0;\\}\
- (.{5,50}=.{5,50})\
- \\[.{2,4}\\[\\d{1,4}\\]\\];\
- (.{5,200}=true.{5,200}\\(\\);)\
- \\}\\}"
- )
- );
- // 1 is var m7p = [arguments]; m7p[4] = y3uu;
- // 2 is G7p[0][2]["mo"] = P1R[43]["lobbyModes"]
- // 3 is code that updates the mode
- let modeVar =
- modeStuff[2].split("=")[0].match(/.{2,4}\[\d{1,2}\]\[\d{1,2}\]/g)[0] +
- `["mo"]`;
- let modesObject =
- modeStuff[2].split("=")[1].match(/.{2,4}\[\d{2,4}\]/g)[0] + `["modes"]`;
-
- window.modeDropdownCreated = false;
- window.createModeDropdown = () => {
- if (window.modeDropdownCreated) return;
- window.modeDropdownCreated = true;
- const dropdown = document.createElement("div");
- dropdown.classList = "dropdown-container";
- const mds = dropdown.style;
- mds.color = "#ffffff";
- mds.position = "absolute";
- mds.right = "15px";
- mds.bottom = "55px";
- mds.width = "116px";
- mds.height = "30px";
- mds.display = "flex";
- mds.textAlign = "center";
- mds.flexDirection = "column-reverse";
-
- document.getElementById("newbonklobby_modebutton").remove();
- title = document.createElement("div");
- title.classList = "dropdown-title dropdown_classic";
- title.innerText = "MODE";
- title.style.fontSize = "18px";
- title.id = "newbonklobby_modebutton";
- title.style.position = "unset";
- dropdown.appendChild(title);
-
- const options = [];
- let dropdownOpen = false;
-
- function toggleVisibility(e) {
- dropdownOpen = !dropdownOpen;
- for (const o of options) {
- o.style.visibility = dropdownOpen ? "" : "hidden";
- }
- e.stopImmediatePropagation();
- }
-
- for (const mode of Object.keys(window.bonkModesObject)) {
- const option = document.createElement("div");
- option.classList = "dropdown-option dropdown_classic";
- option.style.display = "block";
- option.style.visibility = "hidden";
- option.style.fontSize = "15px";
- option.innerText = window.bonkModesObject[mode].lobbyName;
- option.onclick = (e) => {
- window.bonkSetMode(mode);
- toggleVisibility(e);
- };
- options.push(option);
- dropdown.appendChild(option);
- }
-
- title.addEventListener("click", toggleVisibility);
-
- document.getElementById("newbonklobby_settingsbox").appendChild(dropdown);
- };
-
- let PLAYER_CLICK_MENU = `
- if(playerEntry) {
- playerEntry.parentNode.appendChild(m9G[6]);
- }
- else` + " ";
-
- let KEEP_SCORES = `
- if(window.bonkHost.scores.length > 0 && document.getElementById('hostPlayerMenuKeepScores').checked) {
- k7k[1].scores = window.bonkHost.scores;
- }
- else` + " ";
-
- document.getElementById('hostPlayerMenuFreejoin').addEventListener('change', (e) => {
- window.bonkHost.freejoin = e.target.checked;
- });
-
- document.getElementById('hostPlayerMenuTeamlock').addEventListener('change', () => {
- document.getElementById('newbonklobby_teamlockbutton').onclick();
- });
-
- window.bonkHost.playerManagement.addPlayer = (playerEntry, info) => {
- let newPlayerEntry = playerEntry.cloneNode(true);
- newPlayerEntry.classList.remove('newbonklobby_playerentry_half');
- newPlayerEntry.getElementsByClassName("newbonklobby_playerentry_ping")[0].remove();
- newPlayerEntry.getElementsByClassName("newbonklobby_playerentry_host")[0].remove();
- newPlayerEntry.onclick = playerEntry.onclick;
- if(info.team == 0) {
- newPlayerEntry.style.filter = "opacity(0.4)";
- }
- hostPlayerMenuBox.appendChild(newPlayerEntry);
- }
- window.bonkHost.playerManagement.removePlayer = (playerEntry) => {
- if((foundPlayerEntry = window.bonkHost.playerManagement.getPlayer(playerEntry)) && foundPlayerEntry)
- hostPlayerMenuBox.removeChild(foundPlayerEntry);
- }
-
- window.bonkHost.playerManagement.show = () => {
- if(window.bonkHost.menuFunctions.visible) return;
- parent.document.getElementById("adboxverticalleftCurse").style.display = "none";
- document.getElementById('hostPlayerMenu').style.removeProperty("display");
- }
-
- window.bonkHost.playerManagement.hide = () => {
- document.getElementById('hostPlayerMenu').style.display = "none";
- parent.document.getElementById("adboxverticalleftCurse").style.removeProperty("display");
- }
-
- window.bonkHost.playerManagement.getPlayer = (playerEntry, exact = false) => {
- if (exact) {
- let child = [...hostPlayerMenuBox.children].indexOf(playerEntry);
- if(child) return hostPlayerMenuBox.children[child];
- }
- for(let child of hostPlayerMenuBox.children) {
- if(child.children[1].innerText == playerEntry.children[1].innerText
- && child.children[1].innerText == playerEntry.children[1].innerText) {
- return child;
- }
- }
- return false;
- }
-
- window.bonkHost.playerManagement.movePlayer = (playerID, playerCount, team) => {
- window.bonkHost.menuFunctions.visible = true;
- if(team > 0)
- window.bonkHost.bonkHandlers.hostHandlePlayerJoined(playerID, playerCount, team);
- else
- window.bonkHost.bonkHandlers.hostHandlePlayerLeft(playerID);
- window.bonkHost.menuFunctions.updatePlayers();
- }
-
- window.bonkHost.startGame = () => {
- window.bonkHost.startGameFunction();
- }//Remove round limit
- document.getElementById('newbonklobby_roundsinput').removeAttribute("maxlength");
- newStr = newStr.replace(/...\[[0-9]\]\[[0-9]\]\[...\[[0-9]\]\[[0-9]?[0-9]?[0-9]\]\]=Math\[...\[[0-9]\]\[[0-9]?[0-9]?[0-9]\]\]\(Math\[...\[[0-9]\]\[[0-9]?[0-9]?[0-9]\]\]\(1,...\[[0-9]\]\[[0-9]\]\[...\[[0-9]\]\[[0-9]?[0-9]?[0-9]\]\]\),9\);/, '');
-
- //Mode selection menu
- newStr = newStr.replace(modeStuff[0], `${modeStuff[0]};window.bonkModesObject=${modesObject};window.bonkSetMode=m=>{${modeStuff[1]}${modeVar}=m;${modeStuff[3]}};window.createModeDropdown();`);
- //Add mode mutton to map suggestion message
- newStr = newStr.replace('v2k[79][d9G[3][624]]([d9G[73]]);', 'v2k[79][d9G[3][624]]([d9G[73]]);' + SUGGESTION_MODE_BUTTON);
- //Append mode button
- newStr = newStr.replace('d9G[8][d9G[3][455]](d9G[73]);', 'd9G[8][d9G[3][455]](d9G[73]);'+APPEND_SUGGESTION_MODE_BUTTON);
-
- //Balance all
- newStr = newStr.replace('I8H[7][I8H[1][645]]()', 'I8H[7][I8H[1][645]]() || I8H[7] === "*" || I8H[5][0] == "/balanceall"');
- newStr = newStr.replace('I8H[5][0] == G9b.z43(1869)', 'I8H[5][0] == G9b.z43(1869) || I8H[5][0] == "/balanceall"');
- newStr = newStr.replace('I8H[67]=I8H[17];break;', BALANCE_SELECTION);
- newStr = newStr.replace('parseInt(I8H[5][2]);', 'parseInt(I8H[5][I8H[5][0] == "/balanceall" ? 1 : 2]);');
- newStr = newStr.replace('if(I8H[32] == 0)', BALANCE_ALL_MESSAGE);
-
- newStr = newStr.replace('if(I8H[5][0] == G9b.z43(1869)', CUSTOM_COMMANDS+'else if(I8H[5][0] == G9b.z43(1869)');
- newStr = newStr.replace('u6H[29][I8H[1][644]](G9b.A43(1897),G9b.z43(1871),false);', 'u6H[29][I8H[1][644]](G9b.A43(1897),G9b.z43(1871),false);u6H[29].showStatusMessage("/hhelp - commands from host extension","#cc3333",false);');
-
- //Let people join mid game
- newStr = newStr.replace('if(u6H[64]){u6H[30]', 'if(window.bonkHost.freejoin||u6H[64]){u6H[30]');
-
- /////////////
- //Host menu//
- /////////////
-
- //Add players
- newStr = newStr.replace('{Q1h();}};', '{Q1h();}};' + 'window.bonkHost.playerManagement.addPlayer(X9G[1], w3G[0][1][X9G[0][0]]);');
-
- //Remove players
- newStr = newStr.replace('if(w3G[32][h9G[5]]){', 'if(w3G[32][h9G[5]]){' + 'window.bonkHost.playerManagement.removePlayer(w3G[32][h9G[5]]);');
- newStr = newStr.replace('if(w3G[32][c1G[2]]){', 'if(w3G[32][c1G[2]]){' + 'window.bonkHost.playerManagement.removePlayer(w3G[32][c1G[2]]);');
-
- //Player click menu
- newStr = newStr.replace('if(X9G[1][m9G[2][1379]]){', PLAYER_CLICK_MENU + 'if(X9G[1][m9G[2][1379]]){')
-
- //Player click menu position and highligh removal
- newStr = newStr.replace('if(m9G[4] == false){', 'if(playerEntry){w3G[26].playerElement=playerEntry;m9G[6].style.removeProperty("left");m9G[6].style.right=0;m9G[6].style.top=([...playerEntry.parentNode.children].indexOf(playerEntry)+1)*43+"px";}' + 'if(m9G[4] == false){');
-
- //Highlight
- newStr = newStr.replace('X9G[1][m9G[2][457]][m9G[2][456]](G9b.z43(3256));', 'let playerEntry = window.bonkHost.playerManagement.getPlayer(m9G[0][0].target, true); if(playerEntry) {playerEntry.classList.add("newbonklobby_playerentry_menuhighlighted");} else{' + 'X9G[1][m9G[2][457]][m9G[2][456]](G9b.z43(3256));' + '}');
-
- //Some bonk function handlers
- newStr = newStr.replace('R2k[0][1]});};}', 'R2k[0][1]});};' + 'window.bonkHost.bonkHandlers = this;' + '}');
-
- //Some menu functions
- newStr = newStr.replace('w3G[60]);}};', 'w3G[60]);}};'+ 'window.bonkHost.menuFunctions = this;');
-
- //Player counter
- newStr = newStr.replace('if(u6H[5]', 'window.bonkHost.playerCount=s6H[3];if(u6H[5]');
-
- //Change team handlers
- newStr = newStr.replace('w8G[9]=v8yy;', 'w8G[9]=v8yy;' + "window.bonkHost.playerManagement.movePlayer(w8G[0][0], window.bonkHost.playerCount, w8G[0][1]);");
- newStr = newStr.replace('S8G[8]=v8yy;', 'S8G[8]=v8yy;' + "window.bonkHost.playerManagement.movePlayer(this.getLSID(), window.bonkHost.playerCount, S8G[0][0]);");
-
- //Get start game function
- newStr = newStr.replace('function P5S', 'window.bonkHost.startGameFunction=P5S;document.getElementById("hostPlayerMenuRestartButton").addEventListener("click", window.bonkHost.startGame);' + 'function P5S')
-
- //Scores
- newStr = newStr.replace(';if(k7k[0][5][k7k[4][114]])', ';' + KEEP_SCORES + 'if(k7k[0][5][k7k[4][114]])');
- newStr = newStr.replace('o9k[1][o9k[7][122]]=[0,0,0,0];', 'o9k[1][o9k[7][122]]=' + '(window.bonkHost.scores.length > 0 && document.getElementById("hostPlayerMenuKeepScores").checked) ? window.bonkHost.scores' + ':[0,0,0,0];')
-
- //Score counter
- newStr = newStr.replace('G9b.A2k(1000,b2k[6]);', 'G9b.A2k(1000,b2k[6]);window.bonkHost.scores=i2k[7][i2k[1]].scores;');
-
- //Update menu while in game if host
- newStr = newStr.replace('!this[h9G[9][481]]', '!this[h9G[9][481]] && w3G[3].getLSID() != w3G[3].hostID');
- newStr = newStr.replace('!this[V9G[1][481]]', '!this[V9G[1][481]] && w3G[3].getLSID() != w3G[3].hostID');
-
- //Show menu when in game if host
- newStr = newStr.replace('if(u6H[29]){u6H[29][w8H[9][722]]();}', 'if(u6H[29]){u6H[29][w8H[9][722]]();' + `if(u6H[11].hostID == u6H[11].getLSID())window.bonkHost.playerManagement.show();` + '}');
-
- //Hide menu when not in game
- newStr = newStr.replace('w1G[5]=v8yy;', 'w1G[5]=v8yy;' + 'window.bonkHost.playerManagement.hide();');
- newStr = newStr.replace('c1G[5]=v8yy;', 'c1G[5]=v8yy;' + 'window.bonkHost.playerManagement.hide();');
-
- //Add default click handler (mainly for closing the dropdown menu)
- newStr = newStr.replace('=e6h;', '=e6h;' + 'document.getElementById("hostPlayerMenu").onclick=e6h;');
-
- //Handle host change
- newStr = newStr.replace('l5h(G9b.z43(3279),G9b.A43(3276),false);}', 'window.bonkHost.playerManagement.show();' + 'l5h(G9b.z43(3279),G9b.A43(3276),false);}' + 'else{window.bonkHost.playerManagement.hide();}');
- newStr = newStr.replace('C0z(G9b.A43(2039));', 'C0z(G9b.A43(2039));' + 'window.bonkHost.playerManagement.show();');
-
- //Teamlock
- newStr = newStr.replace('if(w3G[0][2][V9G[1][662]])', 'document.getElementById("hostPlayerMenuTeamlock").checked=w3G[0][2].tl;' + 'if(w3G[0][2][V9G[1][662]])');
-
- //Handle an error when clicking host menu. MIGHT BREAK IN RARE CASES WITH OTHER MODS because it's missing {}, but it should be fine
- newStr = newStr.replace('t9G[5]=v8yy;', 't9G[5]=v8yy;' + 'if(w3G[26][t9G[5][1372]]!=null)'); console.log("Bonk Host injector run");
- return newStr;
- }
-
- if(!window.bonkCodeInjectors) window.bonkCodeInjectors = [];
- window.bonkCodeInjectors.push(bonkCode => {
- try {
- return injector(bonkCode);
- } catch (error) {
- alert(
- `Whoops! Bonk Host was unable to load.
- This may be due to an update to Bonk.io. If so, please report this error!
- This could also be because you have an extension that is incompatible with \
- Bonk Host, such as the Bonk Leagues Client. You would have to disable it to use \
- Bonk Host.`);
- throw error;
- }
- });
-
- console.log("Bonk Host injector loaded");