mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 05:09:23 +01:00
151b2f829b
use, as well as all the docs being in SGML now.
207 lines
10 KiB
Plaintext
207 lines
10 KiB
Plaintext
<!DOCTYPE article SYSTEM "supybot.dtd">
|
|
|
|
<article>
|
|
<articleinfo>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Jeremiah</firstname>
|
|
<surname>Fincher</surname>
|
|
</author>
|
|
<editor>
|
|
<firstname>Daniel</firstname>
|
|
<surname>DiPaolo</surname>
|
|
<contrib>DocBook translator</contrib>
|
|
</editor>
|
|
</authorgroup>
|
|
<title>Supybot capabilities system explanation</title>
|
|
<revhistory>
|
|
<revision>
|
|
<revnumber>0.1</revnumber>
|
|
<date>18 Feb 2004</date>
|
|
<revremark>Initial Docbook translation</revremark>
|
|
</revision>
|
|
</revhistory>
|
|
</articleinfo>
|
|
<sect1>
|
|
<title>Introduction</title>
|
|
<subtitle>
|
|
Supybot's capabilities overview and comparisons to other bots
|
|
</subtitle>
|
|
<para>
|
|
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 <emphasis>really</emphasis> 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.
|
|
</para>
|
|
<para>
|
|
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 <varname>o</varname>
|
|
flag, are instead able to check if a user has the
|
|
<capability>owner</capability> 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.
|
|
</para>
|
|
</sect1>
|
|
<sect1>
|
|
<title>What sets supybot's capabilities apart</title>
|
|
<para>
|
|
If that was all, well, the capability system would be
|
|
“cool”, but not many people would say it was
|
|
“awesome”. But it <emphasis>is</emphasis> 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 <emphasis>cannot</emphasis> do. It's
|
|
formed rather simply by adding a dash (“-”) to the
|
|
beginning of a capability; <botcommand>rot13</botcommand> is a
|
|
capability, and <botcommand>-rot13</botcommand> is an
|
|
anticapability. Anyway, when a user issues the bot a command,
|
|
perhaps <botcommand>calc</botcommand> or
|
|
<botcommand>help</botcommand>, the bot first checks to make sure
|
|
the user doesn't have the <capability>-calc</capability> or the
|
|
<capability>-help</capability> capabilities before even
|
|
considering responding to the user. So commands can be turned on
|
|
or off on a <emphasis>per user</emphasis> basis, offering
|
|
finegrained control not often (if at all!) seen in other bots.
|
|
</para>
|
|
<sect2>
|
|
<title>Channel capabilities</title>
|
|
<para>
|
|
But that's not all! The capabilities system also supports
|
|
<emphasis>Channel</emphasis> capabilities, which are
|
|
capabilities that only apply to a specific channel; they're of
|
|
the form <capability>#channel.capability</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 <emphasis>in that
|
|
channel</emphasis> 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!
|
|
</para>
|
|
<para>
|
|
So when a user <nick>foo</nick> sends a command
|
|
<botcommand>bar</botcommand> to the bot on channel
|
|
<channel>#baz</channel>, first the bot checks to see if the
|
|
user has the anticapability for the command by itself,
|
|
<capability>-bar</capability>. 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,
|
|
<capability>#baz.-bar</capability>. 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.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1>
|
|
<title>Motivations behind the capabilities system</title>
|
|
<sect2>
|
|
<title>A programmer's perspective</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</sect2>
|
|
<sect2>
|
|
<title>An end-user's perspective</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
It's really a revolution!
|
|
</para>
|
|
</sect1>
|
|
<sect1>
|
|
<title>Hard-coded supybot capabilities</title>
|
|
<para>
|
|
There are several default capabilities the bot uses. The most
|
|
important of these is the <capability>owner</capability>
|
|
capability. This capability allows the person having it to use
|
|
<emphasis>any</emphasis> command. It's best to keep this
|
|
capability reserved to people who actually have access to the
|
|
shell the bot is running on.
|
|
</para>
|
|
<para>
|
|
There is also the <capability>admin</capability> 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.
|
|
</para>
|
|
<para>
|
|
People who are to administer channels with the bot should have the
|
|
<capability>#channel.op</capability> capability -- whatever
|
|
channel they are to administrate, they should have that channel
|
|
capability for <capability>op</capability>. For example, since I
|
|
want <nick>inkedmn</nick> to be an administrator in
|
|
<channel>#supybot</channel>, I'll give him the
|
|
<capability>#supybot.op</capability> capability. This is in
|
|
addition to his <capability>admin</capability> capability, since
|
|
the <capability>admin</capability> capability doesn't give the
|
|
person having it control over channels.
|
|
<capability>#channel.op</capability> 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 <capability>#channel.op</capability> capability
|
|
is also basically the equivalent of the owner capability for
|
|
capabilities involving <channel>#channel</channel> –
|
|
basically anyone with the <capability>#channel.op</capability>
|
|
capability is considered to have all positive capabilities and no
|
|
negative capabilities for <channel>#channel</channel>.
|
|
</para>
|
|
<para>
|
|
One other globally important capability exists:
|
|
<capability>trusted</capability>. 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
|
|
<botcommand>Math.icalc</botcommand>, 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 <botcommand>Utilties.re</botcommand>, 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 <literal>re [strjoin "" s/./
|
|
[dict go] /] [dict go]</literal>.
|
|
</para>
|
|
</sect1>
|
|
</article>
|
|
|
|
|