Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change cfbot to use latex formatting
- Loading branch information
Showing
1 changed file
with
168 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,105 +1,221 @@ | ||
Simple IRC Bot | ||
\documentclass{article} | ||
\usepackage{verbatim} | ||
\usepackage{listings} | ||
\lstnewenvironment{code} { | ||
\lstset{ | ||
basicstyle=\small\ttfamily, | ||
flexiblecolumns=false, | ||
frame=single, | ||
basewidth={0.5em,0.45em} | ||
} | ||
}{ | ||
} | ||
|
||
\setlength{\parindent}{0.0in} | ||
\setlength{\parskip}{0.1in} | ||
|
||
\begin{document} | ||
|
||
\section{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. | ||
|
||
> object copy bot-traits set | ||
> object copy bot set | ||
> bot;bot-traits;parent* add-slot. | ||
> "irc.freenode.net" server add-slot | ||
> "6667" port add-slot | ||
> "cfevalbot" nickname add-slot | ||
> "#doublec" channel add-slot | ||
> 10000 timelimit set | ||
> 200 textlimit set | ||
\begin{code} | ||
object copy bot-traits set | ||
object copy bot set | ||
bot;bot-traits;parent* add-slot. | ||
"irc.freenode.net" server add-slot | ||
"6667" port add-slot | ||
"cfevalbot" nickname add-slot | ||
"#doublec" channel add-slot | ||
10000 timelimit set | ||
200 textlimit set | ||
\end{code} | ||
|
||
When connected to the server we deal with the 'bot' object. As well as | ||
the slots listed above it contains the following private slots: | ||
|
||
1. The line-channel used to read server responses | ||
2. The socket used to write requests | ||
\begin{enumerate} | ||
\item The line-channel used to read server responses | ||
\item The socket used to write requests | ||
\end{enumerate} | ||
|
||
> nil bot-lines add-slot | ||
> nil bot-socket add-slot | ||
\begin{code} | ||
nil bot-lines add-slot | ||
nil bot-socket add-slot | ||
\end{code} | ||
|
||
That's all of the bot instance slots. The methods are defined on the | ||
traits object. | ||
|
||
> drop.bot-traits; | ||
\begin{code} | ||
drop.bot-traits; | ||
\end{code} | ||
|
||
Send a string to the server | ||
|
||
> [line][line.bot-socket.socket-writeln] irc-write add-method | ||
\begin{code} | ||
[line][line.bot-socket.socket-writeln] irc-write add-method | ||
\end{code} | ||
|
||
Connect to the server, returning the bot object | ||
|
||
> [][ "NICK " nickname.,irc-write. ] set-nick add-method | ||
> [][ "USER " nickname.," +iw ",nickname.," :",nickname.,irc-write. ] set-status add-method | ||
> [][ | ||
> server.port.socket | ||
> dup.'line-channel` | ||
> self.bot-socket:;. | ||
> bot-lines:;. | ||
> set-nick;. | ||
> self.set-status;. | ||
> ] bot-connect add-method | ||
\begin{code} | ||
[][ | ||
"NICK " nickname.,irc-write. | ||
] set-nick add-method | ||
|
||
[][ | ||
"USER " nickname.," +iw ",nickname.," :",nickname.,irc-write. | ||
] set-status add-method | ||
|
||
[][ | ||
server.port.socket | ||
dup.'line-channel` | ||
self.bot-socket:;. | ||
bot-lines:;. | ||
set-nick;. | ||
self.set-status;. | ||
] bot-connect add-method | ||
\end{code} | ||
|
||
Methods to join channels, identify with nickserv and chat: | ||
|
||
> [channel][ "JOIN " channel.,irc-write. ] join add-method | ||
> [password][ "PRIVMSG nickserv :identify " password.,irc-write. ] identify add-method | ||
> [channel message][ "PRIVMSG " channel. , " :" , message. , irc-write. ] say add-method | ||
\begin{code} | ||
[channel][ | ||
"JOIN " channel.,irc-write. | ||
] join add-method | ||
|
||
[password][ | ||
"PRIVMSG nickserv :identify " password.,irc-write. | ||
] identify add-method | ||
|
||
[channel message][ | ||
"PRIVMSG " channel. , " :" , message. , irc-write. | ||
] say add-method | ||
\end{code} | ||
|
||
Return the list of responses received from the server. Blocks if no | ||
responses have yet been received. | ||
|
||
> [][ bot-lines.line-channel-getall ] bot-responses add-method | ||
\begin{code} | ||
[][ | ||
bot-lines.line-channel-getall | ||
] bot-responses add-method | ||
\end{code} | ||
|
||
Utility words to evaluate cf code. These should probably be in the | ||
prelude: | ||
|
||
> [ tokenize parse 'gc,[[]]` timelimit;make-limited-thread spawn thread-join to-string 2 sdrop dup. count 2 - stake ] eval set | ||
\begin{code} | ||
[ | ||
tokenize parse 'gc,[[]]` timelimit; | ||
make-limited-thread spawn thread-join | ||
to-string 2 sdrop dup. count 2 - stake | ||
] eval set | ||
\end{code} | ||
|
||
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 | ||
\begin{code} | ||
[ | ||
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 | ||
\end{code} | ||
|
||
Is it a private message? | ||
|
||
> [ response-type. "PRIVMSG" swap. = ] privmsg? set | ||
\begin{code} | ||
[ response-type. "PRIVMSG" swap. = ] privmsg? set | ||
\end{code} | ||
|
||
Is it for the channel we are monitoring? | ||
|
||
> [ [response-channel.]`= ] channel? set | ||
\begin{code} | ||
[ [response-channel.]`= ] channel? set | ||
\end{code} | ||
|
||
Is it for us? | ||
|
||
> [][ response-text. nickname. swap. head?. ] for-bot? add-method | ||
\begin{code} | ||
[][ | ||
response-text. nickname. swap. head?. | ||
] for-bot? add-method | ||
\end{code} | ||
|
||
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.self.for-bot?;.[response-text.nickname.count 1 + sdrop][drop.0]if][drop.0]if][drop.0]if] wanted-messages add-method | ||
\begin{code} | ||
[][ | ||
dup.privmsg?.[ | ||
dup.channel.channel?.[ | ||
dup.self.for-bot?;.[ | ||
response-text.nickname.count 1 + sdrop | ||
][ | ||
drop.0 | ||
]if | ||
][ | ||
drop.0 | ||
]if | ||
][ | ||
drop.0 | ||
]if | ||
] wanted-messages add-method | ||
\end{code} | ||
|
||
Get all responses, filter for the messages we want | ||
|
||
> [][bot-responses.[self.wanted-messages;.]map.[]filter.] messages-to-eval add-method | ||
\begin{code} | ||
[][ | ||
bot-responses.[ | ||
self.wanted-messages;. | ||
]map.[]filter. | ||
] messages-to-eval add-method | ||
\end{code} | ||
|
||
Build the expression to evaluate on another thread: | ||
|
||
> [ dup.count textlimit; < [ ] [ textlimit; stake "...", ] if ] limit-string set | ||
> [][ | ||
> messages-to-eval.[ | ||
> eval.limit-string.channel.swap.say.42 | ||
> ] map.drop. | ||
> ] handle-messages add-method | ||
|
||
> [][ handle-messages.bot-loop. ] bot-loop add-method | ||
|
||
> [password][ bot-connect.password.identify.channel.join. ] start add-method | ||
> [][ self.unit.[ bot-loop;. ] make-thread spawn ] daemonize add-method | ||
|
||
> drop. | ||
\begin{code} | ||
[ | ||
dup.count textlimit; < [ | ||
] [ | ||
textlimit; stake "...", | ||
] if | ||
] limit-string set | ||
[][ | ||
messages-to-eval.[ | ||
eval.limit-string.channel.swap.say.42 | ||
] map.drop. | ||
] handle-messages add-method | ||
|
||
[][ | ||
handle-messages.bot-loop. | ||
] bot-loop add-method | ||
|
||
[password][ | ||
bot-connect.password.identify.channel.join. | ||
] start add-method | ||
|
||
[][ | ||
self.unit.[ bot-loop;. ] make-thread spawn | ||
] daemonize add-method | ||
|
||
drop. | ||
\end{code} | ||
\end{document} |