Auto Actions

Auto Actions are a powerful feature that Foo IRC provides to allow users to have more control over there IRC session by providing some functionality only seen in desktop IRC applications like mIRC. Auto Actions are constructed using a language that shares similar syntax to some of the most popular programming languages. This document provides all the information needed in order to use and understand this language.

Changes in v3.7.0

  • Operator '+' now works to join two arrays.
  • Operator '-' now works to diff arrays and strings.

Changes in v3.5.1

  • unset can now be used on array items.

Changes in v3.0.5

  • Bug fixes.

Changes in v3.0

  • Arrays are now ordered maps which means the index (key) can now be a string.
  • IRC commands can now be used directly in a script by starting a line with /< the command name >

Changes in v2.7

  • Added the ability to prioritize actions added to a action stream.

Changes in v2.5

  • Support for '-' (negative sign) for negative numbers.
  • Improved support for the '!' (not) operator
  • Math expression fixes.

Changes in v2.2.1.2:

  • Added support for single line comments (// comment text).
  • Fixed line number counts

Changes in v2.2.1:

  • Added support for comments (/* comment text */) and the ! (not) operator.
  • Fix for setting and retrieving array values.

Action Groups

Action groups are similar to classes of programming languages. Groups provide a way to combine actions into a single scope that they can be called from and share data with.

Below is an example definition of a group with no action:

MyGroup {

}

Actions

Actions are similar to functions or methods of programming languages. An action can be called directly from another action or it can be triggered by an event. All actions must be placed in an action group and be uniquely named in that action group.

Creating an Action

An action can be defined as follows:

MyGroup {

    action MyAction(parameter1, parameter2) {

    }

}

This action is named MyAction and has two named parameters, parameter1 and parameter2. The name of an action can only have numbers, letters, and underscores. Actions can have zero or more parameters which can be access by commands inside the body of the action.

Auto Run Actions

If actions exist in an action group with the names Init or ServerInit, these actions will be automatically triggered. These actions are not required to be in action groups. The triggering of these actions are not associated with any stream, and may not have certain reserved variables available for use.

Init()

Triggered when the action group that holds this action is first added to the system.

ServerInit()

Triggered when a server is added to the system.

Commands

Commands can be placed in the body of an action and are run whenever the action is called. They can consist of variable assignments, action calls, and arithmetic. Each command must be separated by and end with semicolons unless it is a block.

Variables

Scope

Variables can be set and accessed from various scope levels which control how variables are shared between different actions. Variables can be set in the following scopes:

local (default) Variables set in the local scope are only accessible in the current block (i.e. inside the closest surrounding parentheses). If a scope is not explicitly given, the local scope is used by default. When attempting to access a local variable, if it does not exist in the current block, the variable will be looked up in parent scope, down to the group scope.

group The variable is accessible by all actions a part of this action group. These are treated similar to static variables of some programming languages.

global The variable is accessible by all action groups.

server The variable is accessible to all actions running on the current server running this action.

To set or access a variable from a particular scope, the variable can be accessed in the form [scope].[variableName].

Ex:

global.myVar

Declaring Variables

A variable must be declared before it can be assigned or accessed. Variables can be declared as follows:

set group.myVar;

The type of a variable is determined dynamically and can be an integer, double, string, or an array. The name of a variable can contain numbers, letters, and underscores, but it cannot start with a number. To unset a variable, use unset instead of set.

unset group.myVar;
unset group.myVarArr[1];

Assigning Variables

A variable can be assigned as follows:

[scope].[variable name] = [expression];

Only variables that have already been declared can be assigned. If no scope is given, the local scope is used by default.

Reserved Variables

Reserved variables can only be accessed in a read-only manner. Variables names starting with r_ are reserved variables and cannot be declared or assigned by the user.

See the Registering Auto Actions section to see some examples of reserved variables that are used.

Reserved Server Variable

r_serverHostname: The hostname entered by the user to connect to this server.

r_serverRealHostname: The hostname reported by the connected

r_serverName: The name of the server reported by the server.

r_nickname: The users current nickname.

r_settingsGuid: The guid used for this server in the saved server settings.

r_guid: The guid used to uniquely identify this server connection.

Arrays

An array is a ordered map variable that can hold multiple key/value pairs. The value at each key of an array can be retrieved or assigned just like regular variables. The following is an example of declaring and assigning an array:

set myArray[];

myArray[0] = 1;

myArray[1] = 2;

myArray["two"] = 3;

Values

The types of values are dynamically determined and supported in the form of Booleans, Integers/Doubles, or Strings.

Boolean: true or false

Integer/Double: -1.7976931348623157E+308 to 1.7976931348623157E+308

String: Begin and end with quotation marks

Calling Actions

An action can be called by another action using the following form:

[group name].[action name]([parameter 1, , parameter N])

[group name] is the name of the action group, [action name] is the name of the action name, and [parameter 1, , parameter N] is comma separated parameters. If calling an action from the same action group, then the action group is implied is does not need to be given. An action call can be placed anywhere in a command except as an assignable variable in an assignment.

Operators

Operators can be used to perform specific arithmetic, relational, or logical operations on values to get a result. The following operators are supported.

[value 1] [operator] [value 2]

Arithmetic

+ : Numeric addition, String concatenation, array joining

- : Numeric subtraction, string substring removal, array diffing

/ : Numeric division

* : Numeric multiplication

Relational

== : Equals

!= : Not equal

< : Numeric less than

<= : Numeric less than or equal to

> : Numeric greater than

>= : Numeric greater than or equal to

Logical

| : Boolean or

& : Boolean and

! : Boolean not

Returning Values

An action can return a value using the return keyword. When a value is returned, the value takes the place of where the action was called. Once a return is reached in an action, no other commands in the current action are run and the action that called it continues where it left off.

return [expression];

IRC Style Commands

IRC commands can be used directly in Auto Action scripts in the same form they are normally sent to an IRC server. This follows the form /< IRC command > < parameters >. The full line will be consider the command unless the command contains a non-conditional block.

Non-Conditional Blocks

A block is a section of code that starts with an open brace '{' and ends with a close brace '}'. While it is a necessary part of actions and control flow statements, a block can also be used standalone anywhere inside an action and can contain any code that is typically allowed within an action, including other blocks. These standalone blocks are called non-conditional blocks.

Control Flow Statements

While

Structure of a while statement:

While ([condition]) {
    [commands];
}

While statements can be used to run commands in the block of a while statement as long as the condition is true. The condition must be an expression that results in a Boolean value. Be careful to make sure the condition eventually becomes false, otherwise the commands may continue to be run until the system is terminated.

Conditionals

Structure of conditionals:

if ([condition]) {
    [commands];
}
else if ([condition]) {
    [commands];
}
else {
    [commands];
}

Conditionals allow control over running a block of commands based on a Boolean condition. A conditional starts with an if statement. If the condition of the if statement is true, the commands in its block are run. Otherwise, flow control moves to the next conditional statement if there is one. The next conditional can be an else if or else. An else if acts the same as an if and must be following an if or another else if. An else is the last conditional and its commands are always run if no previous conditions were met.