• Simple IRC bot
    13 replies, posted
Hi everyone, People who are frequently on IRC probably tried to create their own IRC bot. There are several ways to do so, like modifying a PHP, Perl or Python script. However, the downsides (for especially new coders) of these ways are it's relatively difficult to understand the language and using code you don't understand. To allow these new coders to experiment with IRC bots I started [I]Simple IRC bot[/I], which runs the scripts and handles all IRC related stuff. The application works with [I]PascalScript[/I] for the script engine, which is easy to understand and work with (although advanced coders may find the syntax a bit strange). Because this project is still in alpha/beta status, there aren't many functions yet. However, I'm working hard on adding new events/functions/features. But it's already possible to make your first IRC bot. Also, Linux and Mac OS X binaries are planned when the Windows build is stable. More info and a download can be found at [URL]http://sircbot.limetric.com/[/URL] . Feel free to join our IRC channel if you're in need of help ( irc.gtanet.com #sircbot ).
I like this effort of helping other programmers with IRC related code. I guess I can help by linking to some example code as well. I wrote up an IRC networking library in C# quite a while ago, and it's been sitting around. You can find the source here: [url]http://code.assembla.com/HeronIRC/subversion/nodes/HeronIRC[/url] Currently the project is maintained by myself and AzuiSleet.
[QUOTE=VoiDeD;20218424]I like this effort of helping other programmers with IRC related code. I guess I can help by linking to some example code as well. I wrote up an IRC networking library in C# quite a while ago, and it's been sitting around. You can find the source here: [url]http://code.assembla.com/HeronIRC/subversion/nodes/HeronIRC[/url] Currently the project is maintained by myself and AzuiSleet.[/QUOTE] Blimey, Voided, a gift from heaven, just what I needed! Can't wait to try this out! However, I couldn't find anything regarding licensing, could you please provide us/me more information regarding this?
[QUOTE=Shammah;20218854]Blimey, Voided, a gift from heaven, just what I needed! Can't wait to try this out! However, I couldn't find anything regarding licensing, could you please provide us/me more information regarding this?[/QUOTE] Absolutely no license whatsoever. Feel free to do whatever you like with it.
Made my own IRC bot in PHP a while ago, was quite a hassle. I see how both your library/framework could be useful for starters. Good job!
Here's my horrible mess of spaghetti Perl code that I used to use as an IRC bot. 384 lines of goodiness: [highlight]WARNING THIS CODE IS SHIT[/highlight] [code] use Net::IRC; use HTTP::Lite; use XML::Simple; use Data::Dumper; print "LOG> Started.\n"; my $irc = new Net::IRC; my $conn = $irc->newconn( Nick => 'Turb_Bot', Server => shift || 'irc.freenode.net', Port => 6667, Ircname => 'Turb_Bot', Username => 'Turb_Bot'); $conn->{channel} = shift || '#hexxeh'; my %ban_list; my %admin_list; my %admins; my %CONSTANTS; my $news_cache; my $digg_cache; my $news_age; my $digg_age; $admins{"Turbulence"} = "PASSWORD GOES HERE"; $CONSTANTS{"pi"} = 3.14159265358979323846; $CONSTANTS{"e"} = 2.71828182845904523536; $CONSTANTS{"phi"} = 1.6180339887498948482; print "LOG> Configured.\n"; sub exitTurbbot { $conn->privmsg($conn->{channel},"6[TurbBot] TurbBot is now exiting."); exit; } $SIG{INT} = \&exitTurbbot; sub do_auth { # here you can stick shit that auths the bot with nickserv or something } sub leave_irc { } sub on_public { my ($c, $event) = @_; my $text = $event->{args}[0]; if($text=~/^-tb (.*)$/) { do_tb_cmd($c, $1, $event->{nick}); } print "<" . $event->{nick} . "> " . $text . "\n"; } $conn->add_handler('public',\&on_public); sub do_tb_cmd { ($c,$cmd,$nick) = @_; if($ban_list{$nick} > time()) { $user_banned = 1; } else { $user_banned = 0; } if(! $user_banned) { if($cmd=~/^news$/) { $conn->privmsg($conn->{channel},"4Headlines © Copyright News Limited."); $news_http = new HTTP::Lite; my $news_content; if(time() > ($news_age + 300)) { $news_req = $news_http->request('http://feeds.news.com.au/public/rss/2.0/heraldsun_top_stories_254.xml') or warn 'fail: $1'; $news_cache = $news_content = XMLin($news_http->body()); $news_age = time(); } else { $news_content = $news_cache; } $news_ref = $news_content; %news_hash = %$news_ref; $i = 0; $conn->privmsg($conn->{channel},"6[News] For more info on a story, say '-tb news <story id>'"); while(%news_hash->{channel}->{item}->[$i] && $i < 5) { @news_arr = %news_hash->{channel}->{item}->[$i]; $news_desc = @news_arr[0]->{description}; $news_desc=~s/<.*?>//g; $conn->privmsg($conn->{channel},"6[News] " . ($i+1) . " - " . @news_arr[0]->{title}); #sleep 0.2; $i++; } } if($cmd=~/^news (\d+)$/) { if($1 > 0 && $1 < 6) { $conn->privmsg($conn->{channel},"4Headlines © Copyright News Limited."); $news_http = new HTTP::Lite; my $news_content; if(time() > ($news_age + 300)) { $news_req = $news_http->request('http://feeds.news.com.au/public/rss/2.0/heraldsun_top_stories_254.xml') or warn 'fail: $1'; $news_cache = $news_content = XMLin($news_http->body()); $news_age = time(); } else { $news_content = $news_cache; } $news_ref = $news_content; %news_hash = %$news_ref; @news_arr = %news_hash->{channel}->{item}->[$1-1]; $news_desc = @news_arr[0]->{description}; $news_desc=~s/<.*?>//g; $conn->privmsg($conn->{channel},"6[News] " . @news_arr[0]->{title}); $descr = @news_arr[0]->{description}; $descr=~s/<.*?>//g; $conn->privmsg($conn->{channel},"6[News] " . $descr); $conn->privmsg($conn->{channel},"6[News] 12" . @news_arr[0]->{guid}); } } if($cmd=~/^digg$/) { $conn->privmsg($conn->{channel},"4Digg Headlines © Copyright Digg & Contributors."); $news_http = new HTTP::Lite; if(time() > ($digg_age + 300)) { $digg_cache = $news_req = $news_http->request('http://feeds.digg.com/digg/popular.rss') or warn 'fail: $1'; $digg_age = time(); } else { $news_req = $digg_cache; } $news_ref = XMLin($news_http->body()); %news_hash = %$news_ref; $i = 0; $conn->privmsg($conn->{channel},"6[Digg] For more info on a headline, say '-tb digg <headline id>'"); #while(%news_hash->{channel}->{item}->[$i]) { while($i < 5) { @news_arr = %news_hash->{channel}->{item}->[$i]; $news_desc = @news_arr[0]->{description}; $news_desc=~s/<.*?>//g; $conn->privmsg($conn->{channel},"6[Digg] " . ($i+1) . " - " . @news_arr[0]->{title}); #sleep 0.2; $i++; } } if($cmd=~/^digg (\d+)$/) { if($1 > 0 && $1 < 6) { $conn->privmsg($conn->{channel},"4Digg Headlines © Copyright Digg & Contributors."); $news_http = new HTTP::Lite; if(time() > ($digg_age + 300)) { $digg_cache = $news_req = $news_http->request('http://feeds.digg.com/digg/popular.rss') or warn 'fail: $1'; $digg_age = time(); } else { $news_req = $digg_cache; } $news_ref = XMLin($news_http->body()); %news_hash = %$news_ref; @news_arr = %news_hash->{channel}->{item}->[$1-1]; $news_desc = @news_arr[0]->{description}; $news_desc=~s/<.*?>//g; $conn->privmsg($conn->{channel},"6[Digg] " . @news_arr[0]->{title}); $descr = @news_arr[0]->{description}; $descr=~s/<.*?>//g; $conn->privmsg($conn->{channel},"6[Digg] " . $descr); $conn->privmsg($conn->{channel},"6[Digg] 12" . @news_arr[0]->{guid}->{content}); } } if($cmd=~/^req (.+)$/) { open(REQ,">>TurbBot_Requests.txt"); print REQ "<$nick> $1 \n"; close REQ; $conn->privmsg($conn->{channel},"6[Request] Thanks " . $nick . ", your feature request has been recorded."); } if($cmd=~/^extensive research (.+)$/) { $u = $1; $u=~s/ /_/; $conn->privmsg($conn->{channel},"6[Extensive Research] Google is your friend... 12http://en.wikipedia.org/wiki/" . $u); } if($cmd=~/^dice\s*$/ || $cmd=~/^dice (\d+)$/) { if($1 && $1 > 0 && $1 < 11) { $numdice = $1; } else { $numdice = 1; } my $str; for($i = 0; $i < $numdice; $i++) { if($i != 0) { $str = $str . ", "; } $dice = int(rand(1)*6) + 1; $str = $str . $dice; } $conn->privmsg($conn->{channel},"6[Dice] You rolled " . $str); } if($cmd=~/^rr$/) { $conn->privmsg($conn->{channel},"6[Russian Roulette] $nick chambers a single bullet..."); sleep 2; $conn->privmsg($conn->{channel},"6[Russian Roulette] $nick slowly draws the gun to his temple..."); sleep 2; if(rand(1) > 0.5) { $conn->privmsg($conn->{channel},"6[Russian Roulette] 4BLAM! $nick shot himself."); } else { $wmsg = int(rand(2)); if($wmsg == 0) { $conn->privmsg($conn->{channel},"6[Russian Roulette] Close one! $nick lives to fight another day."); } if($wmsg == 1) { $conn->privmsg($conn->{channel},"6[Russian Roulette] Click!"); } if($wmsg == 2) { $conn->privmsg($conn->{channel},"6[Russian Roulette] $nick just dodged a Darwin Award."); } } } if($cmd=~/^help$/) { $conn->privmsg($conn->{channel},"6[Help] Hi there! Thanks for using TurbBot, Turbulence's IRC Bot."); $conn->privmsg($conn->{channel},"6[Help] All TurbBot commands follow this rule: -tb <command> [<optional parameters>]"); $conn->privmsg($conn->{channel},"6[Help] Current TurbBot commands: help, news, digg, rr, extensive research, calc, req, and dice."); #$conn->privmsg($conn->{channel},"6[Help] For more info on a certain command, say -tb help <command>"); } if($cmd=~/^help news$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb news"); $conn->privmsg($conn->{channel},"6[Help] This command retreives the Top 10 headlines from the Herald Sun."); $conn->privmsg($conn->{channel},"6[Help] You can find out more information about an article (including the link) by saying 3-tb news <article id>"); } if($cmd=~/^help digg$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb digg"); $conn->privmsg($conn->{channel},"6[Help] This command retreives the Top 10 headlines from Digg.com"); $conn->privmsg($conn->{channel},"6[Help] You can find out more information about an article (including the link) by saying 3-tb digg <article id>"); } if($cmd=~/^help req$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb req"); $conn->privmsg($conn->{channel},"6[Help] You can request additional features to be added to TurbBot with this command"); $conn->privmsg($conn->{channel},"6[Help] Simply type into chat 3-tb req <requested feature>"); } if($cmd=~/^help rr$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb rr"); $conn->privmsg($conn->{channel},"6[Help] You can play Russian Roulette with TurbBot!"); $conn->privmsg($conn->{channel},"6[Help] Just say 3-tb rr"); } if($cmd=~/^help extensive research$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb extensive research"); $conn->privmsg($conn->{channel},"6[Help] TurbBot is able to carry out extensive research into any subject for you."); $conn->privmsg($conn->{channel},"6[Help] That assignment due tomorrow? No problems! Just cheat off TurbBot."); $conn->privmsg($conn->{channel},"6[Help] Just say 3-tb extensive research <subject>"); } if($cmd=~/^help calc$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb calc"); $conn->privmsg($conn->{channel},"6[Help] You can harness the computing power of the Perl language (although stripped down) with the calc command"); $conn->privmsg($conn->{channel},"6[Help] You can use any number, the decimal point, the characters +, -, *, / and parenthesis (brackets) in your expression"); $conn->privmsg($conn->{channel},"6[Help] Powers can be calculated by using a double asterisk, eg 2**4 evaluates to 16."); $conn->privmsg($conn->{channel},"6[Help] Calculator also supports certain mathematical constants. You can use these by enclosing the constant name in square brackets."); $conn->privmsg($conn->{channel},"6[Help] The constants which are currently supported are; Pi - [pi], Euler's Number - [e], Phi (Golden Ratio) - [phi]"); $conn->privmsg($conn->{channel},"6[Help] Just say 3-tb calc <expression>"); } if($cmd=~/^help dice$/) { $conn->privmsg($conn->{channel},"6[Help] Help for 3-tb dice"); $conn->privmsg($conn->{channel},"6[Help] You can roll up to 10 dice at once with TurbBot!"); $conn->privmsg($conn->{channel},"6[Help] Just say 3-tb dice [number of dice]"); } if($cmd=~/^echo (.*)$/) { $conn->privmsg($conn->{channel},"6[Echo] <$nick> $1"); } if($cmd=~/^calc (.*)$/) { $expr = $1; $expr=~s/\[pi\]/$CONSTANTS{pi}/g; $expr=~s/\[e\]/$CONSTANTS{e}/g; $expr=~s/\[phi\]/$CONSTANTS{phi}/g; if($expr=~m/^[0-9\.\-+*\/\s\(\)\[\]]*$/) { $r = eval($expr) or $@; if($@) { if($@=~m/^Illegal division by zero/) { $conn->privmsg($conn->{channel},"6[Calculator] 4 LOL U CANT DIVIED BAI ZEER0!"); } else { $conn->privmsg($conn->{channel},"6[Calculator] 4" . $@); } } else { $conn->privmsg($conn->{channel},"6[Calculator] " . $r); } } else { $conn->privmsg($conn->{channel},"6[Calculator] You have used illegal characters in your expression. Valid characters are numbers, decimal points, +, -, *, /, and parenthesis."); } } } else { $conn->privmsg($nick,"4You are currently banned from using TurbBot. Please try again later."); } } sub on_msg { my ($c,$event) = @_; if($event->{args}->[0]=~/^auth (.*)$/i) { if($admins{$event->{nick}} eq $1) { $admin_list{$event->{nick}} = 1; if($event->{nick} eq "Turbulence") { $admin_list{$event->{nick}} = 2; } $conn->privmsg($event->{nick},"3Your admin privileges have been applied."); $conn->privmsg($conn->{channel},"6[Admin] " . $event->{nick} . " is now a TurbBot Admin."); } else { $conn->privmsg($event->{nick},"4Incorrect password!"); } } else { if($admin_list{$event->{nick}}) { if($event->{args}->[0]=~/^--ban (\d+) (.*)$/i) { $bansecs = $1 * 60; $ban_list{$2} = time() + $bansecs; $conn->privmsg($conn->{channel},"6[Admin] $2 has been banned from TurbBot for $1 minutes, by " . $event->{nick}); } if($event->{args}->[0]=~/^--unban (.*)$/i) { $ban_list{$1} = 0; $conn->privmsg($conn->{channel},"6[Admin] $1 has been unbanned from TurbBot, by " . $event->{nick}); } if($event->{args}->[0]=~/^--grant (.*)$/i) { $ban_list{$1} = 0; $conn->privmsg($conn->{channel},"6[Admin] $1 has been granted TurbBot admin, by " . $event->{nick}); } if($event->{args}->[0]=~/^--revoke (.*)$/i) { $ban_list{$1} = 0; if($admin_list{$1} > $admin_list{$event->{nick}}) { $conn->privmsg($event->{nick},"4You cannot revoke $1's admin privileges!"); } else { $conn->privmsg($conn->{channel},"6[Admin] " . $event->{nick} . " has revoked $1's admin privileges."); } } if($event->{args}->[0]=~/^--doauth/i) { do_auth(); } if($event->{args}->[0]=~/^--pm ([a-zA-Z_\-\@\#]+) (.+)$/i) { $conn->privmsg($1,$2); } if($event->{args}->[0]=~/^--eval (.+)$/i) { $conn->privmsg($event->{nick},"DEBUG> $1"); eval($1) or warn $@; } } else { $conn->privmsg($event->{nick},"4Sorry, but you haven't authenticated with TurbBot yet."); $conn->privmsg($event->{nick},"4Please say 3/msg TurbBot auth <your password>"); } } } $conn->add_handler('msg', \&on_msg); print "LOG> Initializing...\n"; my $i = 0; while($i < 20) { $irc->do_one_loop(); $i++; print "LOG> *\n"; } print "LOG> Connecting...\n"; print "\n"; print "\n"; do_auth(); $conn->join($conn->{channel}); $conn->privmsg($conn->{channel},"6[TurbBot] Hello! For help, type 3-tb help"); print "LOG> Connected.\n"; $irc->start(); [/code] It's been superseded by my C# IRC bot though
The problem with HeronIRC and turb_ his code is that new coders won't understand it. I mean, there are enough PHP/Perl/Python bots like I said before. But I wasn't able to find a good working IRC bot application for new coders. So I made my own. :)
Lua: [url]http://upl.luahelp.com/uploads/iOjdPqD8/irc.rar[/url] Example: [lua] local irc = require "irc" local channel = "#example" local s = irc.new{ nick = "LuaBot" } --optional username, realname s:hook("OnConnect", function() s:join(channel) end) s:hook("OnJoin", function(user, channel) print(("%s!%s@%s joined %s"):format(user.nick, user.username, user.host, channel)) end) s:hook("OnPart", function(user, channel) print(("%s!%s@%s left %s"):format(user.nick, user.username, user.host, channel)) end) s:hook("OnChat", function(user, channel, message) print(("[%s] %s: %s"):format(channel, user.nick, message)) end) assert(s:connect("irc.gamesurge.net")) --default port is 6667 while true do irc.think() --does not block, so you can do other stuff in the main loop end[/lua] I have the equivalent in D, Ruby and Go, too, if anyone is interested.
[code] def parse(self, msg): prefix, trailing = '', None if msg[0] == ':': prefix, msg = msg[1:].split(' ', 1) if msg.find(' :') != -1: msg, trailing = msg.split(' :', 1) args = msg.split() args.append(trailing) return prefix, args.pop(0), args [/code] The superior IRC Parser.
[QUOTE=blankthemuffin;20228779][code] def parse(self, msg): prefix, trailing = '', None if msg[0] == ':': prefix, msg = msg[1:].split(' ', 1) if msg.find(' :') != -1: msg, trailing = msg.split(' :', 1) args = msg.split() args.append(trailing) return prefix, args.pop(0), args [/code] The superior IRC Parser.[/QUOTE] Shouldn't you initialize prefix to None, too? The empty string is a horrible default value.
Hey, I'm actually having fun helping Ywa with testing the bot/pascalscript-ing etc :P :P
I think there was some reason I didn't, looking at it now probably because of old code.
I made this simple IRC bot a while ago for practice in Ruby. [url]http://github.com/tjlevine/Ruby-Bot-for-IRC[/url]
In case someone cares. Released 0.1.0.3 and 0.1.0.4 a few days ago. Change-log can be found here: [url]http://sircbot.limetric.com/wiki/index.php/Change-log_%28Development%29[/url] Also working on a file-system to read and write plain text & INI files.
Sorry, you need to Log In to post a reply to this thread.