1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
require 'socket'
module Dinobot
class Bot
def initialize(server, port, nick, pass=nil, &block)
@server = server
@port = port
@nick = nick
@pass = pass
@trigger = '!'
@socket = nil
@modules = Hash.new
@channels = Array.new
instance_eval(&block) if block_given?
end
def connect
@socket = TCPSocket.new(@server, @port)
out "PASS #{@pass}" if @pass
out "NICK #{@nick}"
out "USER #{@nick} 0 * :#{@nick}"
@channels.each do |channel|
join channel
end
end
def connected?
!(@socket.nil? || @socket.closed?)
end
def run
while true
puts "== Connecting to #{@server}:#{@port}."
connect
while str = @socket.gets
str.chomp!
puts "<< " + str.inspect
begin
parse_line(str)
rescue
end
end
puts "== Disconnected."
@socket.close
end
end
def parse_line(str)
out str.sub('PING', 'PONG') if str =~ /^PING /
if str =~ /(\S+) PRIVMSG (\S+) :(.*)/
user, channel, message = str.scan(/(\S+) PRIVMSG (\S+) :(.*)/).first
if message =~ /^#{Regexp.escape(@trigger)}/
message.sub!(@trigger, '')
mod = message.split.first.downcase.intern
if @modules.has_key?(mod)
exec_commands(@modules[mod].call(user, channel, message))
end
end
end
end
def exec_commands(commands)
commands.each do |command|
case command.first
when :say
send(*command) if command.length == 3
when :join, :part
send(*command) if command.length == 2
end
end
end
def out(str)
return unless connected?
puts ">> " + str.inspect
@socket.puts str
end
def say(channel, message)
out "PRIVMSG #{channel} :#{message}"
end
def join(channel)
@channels << channel unless @channels.include?(channel)
out "JOIN #{channel}"
end
def part(channel)
@channels.delete(channel)
out "PART #{channel}"
end
def load_module(mod)
file = Dir.entries(File.dirname(__FILE__)).find { |x| x == mod.to_s.downcase + ".rb" }
if file
puts "== Loading #{mod}."
load file
@modules[mod.downcase] = eval("Dinobot::#{mod}").new
end
end
end
end
|