RG2N
RG2N

Reputation: 17

Discord.js not checking if args exist

I'm trying to code a Minecraft server info checker with discord.js and minecraft-server-util but with the checks if the args even exist or there is only 1 argument are not working and it's passing over those checks thinking nothings wrong but when I don't include anything the server-util part sends an error to console "Expected Host(The Arguments) to have content, got an empty string" I'm not exactly sure what the problem is if you can help me out that would be great.

Command name: @javaserverstatus The command and prefix is 17 characters that's why slice is set to 17.

client.on('message', (message) => {
  const args = message.content.slice(17).trim().split(' ') // this is where args is defined.
  if (message.content === `${prefix}javaserverstatus`) {
    if (!args.length) {
      return message.channel.send(`You didn't provide a server, ${message.author}!`) // checks if args exist
    }
    if (args.length > 1) {
      return message.channel.send(`Wrong input! EG. play.hypixel.net, ${message.author}`) // checks if there are only 1 arguments
    }
  }
  const util = require('minecraft-server-util')
  var serverinfo = null
  util
    .status(args.toString()) // This code is giving an error saying args does not exist.
    .then((response) => {
      console.log(response)
      serverinfo = response
      const embed = new Discord.MessageEmbed()
        .setTitle(args + ' Server Status')
        .setColor(0xff0000)
        .setDescription('IP: ' + response.host + '\n' + 'Port: ' + response.port + '\n' + 'Version: ' + response.version + '\n' + 'Online Players: ' + response.onlinePlayers.toString() + '\n' + 'Max Players: ' + response.maxPlayers.toString() + '\n')
      message.channel.send(embed)
    })
    .catch((error) => {
      console.error(error)
    })
})

Upvotes: 0

Views: 916

Answers (1)

theusaf
theusaf

Reputation: 1802

Your command's code is still running even if a message is not the command.

For example, the message "hi" would result in args of [""]. Then it would simply ignore the if statement and run your command.

Also, if the message is "{prefix}javaserverstatus", it will always have an args length of 1 ([""]).

Another thing to note is that if the message is also "{prefix}javaserverstatus some arguments", the if statement to validate your data does not run, as the message is not equal to ${prefix}javaserverstatus anymore.

You should fix your code to only run when the command is actually being run, and properly validate your data:

client.on("message", (message) => {
  // create args
  const args = message.content.slice(17).trim().split(" ");

  // fits the command, including arguments, not just a blank command
  if (message.content.startsWith(`${prefix}javaserverstatus`)) {
    // args.length will always be 1 or greater.
    // instead, check if the first argument is an empty string.
    if (args[0] === "") {
      return message.channel.send(`You didn't provide a server, ${message.author}!`); // checks if args exist
    }
    if (args.length > 1) {
      return message.channel.send(`Wrong input! EG. play.hypixel.net, ${message.author}`) // checks if there are only 1 arguments
    }

    // only if the command is valid, then run the command.
    const util = require('minecraft-server-util');
    let serverinfo = null;
    util
      .status(args.toString())
      .then((response) => {
        console.log(response);
        serverinfo = response;
        const embed = new Discord.MessageEmbed()
          .setTitle(args + " Server Status")
          .setColor(0xff0000)
          .setDescription("IP: " + response.host + "\n" + "Port: " + response.port + "\n" + "Version: " + response.version + "\n" + "Online Players: " + response.onlinePlayers.toString() + "\n" + "Max Players: " + response.maxPlayers.toString() + "\n")
        message.channel.send(embed);
      })
      .catch((error) => {
        console.error(error);
      });
  }
});

Below is a snippet, with code similar to the code in your question to help highlight the issue:

// The following code will not work as expected
function simulateOnMessage(content) {
  console.log("================");
  const args = content.slice(17).trim().split(" ");
  console.log("Args: ", args);
  console.log("Args length: " + args.length);
  if (content === "!javaserverstatus") {
    console.log("Checking arguments...");
    if (!args.length) {
      return console.log("No server provided!");
    }
    if (args.length > 1) {
      return console.log("Bad input!");
    }
    console.log("No problems found!");
  }
  doSomethingWith(args.toString());
}
function doSomethingWith(str) {
  if (str === "") {
    console.log("EMPTY STRING!");
  } else {
    console.log("OK!");
  }
}
simulateOnMessage("!javaserverstatus");
simulateOnMessage("!javaserverstatus args");
simulateOnMessage("!javaserverstatus with args");
simulateOnMessage("completely invalid message");
simulateOnMessage("hi");

TLDR;

  • Use String.startsWith() or something similar to check if your command is being run
  • Only run the code if it fits the conditions

Upvotes: 1

Related Questions