1
votes

So I'm trying to make a leader board command for my xp system using quick.db in my discord.js bot. The code for the command:

const db = require("quick.db");
        const Discord = require("discord.js");

        let firstplace = 0;
        let firstplaceperson = "";
        let secondplace = 0;
        let secondplaceperson = "";
        let thirdplace = 0;
        let thirdplaceperson = "";


        message.guild.members.forEach(member => {
            console.log(member.displayName)
            let xp = db.get(`xp_${message.guild.id}_${member.id}`);
            if (xp === null) db.set(`xp_${message.guild.id}_${member.id}`, 0);
            xp = db.get(`xp_${message.guild.id}_${member.id}`);

            if (xp >= firstplace) {
                firstplace = xp;
                firstplaceperson = member.displayName;
            }

            if (xp <= firstplace && xp > secondplace && firstplaceperson != member.displayName) {
                secondplace = xp;
                secondplaceperson = member.displayName;
            }

            if (xp <= secondplace && xp > thirdplace && firstplaceperson != member.displayName && secondplaceperson != member.displayName) {
                thirdplace = xp;
                thirdplaceperson = member.displayName;
            }
        });




        console.log(firstplace);
        console.log(firstplaceperson);

        console.log(secondplace);
        console.log(secondplaceperson);

        console.log(thirdplace);
        console.log(thirdplaceperson);

        let embed = {
            color: 000000,
            timestamp: new Date(),
            fields: [
                {
                    name: message.guild.language.first_place,
                    value: firstplaceperson + " " + firstplace
                },
                {
                    name: message.guild.language.second_place,
                    value: secondplaceperson + " " + secondplace
                },
                {
                    name: message.guild.language.third_place,
                    value: thirdplaceperson + " " + thirdplace
                }
            ]
        }

        if (thirdplace === 0) {
            embed.fields = [
                {
                    name: message.guild.language.first_place,
                    value: firstplaceperson + " " + firstplace
                },
                {
                    name: message.guild.language.second_place,
                    value: secondplaceperson + " " + secondplace
                },
                {
                    name: message.guild.language.third_place,
                    value: message.guild.language.invalid_xp
                }
            ]
        }


        if (secondplace === 0) {
            embed.fields = [
                {
                    name: message.guild.language.first_place,
                    value: firstplaceperson + " " + firstplace
                },
                {
                    name: message.guild.language.second_place,
                    value: message.guild.language.invalid_xp
                },
                {
                    name: message.guild.language.third_place,
                    value: message.guild.language.invalid_xp
                }
            ]
        }

        message.channel.send({ embed: embed })

    }

I added the console.log parts to see if the problem is with the first part of the code where I'm trying to get the top three members. The problem is that both secondplace and thirdplace stays 0 even tho there are other people in the discord server with xp more than 0. Also the forEach function goes through every member in the guild so that is not the problem.

As expected because the secondplace and thirdplace values stay 0 the embed will end up with the message.guild.language.invalid_xp values in the last two fields. While the first field displays the first place properly.

2

2 Answers

0
votes

I think the 'system' you use for classifying your members is kinda bad. Try using something simpler for leaderboard, like Arrays.

let leaderboard = new Array()

function update(user,xp) {
  if (!leaderboard[0]) return leaderboard.push([user,xp])
  if (xp >= leaderboard[0][1]) return leaderboard.splice(0,0,[user,xp]);
  if (!leaderboard[1]) return leaderboard.push([user,xp])
  if (xp >= leaderboard[1][1]) return leaderboard.splice(1,0,[user,xp]);
  if (!leaderboard[2]) return leaderboard.push([user,xp])
  if (xp >= leaderboard[2][1]) return leaderboard.splice(2,0,[user,xp]);
}

You can now call the function at every iteration of the forEach loop. It would look like this:

message.guild.members.forEach(member => {
  console.log(member.displayName)
  let xp = db.get(`xp_${message.guild.id}_${member.id}`);
  if (xp === null) db.set(`xp_${message.guild.id}_${member.id}`, 0);
  xp = db.get(`xp_${message.guild.id}_${member.id}`);
  
  ((user,xp) => {
    if (!leaderboard[0]) return leaderboard.push([user,xp])
    if (xp >= leaderboard[0][1]) return leaderboard.splice(0,0,[user,xp]);
    if (!leaderboard[1]) return leaderboard.push([user,xp])
    if (xp >= leaderboard[1][1]) return leaderboard.splice(1,0,[user,xp]);
    if (!leaderboard[2]) return leaderboard.push([user,xp])
    if (xp >= leaderboard[2][1]) return leaderboard.splice(2,0,[user,xp]);
  })()

(Using an anonymous function, it looks cooler (: and you don't have to declare a function this way)

0
votes

note: if you use V12 or higher, it should be

message.guild.members.cache.forEach()