Perl Snippets

On this page, a bunch of small XChat Perl scripts are provided. Each of these deal with a specific purpose and so shouldn't be lumped all together in one script. Most of these scripts will have been provided in #xchat to answer some user, but provided here in case someone else has a need for them.

Simply create a plain text file inside of your XChat profile directory named, replacing "something" with a word of your choice. Most of these scripts won't include a registration line, so meaningful information will not show up in Window -> Plugins and Scripts.... To have the script registered in that window, start the file out with the following line (changed for each snippet you save as a separate file):

Xchat::register('One Line Snippets', '001', 'Miscellaneous small perl snippets for specific tasks');

In the above, One Line Snippets would be the name of the script, and only one XChat script can be named this. XChat will complain at you if you try and load multiple files with this as the script name. 001 is the version number of the script, and can be almost anything you like. The last bit is the Description that will be displayed in the Plugins and Scripts dialog.

Away Action ignore

If you would like to ignore all channel actions that start with "* user is auto-away", "* user is back", "* user is auto back" and similar, you can use the following one line Perl script to accomplish that:

Xchat::hook_print('Channel Action', sub { return Xchat::EAT_ALL if ($_[0][1] =~ /^is (?:auto[ -])?(?:away|back)/i); return Xchat::EAT_NONE; });

Reply nick colors

The following script was written for a user on #xchat who wanted to distinguish replies addressed at specific users from generic chat messages in the case of large support channels. To do that, we have the following script which will bold and color green a nick if it starts the line in the form of "nickname:" or "nickname,".

Xchat::register('Distinguish Reply', '001', 'Place colors around a user if they are being addressed');

