SwingBot Plugin Overview:
SwingBot sends and receives events via the JerkLib IRC library. You can find all the different events that the plugins could possibly receive by looking in JerkLib.events. By the time the plugins actually receive one of those events , it has been wrapped in a SwingBotEvent (swingbot.eventhandler). SwingBot has one event of its own. The ExtendedPrivMsg event. This event extends the PrivMsgIRCEvent interface from JerkLib . It adds the additional methods
- public String getTellWho()
- public boolean isTell()
- public String getCommand()
- public String getArgs()
ExtendedPrivMsg (EPMSG) will parse the message found in PrivMsgIRCEVent.
EPMG will decide if the message is a tell. A tell is a request for the bot to tell someone about *something*. You can check if message is a tell by epmg.isTell().
If the message is in fact a tell you can find the nick of who you are supposed to tell by epmg.getTellWho().
# a "tell" message. request to tell mohadib about jdic
~tell mohadib about jdic
EPMG can parse a "command" and possibly a "arg". EPMG uses the strings returned from the getReservedWords()
method in each SwingBotPlugin to find "commands". Plugin writers should list all the possible command triggers for a given plugin
in this method. Example- Here is the factoid plugin's implementation of getReservedWords().
public String[] getReservedWords() {
return new String[]{ "factoid" , "stats" , "forget"};
}
EPMG will use this list (As well as the lists provided by other active plugins) to search messages for "commands". Example.
~stats
EPMG would parse this as "stats" being the command and null argument
~forget somefactoid
EPMG would parse this as "forget" being the command and somefactoid being the argument.
~forget hello world
EPMG would parse this as "forget" being the command and "hello world" being the argument.
~blah
EPMG would parse this as a null "command" because "blah" does not match any of the strings returned by getReservedWords().
"blah" would be parsed as the arg.
If EPMG can not parse a command then it will set the command to null and put the rest of the message in the argument. Keep in mind
that EPMG will still parse "tells" even if it does not reconize a command in the msg.
Most plugins can use EPMG. Just set getReservedWords() to return the strings your plugin would consider a command.
However the syntax of the msg its self must be in one of the following forms:
- tell person about command
- tell person about command args
- tell person about word // tell with a null command and word as the arg
- command args
- command
- word // null command and word as the arg
SwingBot also relays msgs not addressed to it. Message that do not start with ~ or BotName and don't come in a /msg are considered to not be addressed to the bot. SwingBot will pass the plugins a PrivMsgIRCEvent wrapped in a SwingBotEvent.
Now a little about PrivMsgIRCEvent. PrivMsgIRCEvent (PMG) is an event directly from JerkLib events. Here are the methods in a PrivMsgIRCEvent implementation: (these mehods can also be found in ExtendedPrivMsg as it extends PrivMsgIRCEvent)
- public final IRCChannel getChannel()
- public final String getNick()
- public final Type getType()
- public final String getRawEventData()
- public final String getHost()
- public final int getPort()
- public final IRCConnection getConnection()
- public final String getMessage()
IRCChannel and IRCConnection will allow you to speak to a channel or send someone a direct message as well as provide other methods that you would expect to find in a IRC lib., check the javadocs or the source for more information. Now I will go over an example plugin. The plugin is named ExamplesPlugin , this is because the plugin will point you at a URL full of examples for a given java term.
18:39 < mohadib > ~example socket
18:39 <SwingBot> mohadib, some examples of using socket may be be found at http://javaalmanac.com/cgi-bin/search/find.pl?words=socket.
package swingbot.plugins;
import swingbot.SwingBot;
import swingbot.eventhandler.ExtendedPrivMsg;
import swingbot.eventhandler.SwingBotEvent;
/* all plugins must implement SwingBotPlugin */
public class ExamplesPlugin implements SwingBotPlugin {
private SwingBot bot;
private final String exampleString =
"http://javaalmanac.com/cgi-bin/search/find.pl?words=";
/* all plugins must accept an instance of SwingBot in the constructor */
public ExamplesPlugin(SwingBot bot) {
this.bot = bot;
}
public SwingBotPlugin.Handled receiveEvent(SwingBotEvent e) {
/*
* The example plugin only uses ExtendedPrivMsg events as the commands it
* responds too are parsed by ExtendedPrivMsg. So , if the type of the event
* that the received SwingBotEvent wraps is not an ExtendedPrivMsg , We will
* return SwingBotPlugin.Handled.NOTHANDLED (an enum found in the
* SwingBotPlugin interface).
*/
if(e.getType() != SwingBotEvent.Type.EXTENDED_PRIVMSG){
return SwingBotPlugin.Handled.NOTHANDLED;
}
/*
* The actual event we want to work with is wrapped in the SwingBotEvent as
* an IRCEvent. SO to get the actual ExtendedPrivMsg we will call getEvent()
* on the SwingBotEvent instance and cast to ExtendedPrivMsg.
*/
ExtendedPrivMsg pmg = (ExtendedPrivMsg)e.getEvent();
/*
* If the command is null or does not equal the String "example" return not
* handled
*/
if(pmg.getCommand() == null ||
!pmg.getCommand().equalsIgnoreCase("example")){
return SwingBotPlugin.Handled.NOTHANDLED;
}
/* if the msg is a "tell" request (see above) */
if(pmg.isTell()){
/* NICK TO TELL IS NOT IN CHANNEL
* here we ask the IRCChannel to give us the list of nick so we can
* see if there is some to tell with the requested "tell nick" */
if(!pmg.getChannel().getNicks().contains(pmg.getTellWho().toLowerCase())){
try{
/*
* if nick is not in channel use the IRCChannel to channelSay() back
* to the person who requested the tell , and inform them that the
* person is in fact.. not there :p
*/
pmg.getChannel().channelSay(pmg.getNick() + ", " +
pmg.getTellWho().toLowerCase()+ " is not in " +
pmg.getChannel().getName());
}catch(Exception e1){ e1.printStackTrace();}
}
/* DONT TALK TO SELF */
else if(pmg.getTellWho().equalsIgnoreCase(bot.getBotInfo().getNick())){
try{
pmg.getChannel().channelSay
( pmg.getNick() + ", I don't talk to myself.");
}catch(Exception e1){e1.printStackTrace();}
}
/* TELL EXAMPLE */
else{
try{
pmg.getChannel().channelSay
(pmg.getTellWho() + ", some examples of using " +
pmg.getArgs() + " may be be found at " +
exampleString + pmg.getArgs().toLowerCase() + ".");
}catch (Exception e1) { e1.printStackTrace();}
}
return SwingBotPlugin.Handled.HANDLEDSTOP;
}
else{
if(!e.isDirectMsg()){
/* TELL EXAMPLE */
try{
pmg.getChannel().channelSay
(pmg.getNick() + ", some examples of using " +
pmg.getArgs() + " may be be found at " +
exampleString + pmg.getArgs() + ".");
}catch (Exception e1) { e1.printStackTrace();}
}
else{
/*
* SwingBotEvent.isDirectMsg() tested true. This means that some one has
* /msg'ed us. So we will use IRCConnection. privateSay(who , msg) to
* /msg them back. You will notice that the "tell" section above does
* not work correctly with DirectMsgs, but you get the point. Check the
* source of the factoid plugin. it completely works with DirectMsgs.
*/
try{
pmg.getConnection().privateSay
(pmg.getNick() , "some examples of using " +
pmg.getArgs() + " may be be found at " +
exampleString + pmg.getArgs() + ".");
}catch (Exception e1) {
e1.printStackTrace();
}
}
return SwingBotPlugin.Handled.HANDLEDSTOP;
}
}
public String getUsage() {
return "~example sockets";
}
public String getAuthor() {
return "mohadib";
}
public String getHelpName() {
return "example";
}
public String[] getReservedWords() {
return new String[] { "example" };
}
}
Thats the basics. Check the API to see what else you can do. And feel free to stop by ##swing @ freenode.net and ask me (mohadib) or pchapman
any questions you might have.
Please email plugins, changes, anf flames to mohadib@openactive.org.
svn co svn://www.javanub.net/home/mohadib/svn/repo/swingbot and svn co svn://www.javanub.net/home/mohadib/svn/repo/jerklib
