mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-02 17:29:22 +01:00
119 lines
6.7 KiB
Plaintext
119 lines
6.7 KiB
Plaintext
Ok, some explanation of the capabilities system is probably in
|
|
order. With most IRC bots (including the ones I've written myself
|
|
prior to this one) "what a user can do" is set in one of two ways. On
|
|
the *really* simple bots, each user has a numeric "level" and commands
|
|
check to see if a user has a "high enough level" to perform some
|
|
operation. On bots that are slightly more complicated, users have a
|
|
list of "flags" whose meanings are hardcoded, and the bot checks to
|
|
see if a user possesses the necessary flag before performing some
|
|
operation. Both methods, IMO, are rather arbitrary, and force the
|
|
user and the programmer to be unduly confined to less expressive
|
|
constructs.
|
|
|
|
This bot is different. Every user has a set of "capabilities" that is
|
|
consulted every time they give the bot a command. Commands, rather
|
|
than checking for a user level of 100, or checking if the user has an
|
|
"o" flag, are instead able to check if a user has the "owner"
|
|
capability. At this point such a difference might not seem
|
|
revolutionary, but at least we can already tell that this method is
|
|
self-documenting, and easier for users and developers to understand
|
|
what's truly going on.
|
|
|
|
If that was all, well, the capability system would be "cool", but not
|
|
many people would say it was "awesome". But it *is* awesome! Several
|
|
things are happening behind the scene that make it awesome, and these
|
|
are things that couldn't happen if the bot was using numeric
|
|
userlevels or single-character flags. First, whenever a user issues
|
|
the bot a command, the command dispatcher checks to make sure the user
|
|
doesn't have the "anticapability" for that command. An anticapability
|
|
is a capability that, instead of saying "what a user can do", says
|
|
what a user *cannot* do. It's formed rather simply by adding a dash
|
|
("-") to the beginning of a capability; "rot13" is a capability, and
|
|
"-rot13" is an anticapability. Anyway, when a user issues the bot a
|
|
command, perhaps "calc" or "help", the bot first checks to make sure
|
|
the user doesn't have the "-calc" or the "-help" capabilities before
|
|
even considering responding to the user. So commands can be turned on
|
|
or off on a *per user* basis, offering fine-grained control not often
|
|
(if at all!) seen in other bots.
|
|
|
|
But that's not all! The capabilities system also supports *Channel*
|
|
capabilities, which are capabilities that only apply to a specific
|
|
channel; they're of the form "#channel,capability". Whenever a user
|
|
issues a command to the bot in a channel, the command dispatcher also
|
|
checks to make sure the user doesn't have the anticapability for that
|
|
command *in that channel*, and if the user does, the bot won't respond
|
|
to the user in the channel. Thus now, in addition to having the
|
|
ability to turn individual commands on or off for an individual user,
|
|
we can now turn commands on or off for an individual user on an
|
|
individual channel!
|
|
|
|
So when a user "foo" sends a command "bar" to the bot on channel
|
|
"#baz", first the bot checks to see if the user has the anticapability
|
|
for the command by itself, "-bar". If so, it returns right then and
|
|
there, completely ignoring the fact that the user issued that command
|
|
to it. If the user doesn't have that anticapability, then the bot
|
|
checks to see if the user issued the command over a channel, and if
|
|
so, checks to see if the user has the antichannelcapability for that
|
|
command, "#baz,-bar". If so, again, he returns right then and there
|
|
and doesn't even think about responding to the bot. If neither of
|
|
these anticapabilities are present, then the bot just responds to the
|
|
user like normal.
|
|
|
|
From a programming perspective, capabilties are easy to use and
|
|
flexible. Any command can check if a user has any capability, even
|
|
ones not thought of when the bot was originally written.
|
|
Commands/Callbacks can add their own capabilities -- it's as easy as
|
|
just checking for a capability and documenting somewhere that a user
|
|
needs that capability to do something.
|
|
|
|
From an end-user perspective, capabilities remove a lot of the mystery
|
|
and esotery of bot control, in addition to giving the user absolutely
|
|
finegrained control over what users are allowed to do with the bot.
|
|
Additionally, defaults can be set by the end-user for both individual
|
|
channels and for the bot as a whole, letting an end-user set the
|
|
policy he wants the bot to follow for users that haven't yet
|
|
registered in his user database. It's really a revolution!
|
|
|
|
There are several default capabilities the bot uses. The most
|
|
important of these is the "owner" capability. This capability allows
|
|
the person having it to use *any* command. It's best to keep this
|
|
capability reserved to people who actually have access to the shell
|
|
the bot is running on.
|
|
|
|
There is also the "admin" capability for non-owners that are highly
|
|
trusted to administer the bot appropriately. They can do things such
|
|
as change the bot's nick, globally enable/disable commands, cause the
|
|
bot to ignore a given user, set the prefixchar, report bugs, etc.
|
|
They generally cannot do administration related to channels, which is
|
|
reserved for people with the next capability.
|
|
|
|
People who are to administer channels with the bot should have the
|
|
#channel,op capability -- whatever channel they are to administrate,
|
|
they should have that channel capability for "op". For example, since
|
|
I want inkedmn to be an administrator in #supybot, I'll give him the
|
|
#supybot,op capability. This is in addition to his admin capability,
|
|
since the admin capability doesn't give the person having it control
|
|
over channels. #channel,op is used for such things as
|
|
giving/receiving ops, kickbanning people, lobotomizing the bot,
|
|
ignoring users in the channel, and managing the channel capabilities.
|
|
The #channel,op capability is also basically the equivalent of the
|
|
owner capability for capabilities involving #channel -- basically
|
|
anyone with the #channel,op capability is considered to have all
|
|
positive capabilities and no negative capabilities for #channel.
|
|
|
|
One other globally important capability exists: "trusted". This is a
|
|
command that basically says "This user can be trusted not to try and
|
|
crash the bot." It allows users to call commands like Math.icalc,
|
|
which potentially could cause the bot to begin a calculation that
|
|
could potentially never return (a calculation like 10**10**10**10).
|
|
Another command that requires the trusted capability is Utilties.re,
|
|
which (due to the regular expression implementation in Python (and any
|
|
other language that uses NFA regular expressions, like Perl or Ruby or
|
|
Lua or ...) which can allow a regular expression to take exponential
|
|
time to process). Consider what would happen if someone gave the
|
|
bot the command 're [format join "" s/./ [dict go] /] [dict go]'
|
|
|
|
Other plugins may require different capabilities; the Factoids plugin
|
|
requires #channel,factoids, the Topic plugin requires #channel,topic,
|
|
etc.
|