Xchat::hook_print('Channel Message', sub {
        $_[0][1] =~ m/^(\S+)([:,].*)/;
        return Xchat::EAT_NONE unless ($1 && Xchat::user_info($1));
        $_[0][1] = "\cB\cC03$1\cO$2";
        Xchat::emit_print('Channel Message', @{$_[0]});
        return Xchat::EAT_ALL;

If you want to change the color from green to something else, change the 03 in the 6th line of the above to the color code of your choice.

Ignore joins in a specific channel

One user wanted to ignore channel joins but not parts and quits in a specific channel. That can be accomplished with the following line:

Xchat::hook_print('Join', sub { return Xchat::EAT_XCHAT if (lc $_[0][1] eq '#yourspecialchan'); return Xchat::EAT_NONE; });

Flash channel on join

Another user wanted to flash the system tray icon when someone joins a channel, just as if someone had spoke in the channel. That can be accomplished with the following similar line:

Xchat::hook_print('Join', sub { Xchat::command('tray -i 08') if (lc $_[0][1] eq '#yourspecialchan'); return Xchat::EAT_NONE; });

Op users who pm you a keyword

In the following case, this script will op any user if they pm you a specially keyword. While I personally believe it would be better to use chanserv for this purpose, not all networks have a proper services.

foreach ('Private Message', 'Private Message to Dialog') { Xchat::hook_print($_, \&checkop); }
sub checkop { if ($_[0][1] =~ /^keyword/) { Xchat::command("mode #yourchan +o ".Xchat::strip_code($_[0][0])); } }

Ignore all lines that contain a specific word

One user wanted to ignore all channel lines that included a specific word, in this case, the nick of a user that was already being ignored. The following script will do that, however it will not ignore lines that are either channel actions, or highlights, as it is always nice to see when someone is talking to you.

Xchat::hook_print('Channel Message', sub { return Xchat::EAT_ALL if ($_[0][1] =~ /evilnick/i); });

Do not print messages locally

This line will not be useful for most people. Apparently there are some servers that have a setting where users can tell the server to also send their own channel messages back to themselves. This is a hard concept to explain in one line, but it is used in lag detection. The user types a message in the client and it gets sent to the server. The server then sends the message on to all users in the channel including the client that sent it. In order to not see the initial print out, the following script can be used, which will hide all messages typed directly into a channel or query window.

Xchat::hook_command("", sub {if (Xchat::get_info('network') eq "YourNetwork") {Xchat::command("quote PRIVMSG ". Xchat::get_info('channel') ." :".$_[1][0]); return Xchat::EAT_XCHAT;} });

This script must be used in conjunction with a network that is either auto joined, or connected to using /server YourNetwork. If you connect to the server using /server, the script will not work. Again though, this script will hide messages sent to this network, and so most people will not want this script.

Encode a url

The following code creates a /urlit command which accepts a string which will be encoded for URLs, and then said in the channel.

Xchat::hook_command('urlit', sub {
        $_ = $_[1][1];
        s/([^\w'*~!. -])/sprintf '%%%02x', ord $1/eg;
        tr/ /+/;
        return Xchat::EAT_XCHAT;

Ignoring matching actions from a specific user

Some channels have bridges to other networks, such as Jabber. While you may want to see what messages are said from the other side, if you have joins/parts hidden within XChat, you wouldn't want to see the joins from the bridge. If the messages are in the form of:

* botname offsiteuser has become available
* botname offsiteuser has left

You can ignore these using the following script:

Xchat::hook_print('Channel Action', sub {
        return Xchat::EAT_ALL if (Xchat::strip_code($_[0][0]) eq 'botname' && $_[0][1] =~ /^\S+ has (?:left|become available)/);

Disable Freenode's CAPAB (+ and -) feature

By default, if XChat sees a CAPAB token when it connects (such as on FreeNode), XChat tells the server to enable a feature which prefixes each line with a + if the user who said it is identified to services, and a - if they have not. XChat will correctly parse these out (unless you have a poorly written script), but if you are connected to a bouncer with other clients who do not parse this out, they will have their lines prefixed with the + and -. To disable XChat from turning on this server side feature, use the following script:

use Xchat qw(:all); hook_server( "005", sub { if($_[1][0] =~ s/CAPAB //) { command("RECV $_[1][0]"); return EAT_ALL} else { return EAT_NONE } } );

You will need to reconnect the bouncer/proxy to the server however, as CAPAB will be enabled until your connection to the IRC server has closed. This script will simply stop XChat from issuing the CAPAB command, if some other client enables the feature, XChat will correctly parse the + and -.

Use the tab highlight color for private messages

If you would like more distinction when a private message is received than just the new message color, you can use the color normally associated with a highlighted message.

Xchat::hook_print($_, \&color_tab) foreach('Private Message to Dialog', 'Private Action to Dialog');
sub color_tab { Xchat::command('gui color 3'); return Xchat::EAT_NONE; }

... for topic changes (and other events)

Similarly, this method can be used for other text events, such as Topic Change for when the topic is changed. Most events are self explanatory and can be found in Settings->Advanced->Text Events

Xchat::hook_print('Topic Change', sub { Xchat::command('gui color 3'); return Xchat::EAT_NONE; });

Use ; at the beginning of lines to signify action

In some environments, ; (semi-colon) at the beginning of a line signifies an action. To use this behavior within xchat, use the following script:

Xchat::hook_command("", sub { if ($_[1][0] =~ m/^;(.*)/) { Xchat::command("me $1"); return Xchat::EAT_XCHAT; } });

Display nick in use messages in front tab

This line will cause all Nick Failed messages to show up in the current tab rather than in the server tab. This will only work if the message from the server ends with "Nickname is already in use." however.

use Xchat qw (:all); hook_print('Server Text', sub { if ($_[0][0] =~ m/Nickname is already in use\.$/ && find_context != get_context) { set_context(find_context()); emit_print('Server Text', @{$_[0]}); return EAT_ALL; } return EAT_NONE; });

Join channels without specifying # sign

To join channels without specifying the # sign, you can use the following script. Note though that not all channels start with #, some start with & (for use on an individual server rather than network wide). For being really lazy, this method is called by /j channel or possibly /j channel keyword. If you happen to specify the # anyway, no problem, an additional one will not be added. Also note, you cannot use this method to do /j channel1,channel2, as it only prefixes the initial channel.

Xchat::hook_command('j', sub {
        my $channel = $_[1][1];
        $channel = '#'.$channel unless ($channel =~ m/^#/);
        Xchat::command("join $channel");
        return Xchat::EAT_ALL;

Ignore join/part/quit messages for specific nicks

If you can normally see join/part/quit messages in channel, but don't want to see specific users when they join (such as to totally ignore them, not even see when they join) you can use the following. Note that the specified nicks need to be done in lower case, just add new nicks to the list using the same pattern. Hosts though should be the same case as seen when the user join/parts

my $nicks = {
        'annoying1' => 1,
        'annoying2' => 1,
my $hosts = {
        '' => 1,
        'bob@' => 1,
foreach ('Join', 'Quit', 'Part', 'Part with Reason') { Xchat::hook_print($_, \&nick_conference, {data => $_}); }
sub nick_conference {
        my $host = ($_[1] =~ /^Part/ ? $_[0][1] : $_[0][2]);
        return Xchat::EAT_XCHAT if (defined $nicks->{lc Xchat::strip_code($_[0][0])} || defined $hosts->{$host});
        return Xchat::EAT_NONE;

Reply to a CTCP with a system command

It is fairly straight forward to add additional CTCP Replies, however this method only works if adding plain text replies. If instead, you want to add replies that use system calls (such as uptime), you would need the following script. Note that you should replace UPTIME with the actual string you wish your script to reply to.

Xchat::hook_print('CTCP Generic', sub {
        if ($_[0][0] eq 'UPTIME') { Xchat::command("nctcp $_[0][1] ".`uptime`); }
        return Xchat::EAT_NONE;

If you wish to reply to multiple commands, the simple method is to use an elsif, such as the following:

Xchat::hook_print('CTCP Generic', sub {
        if ($_[0][0] eq 'UPTIME') { Xchat::command("nctcp $_[0][1] ".`uptime`); }
        elsif ($_[0][0] eq 'OS') { Xchat::command("nctcp $_[0][1] ".`uname -o`); }
        return Xchat::EAT_NONE;

Perform a command on initial private message

To perform a command whenever someone initially sends a private message to you, the Open Dialog event is used. This example shows a whois being done, however since the whois reply may not show up in the dialog window, it is better to use a script for this, such as Khisanth's Whois on PM.

Xchat::hook_print('Open Dialog', sub { Xchat::command('whois '.Xchat::get_info('channel')); return Xchat::EAT_NONE; });

Owner everyone on join

For reasons that escape me, one user wanted to set owner mode (+q) on everyone who joined his channel. Assuming that owner is already designated with '~', this can be accomplished as follows:

Xchat::hook_print('Join', sub { Xchat::command("mode +q $_[0][0]") if(lc $_[0][1] eq '#mychannel' && Xchat::user_info()->{prefix} eq '~'); return Xchat::EAT_NONE; });

Command to print lag

When the user list is hidden, the lag display is not shown either. If you wish to have a command to show what the current lag is, this once again requires a script (which is called with /lagdisp):

use Xchat qw(:all); register('Lag Display', '001', 'Display the lag with a command'); hook_command('lagdisp', sub { prnt('Lag: '.(context_info->{lag}/1000). ' seconds'); return EAT_XCHAT; });

Play a sound file on channel join

If you are on a channel that is important enough to you that an audible sound should be played when someone joins the channel, you can consider this script. Note though, if a netsplit happens, the result may not be pleasing to the ears:

use Xchat qw(:all); hook_print('join', sub { command('splay "/path/to/file.ogg"') if (lc $_[0][1] eq '#yourchannel'); return EAT_NONE; });

Have all messages in channel change tab color to highlight

If more visual clues are needed for when someone says something in a specific channel, you can have the color of the tab display as a highlight for any message said in the channel. Simply add more channes to the #chan1 #chan2 list.

use Xchat qw (:all);
hook_print($_, \&color_change) foreach('Channel Message', 'Channel Action');
my @chan = qw(#chan1 #chan2);
sub color_change {
        command('gui color 3') if (grep(lc get_info('channel') eq $_, @chan));
        return EAT_NONE;

Use New Event color for new messages in specific channel

If there is a specific channel in which you don't want to see the tab color change on new messages, the following is imperfect, but it most likely will work for you. Why is it imperfect? If you are highlighted in the channel, as soon as a new message is received, the highlight color will be removed from the channel list.

use Xchat qw(:all); register('No color msgs', '001'); hook_print($_, \&decolor) foreach('Channel Message', 'Channel Msg Hilight'); sub decolor { hook_timer(0, sub { command('gui color 1'); return REMOVE; }) if (lc get_info('channel') eq '#annoyingchannel'); return EAT_NONE; }

Print - Recent Changes - Search
Page last modified on August 04, 2013, at 02:54 PM