Overview of IRCmagic Plug-ins
At the heart of IRCmagic is a fast, lean plug-in engine. IRCmagic's plug-in engine makes it possible to add and remove plug-ins on-the-fly, without disrupting other functions of IRCmagic. Plug-ins written for IRCmagic are able to respond to every event that Ircle sends. IRCmagic optionally saves plug-in settings whenever the plug-in is unloaded, and restored when the plug-in is loaded again. IRCmagic also automatically provides a user interface to allow users to enable, disable, and configure your plug-in. Lastly, IRCmagic plug-ins are very similar to stand-alone scripts - so it takes little effort to port an existing script to an IRCmagic plug-in.
A plug-in template named "PluginTemplate.as" is included in the Documentation folder of IRCmagic. The template contains the basic elements required by all IRCmagic plug-ins, and serves as a starting point for creating new plug-ins.
This section shows you how IRCmagic plug-ins are constructed, and provides a short tutorial on building your own plug-in.
The Anatomy of an IRCmagic Plug-in
IRCmagic plug-in scripts are simply normal Ircle scripts with some additional properties and handlers.
Certain properties and handlers must exist in a plug-in script in order for it to be compatible with IRCmagic's plug-in engine. These required properties and handlers allow IRCmagic to communicate and control plug-ins, and allow IRCmagic to provide support to all plug-ins in a standard way.
Five properties must exist in a plug-in for it to be compatible with IRCmagic's plug-in engine. These properties are described in detail below:
- pIrcleHandlers - This property is expected to be a list of strings, each string representing an Ircle event handler supported by this plug-in. If the list is empty, the plug-in will receive no Ircle events. If the list contains one or more strings that match the name of an Ircle event handler, the plug-in will receive the corresponding event when it is sent by Ircle. For example, if the list is {"idle","pubmsg"}, the plug-in will receive pubmsg events whenever others speak in a channel you are in, and will receive idle events.
- pCustomHandlers - This property is expected to be a list of strings, each string representing a custom event handler supported by this plug-in. Custom handlers are handlers that are invoked by users from the Ircle command line. If the list is empty, the plug-in will receive no custom events. If the list contains one or more strings, and the end user types a slash (/) followed by one of the handler names listed, the plug-in will receive the custom event.
For example, if the list is {"Command1","Command2"}, and the end user types /command1, IRCmagic calls the plug-in DoCommand() handler with command1 in the theCommand parameter. Your plug-in is expected to perform whatever actions are expected when the user invokes the custom handler.
- pEnabled - This property is expected to be set to true or false, representing the enabled state of your plug-in. plug-ins should toggle this value in the SetEnabled() handler, discussed later in this section.
- pEventsWhileDisabled -
NOTE: This property is deprecated and should no longer be used. See this change note for more details.
This property is expected to be set to true or false, representing whether or not the plug-in wishes to receive Ircle events while disabled. If this property is set to true, the plug-in will receive Ircle events even when the plug-in is disabled. If this property is set to false, then the plug-in will not receive Ircle events while the plug-in is disabled.
- pPlugData - This property is expected to be a list containing data (if any) the plug-in wishes to persist after the plug-in is unloaded, and restored the next time the plug-in loads.
This property should always be returned by the TerminatePlugin() handler. When the plug-in is unloaded, IRCmagic checks to see if this list contains anything. If so, IRCmagic automatically saves the data to a preferences file. The next time the plug-in is loaded, IRCmagic reads the data into memory and passes it to the plug-in in the savedData parameter of the InitPlugin() handler.
In addition to these properties, plug-ins may provide additional properties to enable optional plug-in support functions. These optional properties are listed below:
- pCustomStringTags - This optional property is expected to be a list of custom message tags that this plug-in provides in the form of {"<text>","<text>"}. If this property exists, IRCmagic attempts to call the ResolveCustomTag() handler in the plug-in when a message containing any custom tags is encountered in any IRCmagic setting. For more information on custom message tags, see How Custom Messages Work.
The IRCmagic plug-in template declares four additional properties for your convenience. These properties are also optional. In the plug-in template they are initialized in the InitPlugin() handler, and used in various handlers in the template:
- pMainScript - This property is set to the mainScript parameter in the InitPlugin() handler. This property is a "pointer" to the main script object (the IRCmagic script). Plug-ins can use this property to refer to the main script, or call handlers in the main script. For example, the ShowMessage() handler in the plug-in template uses this property to call the main script's ShowPluginMessage() handler in order to display plug-in messages in the current Ircle window.
- pMySelf - This property is set to the plugScript parameter in the InitPlugin() handler. This property is a "pointer" to the plug-in script object. plug-ins could use this property to refer to themselves, or call handlers from themselves. This is normally done by using the me or my keywords; therefore most plug-ins will not need this property.
Warning: This property may not be supported in future releases of IRCmagic.
- pMyName - This property is set to the plugName parameter in the InitPlugin() handler. This property is the file name of the plug-in at the last time it was loaded.
- pMyPath - This property is set to the plugPath parameter in the InitPlugin() handler. This property is the full path to the plug-in at the last time it was loaded.
Five handlers must exist in a plug-in for it to be compatible with IRCmagic's plug-in engine. These handlers are described in detail below:
- InitPlugin(mainScript, plugScript, plugName, plugPath, plugEnabled, savedData) - This handler is called when the plug-in is being loaded by IRCmagic. Six parameters are passed to the plug-in in this handler:
- mainScript - A "pointer" to the main script object (the IRCmagic script). In the plug-in template, this parameter is transferred to the pMainScript global property so that it can be accessed by other handlers.
- plugScript - A "pointer" to the plug-in script object. In the plug-in template, this parameter is transferred to the pMySelf global property so that it can be accessed by other handlers.
- plugName - The file name of the plug-in at the last time it was loaded. In the plug-in template, this parameter is transferred to the pMyName global property so that it can be accessed by other handlers.
- plugPath - The full path to the plug-in at the last time it was loaded. In the plug-in template, this parameter is transferred to the pMyPath global property so that it can be accessed by other handlers.
- plugEnabled - A boolean value (true or false) representing the enabled state of the plug-in the last time it was unloaded. In the plug-in template, this parameter is used to set the pEnabled required property by passing it to the SetEnabled() handler like so: my SetEnabled(plugEnabled)
- savedData - The plug-in data (if any) that was saved the last time the plug-in was unloaded. plug-ins should check to see if this parameter is an empty list ( {} ), and if not, set the pPlugData global property to it to restore plug-in settings to the state they were in the last time the plug-in was unloaded. The plug-in template does this with the following line:
if savedData is not {} then set pPlugData to savedData.
- TerminatePlugin() - This handler is called when the plug-in is being unloaded by IRCmagic. This handler has no parameters. Plug-ins should do all cleanup and prepair for being unloaded when this handler is called. If any plug-in data is to be saved while the plug-in is unloaded, the data should be returned as the result of this handler.
The plug-in template returns the pPlugData global property as the result of this handler. This data will be passed to the InitPlugin() handler in the savedData parameter when the plug-in is loaded again.
- Settings() - This handler is called when the user requests to edit the plug-in's settings from the IRCmagic user interface. If your plug-in implements a settings panel, the plug-in is expected to display a dialog box or window containing the plug-ins settings, and allow the user to change them. The plug-in template calls this handler from it's /pluginname custom command handler (DoCommand(theCommand, con, target, commandLine)).
Note: The return value of this handler is important. If the plug-in implements a settings dialog, then it must return true as the handler return value. If the plug-in does not implement a settings dialog, it should return false. When false is returned, IRCmagic displays a message to the user stating that the plug-in has no settings panel.
- SetEnabled(flag) - This handler is called when the end user attempts to enable or disable the plug-in via the IRCmagic user interface. The plug-in template calls this handler from the InitPlugin() and PluginName() handlers. This handler has one single parameter:
- flag - This parameter contains a boolean value (true or false), reflecting whether the plug-in should enable itself (true) or disable itself (false).
- DoCommand(theCommand, con, target, commandLine) - This handler is called when the end user types into the Ircle command line a slash (/) followed by one of the strings in the pCustomCommands global property of the plug-in. The plug-in template contains an example DoCommand() handler and shows how one might branch off to sub-handlers based on the contents of the theCommand parameter. The custom hanler that is used in the plug-in template shows how plug-ins should handle the standard on/off commands.
- theCommand - This parameter contains a string representing which custom command is being requested. The plug-in should examine theCommand and call the appropriate sub-handler.
- con - The connection number in which this command was issued.
- target - The name of the window or channel in which this command was issued.
- commandLine - The entire command line as typed by the user.
The following handler is only required if your plug-in contains the pCustomStringTags property, and the property is not empty. If the pCustomStringTags property is not found in a plug-in whn the plug-in is loaded by IRCmagic, this handler will not be called by IRCmagic.
- ResolveCustomTag(tagText) - This handler is called by IRCmagic when a message containing any of the tags contained in the plug-in property pCustomStringTags is encountered in any IRCmagic plug-in setting. This handler is expected to return the expanded output corresponding to the custom tag contained in the tagText parameter.
For example, if your pCustomStringTags property contains <time>, and IRCmagic calls your CustomMessage(tagText) handler with tagText equal to <time>, the handler might return something like 3:08:21 PM. For more information on custom message tags, see How Custom Messages Work.
The following global properties and handlers are built into IRCmagic, and acessible to plug-ins. Plug-ins may call these handlers in the following manner: pMainScript's Handler(parameters)
- gPrefsFolderPath - Contains the path to the new IRCmagic Preferences folder. This folder was moved from inside the Plugins folder to the IRCmagic Folder in version 1.2 of IRCmagic.
- ForceUnload() - Normally, if a script loaded in Ircle tells Ircle to unload, Ircle crashes due to the fact that after unloading a script and disposing of the script's memory, Ircle attempts to return a result to the script that told it to unload, which is disposed of, resulting in a crash. By launching a seperate small application to do the unloading, this handler provides a safe way for a plug-in to force IRCmagic to unload.
- IRC() - This handler displays the IRCmagic main dialog (click here for more information).
- IRCmagicPrefs() - This handler displays the IRCmagic Preferences dialog (click here for more information).
- GetPluginByName(pName) - This handler returns the loaded plugin object of the plug-in named pName. Plug-ins may use this handler to obtain other plug-in objects in order to control or manipulate them. The following example uses this handler to obtain the AutoGone plug-in object in order to determine the status of the Disable CTCP Sounds setting:
set autogonePlugin to pMainScript's GetPluginByName("AutoGone")
if autogonePlugin is not {} then
set gGoneFlags_Ref to (a reference to autogonePlugin's gGoneFlags)
set awaySlot to (item con of gGoneFlags_Ref)
set plugData to (autogonePlugin's pPlugData)
set soundsDisabled to (disableCTCPSounds of autogonePlugin's pPlugData)
end if
- BroadcastToConnection(con, msg) - This handler broadcasts msg to every window in connection con.
- BuildCustomString(cText, cNick, cChan, cFile) - This handler replaces custom tags in cText with the provided values. <nick> is replaced withthe contents of cNick. <chan> is replaced with the contents of cChan. <file> is replaced withthe contents of cFile.
- FileDoesExist(fPath) - This handler returns true or false, indicating whether or not the file fPath exists. fPath can be an alias or a text path.
- FilenameFromPath(fPath) - This handler returns the name of the file fPath.
- FindAppByCreator(creatorType, launch) - This handler returns a record containing the process and name of the application with creator creatorType. If the application is not already running and launch is true, the application is launched. The format of the returned record is: {appProcess:process, appName:name}.
- FindChannel(chanName) - This handler returns the name and connection of the channel named chanName. The channel must currently be open. The format of the returned record is: {channelName:name, channelCon:connection number}.
- FormatNumber(num, rDigits, lDigits, padChar) - This handler returns a padded, formatted text string representing the number num. rDigits is the number of digits to the right of the decimal point. lDigits is the number of digits to the left of the decimal point. padChar is the character to use for padding.
- FormatSize(bytes, numDigits) - This handler returns a size-formatted text string representing bytes. bytes is the size in bytes. numDigits is the requested number of digits to the right of the decimal point.
- IRCmagicPath() - This handler returns the path to the IRCmagic main script.
- GetScriptingAdditionsFolder() - This smart handler returns the path to the scripting additions folder regardless of the OS version.
- MungerString(searchStr, replaceStr, sourceStr) - This handler replaces every occurence of searchStr with replaceStr in sourceStr, and returns the result.
Writing Your Own IRCmagic Plug-in - A Tutorial
This section steps you through building a simple plug-in using the IRCmagic plug-in template as a starting point. The plug-in we will build opens a query window whenever the end user sends or receives a private message or notice. We'll call this plug-in the "AutoQuery" plug-in.
1) Open the plug-in template file
Open the plug-in template file in your script editor. The plug-in template file is named PluginTemplate.as and is located in the Documentation folder in the IRCmagic folder.
2) Set Ircle handler list
We want this plug-in to receive the input, privmsg, and notice Ircle events. So the pIrcleHandlers property should be set like so:
property pIrcleHandlers : {"input", "privmsg", "notice"}
This property is located at the top of the plug-in template. IRCmagic will call these handlers in this plug-in whenever Ircle sends those events.
3) Set custom handler list
The only custom handler this plug-in supports is the "AutoQuery" handler, which can be used by the end user to enable or disable the plug-in, or access the plug-ins settings. The pCustomHandlers property should be set like so:
property pCustomHandlers : {"AutoQuery"}
This property is located at the top of the plug-in template. IRCmagic will call this handler in this plug-in whenever the end user types /autoquery.
Write Ircle handlers
Now we will write the Ircle handlers that we specified in the pIrcleHandlers property. Locate the section labeled -- IRCLE EVENT HANDLERS in the plug-in template. Write the following functions in this section:
on input(con, target, theString)
if (theString starts with "/msg") then
set saveDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to {" "}
if (the number of text items in theString > 1) then
set recipient to (item 2 of (text items of theString))
else
set recipient to ""
end if
set AppleScript's text item delimiters to saveDelim
tell application "ircle"
if not (exists window recipient) then type "/query " & recipient in connection (con as integer)
end tell
end if
return false
end input
on privmsg(con, theNick, theHost, theChan, theStr)
tell application "ircle"
if not (exists window theNick) then type "/query " & theNick in connection (con as integer)
end tell
return false
end privmsg
on notice(con, theNick, theHost, theChan, theStr)
tell application "ircle"
if not (exists window theNick) then type "/query " & theNick in connection (con as integer)
end tell
return false
end notice
These handlers are called by IRCmagic when the input, privmsg, and notice events are sent by Ircle, and open a query window when the end user sends or receives private messages or notices.
Write the custom handler
All plug-ins are required to support one custom command to allow users to enable or disable the plug-in and optionally allow access to the plug-in settings. This custom command handler should be named the same as the plug-in file. In this tutorial, the command handler is named AutoQuery().
Custom handlers are not called directly by IRCmagic. Instead, IRCmagic calls the DoCommand(theCommand) handler, passing in the theCommand parameter the name of the custom handler being called. Locate the DoCommand() handler. Change the contents of this handler like so:
on DoCommand(theCommand)
tell application "ircle" to set con to argument 1
tell application "ircle" to set target to argument 2
tell application "ircle" to set theString to argument 3
-- branch off to custom handlers
if theCommand is "AutoQuery" then
my AutoQuery(con, target, theString)
end if
end DoCommand
When the end user types /autoquery followed by any text, IRCmagic calls this handler. This handler in turn calls the AutoQuery() handler in the plug-in. Next, we will write the AutoQuery() handler.
Locate the section labeled -- CUSTOM EVENT HANDLERS in the plug-in template. Write the following function in this section:
on AutoQuery(con, target, theString)
-- an example custom handler
try
-- get argument
set arg to ""
if ((the number of words in theString) > 1) then
set saveDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to {" "}
set arg to (word 2 of theString) as string
set AppleScript's text item delimiters to saveDelim
end if
if (arg is "on") then
my SetEnabled(true)
ShowMessage(pMyName & " is now on.")
else if (arg is "off") then
my SetEnabled(false)
ShowMessage(pMyName & " is now off.")
else if (arg is "set") or (arg is "") then
my Settings()
else
ShowMessage("The syntax for this command is: /" & pMyName & " on | off | set")
end if
on error errmsg
ShowMessage("AutoQuery() failed: " & errmsg)
end try
end AutoQuery
This handler is called by the DoCommand() handler when the end user types /autoquery followed by any text.
Congratulations. You have just written your first IRCmagic plug-in. To use your new plug-in, save it as AutoQuery and drop the script file into the IRCmagic plug-ins folder. With the plug-in loaded and enabled, a query window will open any time you send or receive a private message.