mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-11-03 17:17:23 +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.
 |