Skip to content

Creating Plugins

Andrei Zbikowski edited this page Aug 16, 2016 · 1 revision

Creating plugins for Jeff is a fairly simple and straight-forward process. Jeff utilizes the plugin infrastructure built-into dscord, so you can start off with the following simple template:

Note, its advised to develop plugins in the 'plugins' subdirectory within your jeff repo.

dub.json

{
  "name": "myplugin",
  "targetType": "dynamicLibrary",
  "dependencies": {
     "jeff": {"path": "../../jeff"},
  }
}

src/myplugin.d

module myplugin;

// Import this to get all of our dscord types/functions/etc
import dscord.core;

// Create a new class that inherits from dscord's plugin
class MyPlugin : Plugin {}

// Finally, write a magic plugin that will allow our dynamic library to be loaded
extern (C) Plugin create() {
  return new MyPlugin;
}

Configuration

To support configuration within your plugin, simply add the following constructor to your Plugin implementation:

this() {
  auto opts = new PluginOptions;
  opts.useConfig = true;
  super(opts);
}

This will tell dscord and jeff that your plugin intends to use a configuration file. Next, its recommend you load settings into local attributes within a load override, like so:

bool mySetting = false;

override void load(Bot bot, PluginState state = null) {
  super.load(bot, state);

  if (this.config.has("my_setting")) {
    this.mySetting = this.config["my_setting"].get!bool;
  }
}

Commands

Commands can be created using UDAs, like so:

@Command("test")
@CommandDescription("This is a test command")
void commandTest(CommandEvent event) {
  event.msg.replyf("It works!");
}

Event Listeners

Events can be listened to using UDAs, like so:

@Listener!MessageCreate()
void onMessageCreate(MessageCreate event) {
  this.log.infof("A message was created: %s", event);
}

Syncing state & supporting reloading

For your plugin to support dynamic reloading, it may need to sync some state between instances. This can be achieved by doing the following:

  1. Add @Synced UDA's to any attributes you'd like synced between instances:
@Synced bool myValue;
@Synced SomeSpecialType specialValue;
  1. Call stateLoad in a load override:
override void load(Bot bot, PluginState state = null) {
  super.load(bot, state);
  this.stateLoad!MyPlugin(this.state);
}
  1. Call stateUnload in a unload override:
override void unload(Bot bot) {
  this.stateUnload!MyPlugin(this.state);
  super.unload(bot);
}

Clone this wiki locally