forked from Pistos/Mathetes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathirc-bot.rb
210 lines (176 loc) · 4.72 KB
/
irc-bot.rb
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
require 'silverplatter/log'
require 'silverplatter/irc/connection'
require 'mathetes'
require 'traited'
require 'yaml'
require 'pp'
Thread.abort_on_exception = true
def escape_quotes( s )
temp = ""
s.each_byte do |b|
if b == 39
temp << 39
temp << 92
temp << 39
end
temp << b
end
temp
end
module Mathetes
DO_LOAD_CONF = true
DONT_LOAD_CONF = false
class IRCBot
def initialize
@conf = YAML.load_file 'mathetes-config.yaml'
@irc = SilverPlatter::IRC::Connection.new(
@conf['server']['host'],
:log => SilverPlatter::Log.to_console( :formatter => SilverPlatter::Log::ColoredDebugConsole )
)
reset DONT_LOAD_CONF
puts "Initialized."
end
def reset( load_conf = DO_LOAD_CONF )
puts "Resetting..."
kill_threads
unsubscribe_listeners
parted = part_channels
if load_conf
@conf = YAML.load_file 'mathetes-config.yaml'
end
initialize_hooks
initialize_plugins
join_channels parted
puts "Reset."
end
def kill_threads
if @threads
@threads.each do |t|
t.kill
end
end
@threads = Array.new
end
def unsubscribe_listeners
return if @hooks.nil?
@hooks[ :JOIN ].each do |hook|
@irc.unsubscribe hook
end
end
def part_channels( channels = nil )
if @irc.connected?
channels ||= @irc.channels.channels
@irc.send_part 'Parting.', *channels
end
channels || []
end
def initialize_hooks
@hooks = {
:PRIVMSG => Array.new,
:NOTICE => Array.new,
:JOIN => Array.new,
}
end
def initialize_plugins
@conf[ 'plugins' ].each do |plugin|
begin
load "mathetes/plugins/#{plugin}.rb"
rescue Exception => e
$stderr.puts "Plugin load error: #{e.message}"
$stderr.puts e.backtrace.join( "\n\t" )
end
end
Plugins.constants.each do |cname|
constant = Plugins.const_get( cname )
if constant.respond_to?( :new )
constant.new( self )
end
end
end
def join_channels( channels = [] )
channels.each do |c|
@irc.send_join c.name
channel = @conf[ 'channels' ].find { |ch| ch[ 'name' ] == c.name }
if channel && channel[ 'ops' ]
@irc.send_privmsg "OP #{ channel[ 'name' ] }", 'ChanServ'
end
end
end
def start
puts "Starting... "
File.open( 'mathetes.pid', 'w' ) do |f|
f.puts Process.pid
end
@irc.connect
@irc.login( @conf[ 'nick' ], 'Mathetes', 'Mathetes Christou' )
@irc.send_privmsg "IDENTIFY #{ @conf[ 'password' ] }", 'NickServ'
@conf[ 'channels' ].each do |channel|
@irc.send_join channel[ 'name' ]
if channel[ 'ops' ]
@irc.send_privmsg "OP #{ channel[ 'name' ] }", 'ChanServ'
end
end
puts "Startup complete."
@irc.read_loop do |message|
case message.symbol
when :PRIVMSG, :NOTICE
next if @conf[ 'ignores' ].find { |ignored_nick|
message && message.from && SilverPlatter::IRC::Hostmask.new( ignored_nick, "*", "*", @irc ) =~ message.from
}
@hooks[ message.symbol ].each do |h|
if h.regexp.nil? || h.regexp =~ message.text
h.call( message )
end
end
end
end
end
# --------------------------------------------
def say( message, destination )
@irc.send_privmsg( message, destination )
end
def ban( user, channel, seconds = 24 * 60 * 60 )
@irc.send_raw( 'MODE', channel, '+b', user.hostmask.to_s )
Thread.new do
sleep seconds
@irc.send_raw( 'MODE', channel, '-b', user.hostmask.to_s )
end
end
def kick( *args )
@irc.send_kick *args
end
def nick
@conf[ 'nick' ]
end
# --------------------------------------------
def hook_notice( args = {}, &block )
@hooks[ :NOTICE ] << Hooks::NOTICE.new( args, &block )
end
def hook_privmsg( args = {}, &block )
@hooks[ :PRIVMSG ] << Hooks::PRIVMSG.new( args, &block )
end
def hook_join( &block )
listener = @irc.subscribe( :JOIN ) do |listener,message|
block.call( message )
end
@hooks[ :JOIN ] << listener
end
def new_thread( &block )
t = Thread.new do
begin
block.call
rescue Exception => e
$stderr.puts "Exception in thread: #{e.class}: #{e}"
$stderr.puts e.backtrace.join( "\n\t" )
end
end
@threads << t
t
end
end
end
$mathetes = Mathetes::IRCBot.new
Signal.trap( 'HUP' ) do
$mathetes.reset
end
$mathetes.start