Paste: cfbot code

Author: doublec
Mode: factor
Date: Fri, 24 Apr 2009 11:45:55
Plain Text |
Simple IRC Bot

The channel, server, port and nickname words are used to configure where
the bot lives:

> "irc.freenode.net" server   set
> "6667"             port     set
> "#concatenative"   channel  set
> "cfbot"            nickname set

When connected to the server we deal with an 'ircbot' structure. This is
a list containing the following elements:

  1. The line-channel used to read server responses
  2. The socket used to write requests

These helper words are used to extract this information:

> [ '0`@ ] bot-line-channel set
> [ '1`@ ] bot-socket       set

Send a string to the server

> [ bot-socket.socket-writeln ] irc-write set

Connect to the server, returning the bot structure

> [ server;port;socket dup.'line-channel`, ] bot-connect set

Initializes the connection by setting the nickname, and other IRC
required setup.

> [ "NICK " nickname;,over.irc-write. ] set-nick set
> [ "USER "nickname;," +iw ",nickname;," :",nickname;,over.irc-write. ] set-status set
> [ "JOIN " channel;,over.irc-write. ] join-channel set
> [ set-nick.set-status.join-channel. ] bot-init set

Send a message to the channel:

> [ [[c m] "PRIVMSG " c , " :" , m , ] ( over.irc-write. ] say set 

Return the list of responses received from the server. Blocks if not
responses have yet been received.

> [ dup.bot-line-channel.line-channel-getall ] bot-responses set


Utility words to evaluate cf code. These should probably be in the
prelude:

> [ 
>   [[c]stack.[[]unstack.c.stack.[[]unstack.]`]`swap.unit.,unstack.] (
> ] infra set
> [ tokenize parse infra. to-string ] eval set

The following words operate on responses from the server. 


> [ dup. 32 ? 1 + sdrop dup. 32 ? stake ] response-type set
> [ dup. 32 ? 1 + sdrop dup. 32 ? 1 + sdrop dup. 32 ? stake ] response-channel set
> [ dup. 32 ? 1 + sdrop dup. 32 ? 1 + sdrop dup. 32 ? 2 + sdrop ] response-text set

Is it a private message?

> [ response-type. "PRIVMSG" swap. = ] privmsg? set

Is it for the channel we are monitoring?

> [ [response-channel.]`= ] channel? set

Is it for us?

> [ response-text. nickname; ",", swap. head?. ] for-bot? set

Map expression used to pick up the responses we are interested in. Anything
we aren't interested in results in a 0 which is later filtered out.

> [ dup.privmsg?.[dup.channel;channel?.[dup.for-bot?.[response-text.nickname;count 1 + sdrop][drop.0]if][drop.0]if][drop.0]if] wanted-messages set

Get all responses, filter for the messages we want
> [bot-responses.[wanted-messages.]map.[]filter.] messages-to-eval set

Build the expression to evaluate on another thread:

> [ [[b c] c [[[b channel;]]`unit.,eval,'.,say,'.,[drop.],]map. [b]`] ( ] build-thread-queue set

> [ messages-to-eval.build-thread-queue.[[]swap.make-thread spawn]map.drop.] handle-messages set
> [ handle-messages.bot-loop. ] bot-loop set

> [ bot-connect.bot-init. ] start-bot set
> [ dup.unit. [ bot-loop. ] make-thread spawn ] bot-daemonize set

Annotation: updated for newer eval routine

Author: doublec
Mode: factor
Date: Fri, 24 Apr 2009 14:10:18
Plain Text |
Simple IRC Bot

The channel, server, port and nickname words are used to configure where
the bot lives. 'timelimit' is the maximum amount of time a eval request is
allowed to run before it is aborted.

> "irc.freenode.net" server    set
> "6667"             port      set
> "#doublec"         channel   set
> "cfbot"            nickname  set
> 10000              timelimit set
> 200                textlimit set

When connected to the server we deal with an 'ircbot' structure. This is
a list containing the following elements:

  1. The line-channel used to read server responses
  2. The socket used to write requests

These helper words are used to extract this information:

> [ '0`@ ] bot-line-channel set
> [ '1`@ ] bot-socket       set

Send a string to the server

> [ bot-socket.socket-writeln ] irc-write set

Connect to the server, returning the bot structure

> [ server;port;socket dup.'line-channel`, ] bot-connect set

Initializes the connection by setting the nickname, and other IRC
required setup.

> [ "NICK " nickname;,over.irc-write. ] set-nick set
> [ "USER "nickname;," +iw ",nickname;," :",nickname;,over.irc-write. ] set-status set
> [ "JOIN " channel;,over.irc-write. ] join-channel set
> [ set-nick.set-status.join-channel. ] bot-init set

Send a message to the channel:

> [ [[c m] "PRIVMSG " c , " :" , m , ] ( over.irc-write. ] say set 

Return the list of responses received from the server. Blocks if not
responses have yet been received.

> [ dup.bot-line-channel.line-channel-getall ] bot-responses set


Utility words to evaluate cf code. These should probably be in the
prelude:

> [ tokenize parse [[]]` timelimit;make-limited-thread spawn thread-join to-string 2 sdrop dup. count 2 - stake ] eval set

The following words operate on responses from the server. 


> [ dup. 32 ? 1 + sdrop dup. 32 ? stake ] response-type set
> [ dup. 32 ? 1 + sdrop dup. 32 ? 1 + sdrop dup. 32 ? stake ] response-channel set
> [ dup. 32 ? 1 + sdrop dup. 32 ? 1 + sdrop dup. 32 ? 2 + sdrop ] response-text set

Is it a private message?

> [ response-type. "PRIVMSG" swap. = ] privmsg? set

Is it for the channel we are monitoring?

> [ [response-channel.]`= ] channel? set

Is it for us?

> [ response-text. nickname; ",", swap. head?. ] for-bot? set

Map expression used to pick up the responses we are interested in. Anything
we aren't interested in results in a 0 which is later filtered out.

> [ dup.privmsg?.[dup.channel;channel?.[dup.for-bot?.[response-text.nickname;count 1 + sdrop][drop.0]if][drop.0]if][drop.0]if] wanted-messages set

Get all responses, filter for the messages we want
> [bot-responses.[wanted-messages.]map.[]filter.] messages-to-eval set

Build the expression to evaluate on another thread:

> [ dup.count textlimit; < [ ] [ textlimit; stake "...", ] if ] limit-string set
> [ messages-to-eval.[eval.limit-string.]map.[channel; abc-bca say.drop.][over.unit.]`,each.] handle-messages set
> [ handle-messages.bot-loop. ] bot-loop set

> [ bot-connect.bot-init. ] start-bot set
> [ dup.unit. [ bot-loop. ] make-thread spawn ] bot-daemonize set

New Annotation

Summary:
Author:
Mode:
Body: