Anej
Anej

Reputation: 100

Discord.js - different variables in different servers

I have a bot that changes the variable to true when the radio station starts playing. I want to have a variable that is unique for the different servers it is used in. I don't know how to do this.

This is my code for the system :

const Radio = {
    Predvaja : false,
    Radio1 : false,
    RadioCity : false,
    RadioDJCity : false,
    RadioCenter : false,
    RadioCenter100 : false,
    RadioMTV : false,
    RadioPtuj : false,
    RadioOtvoreni : false,
    RadioAktual : false,
    RadioVeseljak : false,
    RadioDalmacija : false

}

if (msg === 'radio 1') {
        Radio.Predvaja = true;
        Radio.Radio1 = true;
}

Upvotes: 0

Views: 797

Answers (1)

Isolin
Isolin

Reputation: 876

Servers Map

You should create a global Map object in your bot. Have a look at examples how to use it.

The Map stores key-value pairs and by design it is optimized to do efficient lookups of keys. So you can use the server ID as a key for each piece of information about radio stations that are playing right now.

let stationsPerServer = new Map();

//when a server adds your bot
client.on("guildCreate", guild => {
   stationsPerServer.set(guild.id, new Set());
});

//station activation per server
activateStation(guildId, stationName) {
    const stations = stationsPerServer.get(guildId);
    stations.add(stationName);
    //add any other custom actions like broadcast to a voice channel
}

//station deactivation per server
activateStation(guildId, stationName) {
    stationsPerServer.get(guildId).delete(stationName)
    //add any other custom actions like leaving a voice channel
}

//is station playing in server
activateStation(guildId, stationName) {
    return stationsPerServer.get(guildId).has(stationName)
}

//deactivate station for all servers
deactivateStationGlobally(stationName){
    for (let stations of stationsPerServer.values()) {
        stations.delete(stationName);
        //add any other custom actions like leaving the voice channel
    }
}

Stations vector

What you want to store is basically a binary vector. You have at least three options how to do that:

Dedicated object

That's your current solution. An object full of predefined boolean values. Not very flexible.

Using a set

It is much better to take a Set of station names that are playing right now. A Set stores each value only once and it is optimized for fast lookups. You can interpret the boolean value in your object structure as a query if a station is present in a set of active stations.

There are several advantages when using sets:

  1. You can later add other stations easily, or remove existing ones if they stop broadcasting without changing the structure of your object.
  2. You don't need to store the negative (false) values for each server. This would be storage-efficient if you had lots of stations and lots of servers.
  3. If necessary, you can keep a single global set of all known stations for reference.

So per server you can do something like:

let activeStations = new Set(); //initialize the set

//add some stations
//(equals setting the station field to true)
activeStations.add('RadioPtuj');
activeStations.add('RadioDalmacia');
//now the set contains {'RadioPtuj', 'RadioDalmacia'}

//adding a station twice does not change the set
//  a set stores each member just once,
//  unlike an array that does not care about duplicates
activeStations.add('RadioDalmacia');
//the set still contains only {'RadioPtuj', 'RadioDalmacia'}
activeStations.add('RadioDalmacia');
//the set still contains only {'RadioPtuj', 'RadioDalmacia'}

//find out if a station is active
//(equals checking the boolean station field)
activeStations.has('RadioPtuj'); //true
activeStations.has('RadioOtvoreni'); //false

//remove an inactive station
//(equals setting the station field to false)
activeStations.delete('RadioDalmacia');
//now the set contains {'RadioPtuj'}

//deletion of a station not present in the set has no effect
activeStations.delete('RadioMTV');
//the set still contains {'RadioPtuj'}

Enum

Javascript does not support enums out of the box, but you could assign binary codes to stations and use binary operations and masks to replace the set of strings with a set of numbers. This would be relevant if you had thousands of servers running your bot.

Adding more server data

The Map is great for keeping all the par-server data, not only the set of active stations. I assume you will need to store dispatcher objects once you start streaming the stations into voice channels etc. You can pack all this to a server class and have the Map store instances of such class for each server.

Upvotes: 2

Related Questions