Diep.io build selector

At the beginning of the script are the builds, you can edit them or add more at any time. Stats should be added in sequence. Also, you can look into the browser console to see the build and stats arrangement. That's all, enjoy the game.

Versão de: 26/12/2022. Veja: a última versão.

// ==UserScript==
// @name Diep.io build selector
// @match *://diep.io/*
// @version 1.3-logical
// @description At the beginning of the script are the builds, you can edit them or add more at any time. Stats should be added in sequence. Also, you can look into the browser console to see the build and stats arrangement. That's all, enjoy the game.
// @icon https://i.imgur.com/pvqsu5e.png
// @license GNU GPLv3
// @author LimeXator
// @namespace https://greasyfork.org/users/1003196
// ==/UserScript==

const builds = [
  {
    name: "Anni",
    values: [0, 2, 0, 7, 7, 7, 3, 7]
  },
  {
    name: "Sprayer",
    values: [0, 0, 0, 7, 7, 7, 7, 5]
  },
  {
    name: "Ram",
    values: [5, 7, 7, 0, 0, 0, 7, 7]
  },
  {
    name: "OverLord",
    values: [0, 5, 0, 7, 7, 7, 0, 7]
  },
  {
    name: "Trapper",
    values: [5, 7, 0, 0, 7, 7, 7, 0]
  },
  {
    name: "Necro",
    values: [0, 0, 0, 7, 6, 7, 6, 7]
  },
  {
    name: "Glass",
    values: [2,3,0,7,7,7,7,0,]
  },
  {
    name: "Tri-Angle",
    values: [4,4,4,0,7,7,7,0]
  },
  {
    name: "Assassin",
    values: [2, 3, 0, 7, 7, 7, 3, 4]
  },
  {
    name: "Factory",
    values: [0,0,0,5,7,7,7,7]
  }
  // Add more builds
];

function sendCommand(command) {
  input.execute(command);
}

function convertBuildToString(build) {
  let result = "";
  for (let i = 0; i < build.length; i++) {
    for (let j = 0; j < build[i]; j++) {
      result += (i + 1).toString();
    }
  }
  return result;
}

function optimizeBuildString(buildString) {
  // Create an array that will contain the number of occurrences of each digit in the buildString
  const count = new Array(8).fill(0);
  for (let i = 0; i < buildString.length; i++) {
    count[buildString[i] - 1]++;
  }

  // Create a new result string that will contain all the digits in the buildString, shuffled randomly
  let result = "";
  while (result.length < buildString.length) {
    // Find the next most frequently occurring digit in the buildString
    let max = 0;
    let maxValue = null;
    for (let i = 0; i < count.length; i++) {
      if (count[i] > max) {
        max = count[i];
        maxValue = i + 1;
      }
    }
    // Add the next most frequently occurring digit to the result string
    result += maxValue.toString();
    count[maxValue - 1]--;
  }

  // Return the result string
  return result;
}

    // If no such digit exists, add the next most frequently occurring digit to the result string

function selectBuild(build) {
  console.log(`Selecting build: ${build.name}`);
  console.log(build.values);

  // Use optimizeBuildString to reorder stats
  const buildString = optimizeBuildString(convertBuildToString(build.values));
  sendCommand(`game_stats_build ${buildString}`);
  console.log(buildString);
  showBuilds();
            let values = document.querySelector(".build-values");
      if (values) {
        values.parentNode.removeChild(values);
      }
}


function pressKey(key) {
  const inputElement = document.querySelector("input");
  const event = new KeyboardEvent("keydown", {
    key,
    bubbles: true,
    cancelable: true
  });
  inputElement.dispatchEvent(event);
}

function showBuilds() {
  // Select the menu element
  let menu = document.querySelector("#buildMenu");

  // If the menu already exists, hide it
  if (menu) {
    menu.parentNode.removeChild(menu);
    return;
  }

  // Create a new menu
  menu = document.createElement("div");
  menu.id = "buildMenu";
  menu.style.position = "fixed";
  menu.style.top = "50%";
  menu.style.right = "0%";
  menu.style.transform = "translate(-50%, -50%)";
  menu.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
  menu.style.border = "1px solid grey";
  menu.style.padding = "5px";
  menu.style.textAlign = "center";

  // Add a link to GreasyFork in the first item of the menu
  let item = document.createElement("div");
  item.classList.add("menu-item");
  let link = document.createElement("a");
  link.href = "https://greasyfork.org/cs/scripts/457172-diep-io-smart-build-selector";
  link.target = "_blank";
  link.innerHTML = "GreasyFork";
  link.style.textDecoration = "none";
  link.style.color = "white";
  item.appendChild(link);
  menu.appendChild(item);

  // Add items to the menu
  builds.forEach(build => {
    let buildElement = document.createElement("div");
    buildElement.id = `build-${build.id}`;
    buildElement.classList.add("menu-item");
    buildElement.innerHTML = build.name;
    buildElement.style.cursor = "pointer";
    buildElement.style.fontFamily = "Poppins";
    buildElement.addEventListener("mouseenter", () => showBuildValues(build));
    buildElement.addEventListener("mouseleave", () => {
      let values = document.querySelector(".build-values");
      if (values) {
        values.parentNode.removeChild(values);
      }
    });
    buildElement.addEventListener("click", () => selectBuild(build));
    menu.appendChild(buildElement);
  });

  // Add the menu to the document
  document.body.appendChild(menu);
}
function showBuildValues(build) {
  // Select the values element
  let values = document.querySelector(".build-values");

  // If the values element already exists, update its text
  if (values) {
    values.innerHTML = build.values;
    return;
  }

  // Create a new values element
  values = document.createElement("div");
  values.classList.add("build-values");
  values.innerHTML = build.values;
  values.style.position = "fixed";
  values.style.top = "0";
  values.style.right = "0";
  values.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
  values.style.color = "white";
  values.style.padding = "5px";

  // Add the values element to the document
  document.body.appendChild(values);
}

document.addEventListener("keydown", function(event) {
  // show the build menu when the "r" key is pressed
  if (event.key === "r") {
    showBuilds();
          let values = document.querySelector(".build-values");
      if (values) {
        values.parentNode.removeChild(values);
      }
  }
});