-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.rb
143 lines (120 loc) · 3.81 KB
/
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
require 'lib/net-toc/toc'
require 'core/plugin_system'
require 'core/core_extensions'
require 'config'
#The bot class
class Bot
def initialize
Plugins.bot = self
load_plugins
@quit = false
end
def my_names
@my_names ||= [BotConfig::Nicknames, BotConfig::Name].flatten
end
def load_plugins
puts "Loading all plugins....."
Plugins.clear_registered
Plugins.clear_commands
Dir["#{BotConfig::PluginDir}/*.rb"].each{ |x| load x }
puts "Plugins Loaded"
end
def quit
@quit = true
end
def send_im_to(username, message)
@client.buddy_list.buddy_named(username).send_im(message)
end
def send_exception_to_admins(e)
BotConfig::AdminUsers.each do |username|
send_im_to(username, 'Hi, an exception occurred:')
send_im_to(username, e.inspect)
send_im_to(username, e.backtrace.join("<br/>"))
end
end
def start
puts "Starting up..."
@client = Net::TOC.new(BotConfig::Name, BotConfig::Password)
@client.on_im do |message, buddy|
command_executed = false
final_message, speaker, command_name, arguments = parse_message(message, buddy)
if speaker
speaker = @client.buddy_list.buddy_named(speaker)
else
speaker = buddy
end
#Command dispatch
if command_name
command = Plugins.commands[command_name]
if command && speaker_can_execute_command(command, speaker.screen_name)
plugin = Plugins.registered[command[:plugin_name]]
plugin.send("#{command[:type]}_#{command_name}", {:buddy => buddy, :speaker => speaker, :cmd_args => arguments, :message => final_message })
command_executed = true
end
end
#Plugin Callbacks
Plugins.registered.each do |name, instance|
if buddy.screen_name == speaker.screen_name
#We got a private message
instance.send(:on_private_message, final_message, buddy, command_executed)
elsif command_name
#It's a directed message in a blast group (most likely a command)
instance.send(:on_directed_message, final_message, speaker, buddy, command_executed)
else
#it's a blast group message not directed at us
instance.send(:on_non_directed_message, final_message, speaker, buddy, command_executed)
end
end
end
@client.connect
@client.wait 3
puts 'Bot Started'
while !@quit
begin
sleep 1
rescue Exception => e
send_exception_to_admins(e)
end
end
puts "Bot finished"
@client.disconnect
end
private
def speaker_can_execute_command(command, speaker)
command[:type] == "public" || BotConfig::AdminUsers.include?(speaker)
end
def parse_message(message, buddy)
#Strip HTML
message = message.gsub(/<\/?[^>]*>/, "")
#If it's a blast group, lets find the actual sender of the message
if buddy.screen_name.match(/^\[.+?\]$/) #Check the buddy name is in the form: [buddy_name]
speaker = message.match(/^\((.+)\)/)[1] #Match the speaker
else
speaker = nil
end
#Split the message into arguments
parts = message.split(" ")
#if it was sent to a blast group
if speaker
parts.shift
#If the message was directed to me, then I have a command
if parts[0].downcase == BotConfig::Name || BotConfig::Nicknames.include?(parts[0].downcase)
parts.shift
command = parts[0]
arguments = parts[1, parts.size]
else
command = nil
arguments = []
end
else
#The message was directly sent to me, so it's a command
command = parts[0]
arguments = parts[1, parts.size]
end
final_message = parts.join(" ")
return final_message, speaker, command, arguments
end
end
#Main
bot = Bot.new
bot.start