mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-24 03:33:11 +01:00
108 lines
6.7 KiB
Plaintext
108 lines
6.7 KiB
Plaintext
Ok, some 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 finegrained 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, compltely 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 programmatical 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 admin capability doesn't give the
|
|
person having it control over channels. #channel.op is object 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 the someone gave
|
|
the bot the command 're [strjoin "" s/./ [dict go] /] [dict go]'
|
|
|
|
Other plugins may require different capabilities; the Factoids plugin requires
|
|
#channel.factoids, the Topic plugin requires #channel.topic, etc.
|