From: Martin DeMello Date: 2009-10-19T20:44:15+09:00 Subject: Re: [QUIZ] IRC Teams (#221) The main idea behind this quiz was to show how easy it is to get an irc bot up and running in ruby, especially given the number of bot frameworks out there. I chose to base my bot on rif [http://gitorious.org/ruby-irc], a nice lightweight library with everything I needed to get started immediately. The code consists of a Teams class, which does all the actual work of maintaining teams, and a TeamBot, which inherits from RIF::Bot and handles the IRC part of it. For the sake of simplicity, the bot frontend does no real validation; it just unpacks an incoming message into a command and arguments, and blindly sends those arguments to the Teams object. All public methods on the Teams object accept a player name as a first argument, whether they need it or not, and return either a string or an array of strings, or raise an exception. The bot sends the return value to the channel; an array is sent one message at a time. ------------------------------------------------------------------------------------- gem 'rif' require 'rif/bot' class TeambotError < Exception end def TeambotError(foo) TeambotError.new(foo) end class Teams attr_accessor :teams, :members def initialize @teams = {} @members = {} end def create(player, team) raise TeambotError("team #{team} already created") if teams[team] teams[team] = true "created team #{team}" end def delete(player, team) teams.delete(team) members.delete_if {|k,v| v == team} "deleted team #{team}" end def join(player, team) raise TeambotError("no such team: #{team}") if not teams[team] members[player] = team "#{player} has joined team #{team}" end def leave(player, *args) team = members.delete(player) "#{player} has left team #{team}" end def reset(*args) @members = {} @teams = {} "deleted all teams" end def show(player, *args) if args[0] == 'my' members[player] elsif args[0] == 'teams' teams.map {|team, _| "#{team}: #{show_players(team)}"} elsif args[0] == 'team' show_players(team) end end private def players(team) members.select {|k,v| v == team}.keys end def show_players(team) players(team).join(" ") end end class TeamBot < RIF::Bot attr_reader :teams, :channel def initialize(channel, nick, server, port, username) @teams = Teams.new @channel = channel super(nick, server, port, username) end def on_endofmotd(event) join(channel) end def on_message(event) return unless event.channel == channel msg, *args = event.message.split(" ") player = event.nick begin *ret = teams.send(msg, player, *args) rescue NameError ret = nil rescue TeambotError => e ret = [e.message] end ret.each {|m| send_message(channel, m)} if ret end end if __FILE__ == $0 channel = "##{ARGV[0]}" bot = TeamBot.new(channel, "teambot", "irc.freenode.net", 6667, "RIF Bot") bot.connect end martin