This page was written for DMDirc version 0.6.
The contents may not be applicable to earlier or later versions.
This page will show you how to create a basic plugin. DMDirc plugins are written in java, compiled and then put into special jar files which the client will use. This document will show you how to make a plugin that registers a command and a config setting.
All plugins need to extend com.dmdirc.plugins.Plugin, most IDEs will be able to automatically generate a skeleton class that will create stub methods for those that you need to override. For this example we are doing to use com.dmdirc.wiki.basicplugin as the package name for the plugin.
package com.dmdirc.wiki.basicplugin; import com.dmdirc.plugins.Plugin; /** * This is a basic plugin to document the DMDirc plugin system. * * @author Shane 'Dataforce' Mc Cormack */ public class BasicPlugin extends Plugin { /** * Create a new instance of BasicPlugin. */ public BasicPlugin() { super(); } /** {@inheritDoc} */ @Override public void onLoad() { } /** {@inheritDoc} */ @Override public void onUnload() { } }
As you can see, there are two methods here that have been overriden by the plugin, onLoad and onUnload these are called when your plugin is loaded and unloaded by the plugin system, and should be used for setup and cleanup.
This plugin doesn't do much, so lets define a config setting for it to use.
First of all we need to import the Identity classes
import com.dmdirc.config.Identity; import com.dmdirc.config.IdentityManager;
And then we can modify our onLoad method:
/** {@inheritDoc} */ @Override public void onLoad() { // Get the Identity instance used to store default settings for plugins final Identity defaults = IdentityManager.getAddonIdentity(); // Add the setting defaults.setOption("plugin-BasicPlugin", "general.message", "Hello world!"); }
Strictly you don't need to define settings before they can be used, you can provide a default when calling getOption(), however by defining the setting here it allows users to tab complete it in the /set command.
For plugins to be able to be used by DMDirc, they must define a plugin.info file in the META-INF folder of the jar. This file allows DMDirc to see what plugins are useble in your client, request updates from http://addons.dmdirc.com and provide author information.
For this plugin we will just create a basic plugin.info, the values should be self-explanatory
version=1 author=Shane 'Dataforce' Mc Cormack <shane@dmdirc.com> name=basicplugin nicename=Basic Example Plugin description=Basic plugin to show how the plugin system works minversion=0 mainclass=com.dmdirc.wiki.basicplugin.BasicPlugin
Plugins need to be compiled into jar files to be able to be used. Your current directory structure should look something like this:
basicplugin/
|- META-INF
| `- plugin.info <------------------- Plugin Meta Info
`- com/
`- dmdirc/
`- wiki/
`- basicplugin/
`- BasicPlugin.java <----- Plugin Class file
if basicplugin/ is our current directory, we can create a useable jar like so:
javac -cp /home/shane/dmdirc/DMDirc.jar com/dmdirc/wiki/basicplugin/BasicPlugin.java jar -cf BasicPlugin.jar com/dmdirc/wiki/basicplugin/BasicPlugin.class META-INF/plugin.info
this jar can now be copied to the plugins directory inside your DMDirc configuation directory (Linux: ~/.DMDirc/, Windows: C:\Documents and Settings\username\Application Data\DMDirc, OS X: ~/Library/Preferences/DMDirc) and loaded with /loadplugin BasicPlugin.jar.
Once you have loaded the plugin, you can do /set plugin-BasicPlugin general.message to see that the config setting has been registered.
Now that we have a plugin with a config setting, we want to actually do something with it. Lets make a command that echos the value of the setting to the current window.
First thing we should do is make the command, so we create a new file in the same folder as BasicPlugin.java called BasicPluginCommand.java, this command is going to be a global command, so it needs to extend com.dmdirc.commandparser.commands.GlobalCommand.
Once we fill in some of the getter methods, we end up with something like this:
package com.dmdirc.wiki.basicplugin; import com.dmdirc.commandparser.commands.GlobalCommand; import com.dmdirc.ui.interfaces.InputWindow; /** * This is a basic command. * * @author Shane 'Dataforce' Mc Cormack */ public class BasicPluginCommand extends GlobalCommand { /** * Create a new instance of BasicPluginCommand. */ public BasicPluginCommand() { super(); } /** {@inheritDoc} */ @Override public void execute(final InputWindow origin, final boolean isSilent, final String... args) { } /** {@inheritDoc} */ @Override public String getName() { return "basicplugin"; } /** {@inheritDoc} */ @Override public boolean showInHelp() { return true; } /** {@inheritDoc} */ @Override public String getHelp() { return "basicplugin - Shows the value of the plugin-BasicPlugin.general.message Setting"; } }
This command will now show up in /help, but won't actually do anything. To make it so something we need to edit the execute() method.
We want to be able to get a value from the config, so we need to import the Identity Manager class
import com.dmdirc.config.IdentityManager;
and then we can add some code to show a line in the window:
/** {@inheritDoc} */ @Override public void execute(final InputWindow origin, final boolean isSilent, final String... args) { // Get the config setting final String output = IdentityManager.getGlobalConfig().getOption("plugin-BasicPlugin", "general.message"); // Output it to the window // // FORMAT_OUTPUT is a constant that refers to the formatter used for general command output sendLine(origin, isSilent, FORMAT_OUTPUT, output); }
Now to make this command work, we need to edit BasicPlugin.java some more to make it register the command with the CommandManager.
Firstly we need to import com.dmdirc.commandparser.CommandManager
import com.dmdirc.commandparser.CommandManager;
Now we can add the code to register the command.
We now need to create and store the instance of our command, create a new variable in the class:
/** The Command we've registered. */ private BasicPluginCommand command;
and then modify onLoad() and onUnload()
/** {@inheritDoc} */ @Override public void onLoad() { // Get the Identity instance used to store default settings for plugins final Identity defaults = IdentityManager.getAddonIdentity(); // Add the setting defaults.setOption("plugin-BasicPlugin", "general.message", "Hello world!"); // Register our command command = new BasicPluginCommand(); CommandManager.registerCommand(command); } /** {@inheritDoc} */ @Override public void onUnload() { CommandManager.unregisterCommand(command); command = null; }
Now we can recompile the plugin:
javac -cp /home/shane/dmdirc/DMDirc.jar com/dmdirc/wiki/basicplugin/BasicPlugin.java com/dmdirc/wiki/basicplugin/BasicPluginCommand.java jar -cf BasicPlugin.jar com/dmdirc/wiki/basicplugin/BasicPlugin.class com/dmdirc/wiki/basicplugin/BasicPluginCommand.class META-INF/plugin.info
Now you can copy the BasicPlugin.jar to your plugins directory and overwrite the old one, and then do /reloadplugin basicplugin, now try /basicplugin
You should see a line added to the current window that says “Hello World!”, you can change this line using /set plugin-BasicPlugin general.message Foo! and the /basicplugin command will use the new value.
And thats your first basic plugin. A pre-compiled version with source can be found here: basicplugin.jar
The plugin system is incredibly powerful, and can do alot more than the simple things shown here, some of our “core” features are also implemented as plugins, such as DCC, and Logging and other such as the /nowplaying command. Other plugins more elaborate plugins that have been created include a whole new UI (web based) and spell checking in the input field.
More documentation pages will be added over time to show how you can hook into the actions system to react to events or create your own windows.