Skip to content
TheUnknownOne edited this page Jul 9, 2013 · 1 revision

Scripting/Server/Command Cooldown

Next step — reducing abuse and load on your server.

Commands you assign cooldowns can be used only once in a given amount of time. Also those commands will be on cooldown upon login. So if, for example, the /me command has 10 seconds cooldown player will be unable to use it for 10 seconds after login.

Duration

It is better to have cooldowns defined in one place in case you will need to change it layer. Global variables outside of ({ }).

// Cooldowns are in seconds.
var SHORT_COOLDOWN = 5;
var STANDARD_COOLDOWN = 10;
var LONG_COOLDOWN = 30;

Saving last date time used

For this we need to have a class registered for users. You can modify your existing one if there is any.

function POUser(id) {
    this.id = id;
    this.last_used = {};
    this.logged_in_datetime = (new Date()).getTime();
}

SESSION.registerUserFactory(POUser);

Command definition

Command definition need to be changed from the one in Handling player commands a bit (only relevant part will be shown).

function POHandlers() {
    // Basic ones will have priority over special ones.
    // Number is an auth level.
    this.basic_handlers = {
        "0": {
            commands: { handler: command_commands },
            me: { handler: command_me, cooldown: LONG_COOLDOWN },
            rules: { handler: command_rules }
        },
        "1": {
            mute: { handler: command_mute },
            unmute: { handler: command_unmute }
        },
        "2": {
            warn: { handler: command_warn }
        },
        "3": {
            lock: { handler: command_lock }
        }
    };
    // Other code is as usual. special_handlers need to be modified the same way.
}

handler is a command function (previously the only data). cooldown is, well, cooldown.

Handling

Now check itself should happen in a handle_command() function we had earlier. Change if (handler) block to this code.

if (handler) {
    // Check cooldown first.
    var allowed_to_run = true;
    var cooldown = handler.cooldown;
    if (cooldown) {
        var last_used_datetime = src_object.last_used[command_name];
        if (!last_used_datetime) {
            last_used_datetime = src_object.logged_in_datetime;
        }
        var current_datetime = (new Date()).getTime();
        // Update datetime even if command was already on cooldown. Wait properly, don't spam it.
        src_object.last_used[command_name] = current_datetime;
        if (Math.abs(current_datetime - last_used_datetime) < (cooldown * 1000)) {
            allowed_to_run = false;
        }
    }
    if (allowed_to_run) {
        // Call.
        handler.handler(chan, src, data);
    } else {
        // Warn.
        sys.sendMessage(
            src,
            "Cooldown for /" + command_name
                + " command has not expired yet. Wait for "
                + cooldown + " seconds.",
            chan
        );
    }
}