Dynamic Command Plugins

April 12th, 2009

I finished a major feature of OrtzIRC recently, so I thought I would write a bit about how it works.

First of all, a big thanks to Max for being the grease when my gears wouldn’t turn, so to speak. :P And for talking me into doing commands this way instead of mine, which would not have worked out as well.

One of the goals with OrtzIRC is extensibility. OrtzIRC will have many categories of plugins which you write with your favorite .NET language, compile, and place in the plugins folder, much like Paint.NET. (Unlike Paint.NET, OrtzIRC will stay open source. wink wink) The first plugin category is commands.

Here’s what the “say” command looks like:

namespace OrtzIRC.Commands
{
    using OrtzIRC.Common;
    using OrtzIRC.PluginFramework;
 
    /// <summary>
    /// Parts a channel
    /// </summary>
    [Plugin]
    public class Say : ICommand
    {
        /// <summary>
        /// Sends a message to the current channel
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="message"></param>
        public void Execute(Channel channel, string message)
        {
            channel.Say(message);
        }
    }
}

Like with most IRC clients, “say” is the only command called automatically (when you type into the command box without specifying a command).

Commands must follow these rules to work properly:

  1. The class must implement the ICommand interface. At the moment this interface just lets the plugin loader know that it’s a command.
  2. The class must also have the Plugin attribute. Plugin takes an optional string parameter to specify the name of the plugin (in this case the name of the command you type to execute the command, ie “/say”) otherwise the plugin’s name is the name of the class.
  3. The command class must have at least one public Execute method. This method is what OrtzIRC calls when you type in a command.
  4. The type of the first parameter in each of the Execute methods must be one of the following:
    • Channel
    • Server
    • PrivateMessageSession

    This parameter represents the context in which the command was executed, in other words, the window. (A channel window, PM window…)

  5. The type of each of the remaining parameters must be either string or ChannelInfo. The ChannelInfo object is simply to let the command know that the user specified a channel name, ie “#luahelp”.
  6. If you want autocomplete support the Execute methods must each have proper XML docs. (This has not yet been implemented, I will discuss it in more detail when it is)

If these rules are not followed, the command will either not be loaded or not called when the user attempts to execute it. When a user types in a command, the plugin system looks through the commands it has loaded and looks for one that meets all these requirements and whose parameters match the parameters given by the user.

This command system is much more dynamic and easier on the programmer than other systems I have seen, which usually require the programmer to manage arguments manually and add a lot of redundant code.

Questions, comments, suggestions welcome.


Kick It on DotNetKicks.com
Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Live
  • StumbleUpon
  • TwitThis
blog comments powered by Disqus