-
Notifications
You must be signed in to change notification settings - Fork 170
Handling player commands
Scripting/Server/Handling player commands
Now you want handling for player commands. Use code snippets below to do it gracefully.
Note: assuming commands used in the /command parameters
or !command parameters
form.
You will need this function to write less code later. It will add all properties of a from
object to to
object. If that property already exist in to
it will be overwritten. In this case it will be used to add commands from lower level auths to higher level ones.
function push_properties(from, to) {
for (var p in from) {
to[p] = from[p];
}
}
The following class describes which commands are accessible to players.
0
in basic_handlers describes commands that normal players can use. 1
- additional commands for moderators, 2
- for administrators, 3
- for owners. Higher level auths can use commands of lower level ones so you don't need to write them more than once.
Commands themselves are written in the command_name: command_function
syntax. command_name
is a command that a player need to enter. command_function is a name of a function that will handle given command (see section below). For example, me: command_me
says that /me
command should be handled with a function named command_me
.
function POHandlers() {
// Basic ones will have priority over special ones.
// Number is an auth level.
this.basic_handlers = {
"0": {
commands: command_commands,
me: command_me,
rules: command_rules
},
"1": {
mute: command_mute,
unmute: command_unmute
},
"2": {
warn: command_warn
},
"3": {
lock: command_lock
}
};
// Will add commands to higher level auths.
for (var i = 0; i < 3; ++i) {
for (var j = i + 1; j <= 3; ++j) {
push_properties(this.basic_handlers[i], this.basic_handlers[j]);
}
}
// If you have additional auths that aren't in DB you can add commands to them like this.
// This example can be used to hold data for some "Channel master" role implemented by your script.
// These commands are additional to the basic ones.
this.special_handlers = {
channel_master: {
topic: command_topic
}//,
// some_other_auth = {
// some_other_command: command_some_other_command
// }
};
}
This will create a global object HANDLERS
to hold data described above.
var HANDLERS = new POHandlers();
Functions that will handle command should be in the following form:
function function_name_here(chan, src, data) {
// code here
}
chan
is a channel id from which a command was issued. src
is id of player that called a command. data
is parameter string (you need to parse this yourself).
Note: command handlers should not check player's auth themselves unless they behave differently for different auths. This is because "can player even use this?" check is performed automatically elsewhere.
Example of (very basic) /me
command implementation:
function command_me(chan, src, data) {
if (data.length == 0) return; // nothing to print
sys.sendAll("***" + sys.name(src) + " " + data, chan);
}
Then if you use /me blah blah
in chat window it will print *** Your_nickname blah blah
instead of usual Your_nickname: blah blah
message.
You will need this function to check whether player has enough authority to use a command. It will call a handler for it if it is possible.
Code assumes there is a user function registered with registerUserFactory()
and levels is a hash inside that stores true/false for a given non-DB auth. If you don't use them you don't need it just yet.
function handle_command(command_name, chan, src, data) {
var src_auth = sys.auth(src);
if ((src_auth < 0) || (src_auth > 3)) return; // What auth is this again?
var src_object = SESSION.users(src);
var handler = HANDLERS.basic_handlers[src_auth][command_name];
if (!handler) {
// Non-DB auths here. Remove if not needed.
var non_db_levels = ["channel_master"]; // Example.
for (var index in non_db_levels) {
var level = non_db_levels[index];
if (src_object.levels[level]) {
var special_handler = HANDLERS.special_handlers[level][command_name];
if (special_handler) {
handler = special_handler;
break; // Command found. Nothing else to do.
}
}
}
}
if (handler) {
handler(chan, src, data);
}
}
Now you need to make it actually called by PO. There is a beforeChatMessage
event that can help with this. Therefore a basic implementation would be like this:
({
beforeChatMessage: function(src, message, chan) {
if ((message.length > 1) && (message[0] == '/' || message[0] == '!')) {
// Command.
sys.stopEvent(); // do not print this message automatically
var command, command_data = "";
var pos = message.indexOf(' ');
if (pos == -1) {
command = message.substring(1).toLowerCase();
} else {
command = message.substring(1, pos).toLowerCase();
command_data = message.substr(pos + 1);
}
handle_command(command, chan, src, command_data);
}
}
})