About this reference
Every event, field, command and function a .hex script can use, with what each one does. For how a script fits together, with worked examples, start with Scripting with .hex.
Function and field names are written here with their $; event names are case-insensitive and written in capitals by convention. Arguments in [brackets] are optional.
Events
An on block runs when its event happens. A filter after a colon narrows it: channel events (JOIN, PART, KICK, MODE, the status events, BAN/UNBAN, RAWMODE, TOPIC and INVITE) filter on the channel, as in on JOIN:#help; the rest filter on the text, as in on TEXT:*hello*. mIRC headers such as on *:TEXT:*hi*:#:{ work too. IRC events fire only for live traffic, never for history replayed after a reconnect.
| Event | When it fires |
|---|---|
on LOAD | The script is loaded or reloaded: when the app starts, or after you enable or edit it. Set defaults here. mIRC's on *:START: is read as this. |
on TEXT | A message arrives in any buffer. The handler can change the line with rewrite or drop it with halt before it is shown. It doesn't fire for lines you send from this device; your own lines from another client, such as through a bouncer, arrive with $isme true. |
on ACTION | Like TEXT, for /me actions. |
on INPUT | You press send, before the line is processed. rewrite changes what is sent and halt stops it. Lines sent by scripts, buttons and menus don't trigger it. |
on NUMERIC | A server line is about to be printed. halt hides it and rewrite changes it; HexDroid still acts on the line. NAMES replies (353, 366) are handled internally and never reach this event; a who sent by the script does. |
on JOIN | Someone joins a channel, you included. Your own join fires before the server sends the member list. |
on PART | Someone leaves a channel. $text is their part message. |
on QUIT | Someone disconnects. $text is the quit message and $chan is empty, since a quit isn't tied to one channel. |
on KICK | Someone is kicked. $nick did the kicking, $victim was kicked, $text is the reason, and $isme is true when you were kicked. |
on MODE | Someone's status in a channel changes, one event per change. $mode is the change, such as +v; $isme is true when it's your status. |
on OP | Someone is given operator status. Raised alongside MODE. |
on DEOP | Someone loses operator status. |
on VOICE | Someone is given voice. |
on DEVOICE | Someone loses voice. |
on HELP | Someone is given half-op status. |
on DEHELP | Someone loses half-op status. |
on BAN | A ban is set. $banmask is the mask and $nick who set it. |
on UNBAN | A ban is removed. |
on RAWMODE | Any channel MODE line, once. $text is the modes with their arguments, such as +bv *!*@host nick. |
on TOPIC | Someone changes the topic. $text is the new topic. |
on INVITE | You're invited: $nick invited you to $chan. echo $chan would open that channel's buffer; use echo -a to write to the one you're in. |
on CTCP | A CTCP request other than /me. $text is the command and its arguments, such as VERSION or PING 1234. HexDroid still answers the ones it knows. |
on CTCPREPLY | A reply to a CTCP you sent. $text is the command and the reply. |
on NOTICE | A notice arrives, service replies such as NickServ's included. A private notice has no $chan, so echo writes to the buffer you're in. Notices from ignored nicks don't reach scripts. |
on SNOTICE | A server notice, alongside NOTICE. |
on NOTIFY | Someone on your /monitor list comes online.Fields: $nick |
on UNOTIFY | Someone on your /monitor list goes offline.Fields: $nick |
on CONNECT | You finish connecting (registration completes) to a network. $nick is your nick. Handy for identifying or joining channels.Fields: $nick |
on DISCONNECT | A connection that was up closes. $text is the reason. A failed connection attempt doesn't count.Fields: $text |
on APPACTIVE | HexDroid comes to the front or goes to the background. Fields: $appactive |
on FILERCVD | A DCC download finishes. |
on FILESENT | A DCC send finishes. |
on NICK | Someone changes nick. $nick is the old nick and $newnick the new one; $isme is true for your own change. |
on SIGNAL:name | A custom signal, written on SIGNAL:name. Raised by signal, timer, http.get/http.post, media.pick/media.upload, view buttons and other scripts, with any extra words as $1-. HexDroid raises some itself: view_closed when a script view is closed, screenchange when the device rotates under a view, and age_msg, age_deal, age_peer, age_ready and age_left for the encrypted transport.Fields: $1- |
Fields
Read-only values describing the event being handled. A field an event doesn't set is empty.
| Field | Value |
|---|---|
$me | Your current nick on the event's network. |
$nick | Who the event is from or about: the sender of a message, the person joining, the kicker, the old nick in NICK. |
$chan | The buffer the event belongs to: a channel or a private chat. Empty in QUIT and some private events. |
$buffer | The same as $chan. |
$target | The same as $chan. |
$network | The id of the event's network. |
$text | The event's text: the message, part or quit message, kick reason, new topic or mode string. In an INPUT handler it's the line you typed, after any rewrite. |
$isme | true when the event is about you: your own line from another client, your own join, part, quit or nick change, or your being kicked. |
$isprivate | true for a private message or notice, false in a channel. |
$iscmd | true in INPUT when the line is a /command. |
$code | The three-digit numeric in NUMERIC; empty for server text that carries none. |
$whois | true in NUMERIC when the line answers a WHOIS you ran. |
$account | The account of the person joining, in JOIN, when the server reports it. |
$victim | Who was kicked in KICK, or whose status changed in MODE and the status events. |
$mode | The status change in MODE, such as +o or -v. |
$opnick | Whose operator status changed, in OP and DEOP. |
$vnick | Whose voice changed, in VOICE and DEVOICE. |
$hnick | Whose half-op status changed, in HELP and DEHELP. |
$banmask | The mask in BAN and UNBAN. |
$newnick | The new nick in NICK. |
$isserver | true in NOTICE when the notice is from the server. |
$appactive | true or false in APPACTIVE. |
$filename | The file's name in FILERCVD and FILESENT. |
$filesize | The file's size in bytes in FILERCVD. |
$path | Where a received file was saved, in FILERCVD. |
$httpok | true when an HTTP request or upload succeeded. Many upload endpoints answer 200 with JSON that describes a failure, so check the body too. |
$httpstatus | The HTTP status code, or 0 when the request never got one. |
$httpbody | The response body, cut off after about 1 MB. |
$httplocation | The response's Location header, or empty. Upload endpoints that answer 201 Created put the new URL here. |
$httperror | Why a request got no status when $httpstatus is 0: blocked by policy, unreachable, a file too large and so on. |
$mediaok | true in a media.pick signal when a file was chosen, false when you declined. |
$mediatoken | The handle for the picked file, to pass to media.upload. Only the script that asked can use it, until scripts are reloaded. |
$medianame | The picked file's name, as shown to you. |
$mediamime | The picked file's MIME type. |
$mediasize | The picked file's size in bytes, or -1 when the provider doesn't say. |
$from | In the encrypted transport's signals, the sender's fingerprint (yours when you leave, in age_left). |
$data | The sealed secret in age_deal. |
$fp | The announcing member's fingerprint in age_peer. |
$ctime | The current Unix time, in seconds. |
$ticks | Milliseconds from a steady clock, for measuring how long something took. Only the difference between two readings means anything. |
$time | The local time as HH:mm:ss. |
$screen.landscape | 1 in landscape, 0 in portrait. |
$screen.width | The display width in dp. |
$screen.height | The display height in dp. |
$screen.tv | 1 on a TV, otherwise 0. |
$age.me | Your +AGE fingerprint, as hex. |
$1 $2- $1-3 $0 | Positional arguments: the words of $text in an event, the arguments of an alias, or the extra words of a signal. $2- is every word from the second on, $1-3 words one to three, and $0 how many there are. |
Commands
A statement is a command and its arguments, ended by a new line or |. Your own aliases are commands too.
Script commands
| Command | What it does |
|---|---|
set [-l] %name [value] | Set a variable to a string, number, list or map. -l makes it local to the current handler or alias call, hiding a global of the same name. With no value the variable is cleared. |
unset %name | Remove a variable. |
inc %name | Add 1 to a variable. An unset variable counts as 0. |
dec %name | Subtract 1 from a variable. |
push %list value | Append a value to a list. |
setat %coll key value | Set a key in a map, or an index in a list (one past the end appends). Works on nested collections. |
echo [buffer|-a|-s] text | Print a local line, never sent. The first word is the buffer: -a the one you're in, -s the server buffer, and a variable that's empty (such as $chan in QUIT) also means the one you're in. |
msg target text | Send a message to a channel or nick. If the target is an empty variable, nothing is sent. |
raw line | Send a line to the server as it is. |
rewrite text | In TEXT, ACTION, INPUT and NUMERIC: replace the line's text. |
signal name [args] | Raise on SIGNAL:name straight away, with the extra words as $1-. |
timer ms name [args] | Raise on SIGNAL:name after a delay in milliseconds. The way to do repeated or heavy work without blocking the app. |
toast text | Show a brief notice on screen. |
sidebar add id command label | sidebar remove id | Add a launcher to the top bar's script menu that runs command, or remove it. |
log text | Write a line to the script log. |
debug text | The same as log. |
view { ... } | Build and show an interactive screen from the view layout language. Mount it again to redraw. |
decorate ... | Reserved. Accepted, but currently does nothing. |
action ... | Reserved. Accepted, but currently does nothing. |
http.get [-h name:value] url signal [context] | Fetch a URL and raise on SIGNAL:signal with the response in $httpok, $httpstatus, $httpbody, $httplocation and $httperror. The context words arrive as $1-. Redirects are not followed. |
http.post [-t type] [-h name:value] [-b %var] url [body] signal [context] | Send a POST. Without -t the content type comes from the body: { or [ is JSON, key=value&... is form data, anything else is plain text. A positional body is one word, so use -b %var for one with spaces. Flag values are read before expansion. |
media.pick [-m mime] signal [context] | Ask you for a file. HexDroid shows a prompt naming the script's channel and network first, and the signal gets $mediaok, $mediatoken, $medianame, $mediamime and $mediasize. One pick at a time. |
media.upload [-h name:value] [-p name=value] [-f field] [-r] url token signal [context] | Upload a picked file without its bytes passing through the script: multipart under field file by default, -f renames the field, -p adds a form field, -r sends the raw bytes as the body. Files over 64 MB are refused. |
IRC commands
These run as if typed in the buffer the event came from. Commands that would drop or move your connection, such as quit and server, are left out; raw remains for a script that really means it.
| Command | What it does |
|---|---|
me action | Send an action (CTCP ACTION) to the buffer the event came from. |
join #channel [key] | Join a channel. |
part [#channel] [reason] | Leave a channel. |
cycle [#channel] [key] | Leave a channel and join it again. |
topic [#channel] [new topic] | View or set a channel's topic. |
mode target modes [args] | Set or query modes for a channel or user. |
invite nick [#channel] | Invite someone to a channel. |
kick [#channel] nick [reason] | Kick someone from a channel. |
knock #channel [reason] | Ask for an invite to an invite-only channel, on servers that support KNOCK. |
names [#channel] | Print a channel's member list. The replies don't reach on NUMERIC; use who to read members from a script. |
who mask | Send a WHO. When the script sends it, each reply reaches on NUMERIC as a 352 line, <channel> <nick> <flags> <user@host> ..., and 315 ends the list. |
whois nick | Send a WHOIS. Its replies reach on NUMERIC with $whois true. |
whowas nick | Ask about a nick that has left. |
list | Open the channel list. |
notice target text | Send a notice. |
ctcp target command | Send a CTCP request. |
nick newnick | Change your nick. |
away [message] | Mark yourself away. With no message, mark yourself back. |
back | Mark yourself back. |
op [#channel] nick | Give someone operator status. |
deop [#channel] nick | Remove someone's operator status. |
voice [#channel] nick | Give someone voice. |
devoice [#channel] nick | Remove someone's voice. |
ban [#channel] nick|mask [n|u|h|d|a] | Ban by nick (default), user, host, domain or account. |
unban [#channel] mask | Remove a ban. |
ignore [mask] [types] | Ignore a nick or mask, optionally only some types: PUBLIC, MSGS, NOTICES, CTCPS, INVITES, DCC, EVENTS or ALL. |
unignore nick | Remove someone from the ignore list. |
Encrypted transport
The age.* commands use the same machinery as +AGE encryption, for scripts that talk to other players. See Encrypted transport in the guide.
| Command | What it does |
|---|---|
age.join chan | Announce yourself on a channel for the encrypted transport. |
age.host chan | Key a channel as its host. |
age.send chan words | Send words to the channel's members over the encrypted transport. Your own copy arrives as age_msg too. |
age.local from words | Raise age_msg locally as if from from, for solo or practice play. |
age.seal fp data | Seal a secret to one member, who gets it as age_deal. |
age.close chan | Drop a channel's keys and roster. |
age.purge chan | Drop encrypted-transport lines still queued for a channel. |
Control flow & operators
| Statement | What it does |
|---|---|
if (condition) { ... } | Run the block when the condition is true. Conditions use ==, !=, <, >, <=, >=, isin and iswm, combined with && and ||. == and != compare text exactly, so 1.0 == 1 is false; the others compare as numbers when both sides are numbers. |
elseif (condition) { ... } | Another condition, tried when the ones before it were false. |
else { ... } | Run when no condition before it was true. |
while (condition) { ... } | Repeat the block while the condition is true. Loops count towards the script's instruction budget, so use timer for long work. |
foreach %item collection { ... } | Run the block for each item of a list, or each key of a map. |
break | Leave the innermost loop. |
continue | Skip to the next pass of the innermost loop. |
return [value] | Leave the current alias or handler, giving a value when an alias is used as $name(...). |
halt | Stop the whole handler. In TEXT, ACTION, INPUT and NUMERIC it also drops the line. |
Word operators
| Operator | True when |
|---|---|
a isin b | True when a appears in b. Case-sensitive. |
text iswm pattern | True when text matches the wildcard pattern, where * is any run of characters and ? one. Ignores case. mIRC puts the pattern on the left; HexDroid puts it on the right. |
Functions
Functions are written $name(arg, arg, ...) and return a value. Arguments are separated by commas; one in quotes may contain commas and brackets. There is no escape character, so a quote can't appear inside a quoted argument. Your own aliases can be called the same way, giving the value they return.
Strings
| Function | Returns |
|---|---|
$len(value) | The length of a string, or the number of items in a list or map. |
$lower(text) | The text in lower case. |
$upper(text) | The text in upper case. |
$left(text, n) | The first n characters. A negative n drops that many from the end: $left(abcdef, -2) is abcd. |
$right(text, n) | The last n characters. A negative n drops that many from the start: $right(abcdef, -2) is cdef. |
$substr(text, start, [length]) | Part of the text from start (counting from 0), to the end or for length characters. |
$replace(text, find, with) | The text with every find replaced by with. Exact, case-sensitive matching. |
$trim(text) | The text without spaces at either end. |
$contains(text, part) | true when part appears in the text. Case-sensitive. |
$indexof(text, part) | Where part first appears, counting from 0, or -1. |
$repeat(text, n) | The text n times over, at most 1000. |
$pad(text, width, [char]) | The text padded on the right to width with char, a space by default. |
$padleft(text, width, [char]) | The text padded on the left to width. |
$capitalize(text) | The text with its first letter in upper case. |
$title(text) | The text with the first letter of each word in upper case. |
$urlencode(text) | The text encoded for a URL or form body (spaces become +). |
Numbers
| Function | Returns |
|---|---|
$calc(expression) | The result of an expression with + - * / % and brackets. Dividing by zero gives 0. |
$mod(a, b) | The remainder of a divided by b, or 0 when b is 0. |
$idiv(a, b) | a divided by b, rounded down. |
$int(n) | n rounded down to a whole number. |
$round(n, [places]) | n rounded to places decimal places, 0 by default. |
$ceil(n) | n rounded up to a whole number. |
$abs(n) | n without its sign. |
$pow(a, b) | a to the power b. |
$clamp(n, low, high) | n kept between low and high. |
$min(a, b, ...) | The smallest number among the arguments, or in a list: $min(%scores). |
$max(a, b, ...) | The largest number among the arguments, or in a list. |
$rand(n) / $rand(low, high) | A random whole number from 0 to n-1, or from low to high inclusive. Fine for games; for anything that must be unguessable, use $age.rand. |
Regular expressions
| Function | Returns |
|---|---|
$re_match(text, pattern) | true when the pattern matches anywhere in the text. Patterns use Java syntax; an invalid one never matches, and text past 20,000 characters is ignored. |
$re_find(text, pattern) | The first match, or empty. |
$re_group(text, pattern, n) | Capture group n of the first match (0 is the whole match). |
$re_replace(text, pattern, with) | The text with every match replaced by with, as written: $1 style references aren't supported. |
Lists & maps
| Function | Returns |
|---|---|
$list(a, b, ...) | A list of the arguments. |
$map(key, value, ...) | A map from key and value pairs. |
$get(collection, key) | A list's item at an index (counting from 0), or a map's value for a key. Empty when missing. |
$has(collection, x) | true when a map has the key x, or a list has the item x. |
$keys(map) | A map's keys, in the order they were added. |
$values(map) | A map's values. |
$split(text, [separator]) | A list of the parts of the text between separators, a space by default. An empty separator splits into single characters. |
$join(list, [separator]) | The items joined into one string, with a space between by default. |
$sort(list) | A sorted copy: by number when every item is a number, otherwise by text, case-sensitive. |
$reverse(list) | A reversed copy. |
$slice(list, from, to) | The items from index from up to, not including, to. |
$concat(a, b, ...) | One new list from lists, map values and single values, in order. set %deck $concat(%deck, %card) appends without changing the original. |
$find(list, x) | The index of the first item equal to x, or -1. |
$count(list, x) | How many items equal x. For a map, 1 when it has the key x, otherwise 0. |
$sum(list) | The total of the numbers in a list. |
$range(low, high) | A list of the whole numbers from low to high inclusive, at most 10,001 of them. |
$pick(list) | A random item. |
$shuffle(list) | A shuffled copy. |
Data
| Function | Returns |
|---|---|
$json(body, path) | A value from JSON text by dotted path, such as results.0.url. A plain key not found at the top level is looked for anywhere in the text. |
$tojson(value) | A list, map or value as JSON, ready for http.post -b. A string that reads as a JSON number, such as 12, is written unquoted; 007 and 1e5 stay strings. |
$setting(key) | A host setting. applang (or lang) is the device's language code; other keys are empty. |
Encrypted transport
| Function | Returns |
|---|---|
$age.rand([bytes]) | Random bytes from a secure source, as hex, 16 by default. |
$age.sha(text) | The SHA-256 of the text, as hex. |
$age.ready(chan) | true once the channel is keyed. |
$age.owner(chan) | The channel's elected host: the lowest fingerprint present, the same on every client. |
$age.members(chan) | The fingerprints of the other members present, separated by spaces. |
$age.fp(nick) | The fingerprint stored for a nick, or empty. |