Upgrade help plugin
[dcbot.git] / dcbot.rb
blob830c996f5080787558235eb66367f2794a48c78a
1 #!/usr/bin/env ruby
3 require 'rubygems'
4 require 'optparse'
5 require 'eventmachine'
6 require './config'
7 require './dcprotocol'
8 require './keyboard'
9 require './plugin'
10 require 'pp'
12 SLEEP_TABLE = [1, 2, 5, 15, 30, 60, 120, 300]
14 RUBYBOT_VERSION = "0.1"
16 def main
17   # parse args
18   options = {}
19   options[:config_file] = "dcbot.conf"
20   OptionParser.new do |opts|
21     opts.banner = "Usage: dcbot.rb [options]"
22     
23     opts.on("--config filename", "Use filename as the config file", "[default: dcbot.conf]") do |filename|
24       options[:config_file] = filename
25     end
26     opts.on("--[no-]debug", "Sets the debug flag") { |flag| options[:debug] = flag }
27   end.parse!
28   
29   config = IniReader.read(options[:config_file])
30   
31   global_config = config.find { |section| section[0] == "global" }
32   if options.has_key? :debug then
33     $debug = options[:debug]
34   elsif global_config and global_config[1].has_key? "debug" then
35     debug = global_config[1]["debug"].downcase
36     if debug == "true" then
37       $debug = true
38     else
39       $debug = false
40     end
41   end
42   
43   connections = config.select { |section| section[0] == "connection" }
44   # FIXME: use all config sections
45   connection = connections[0][1]
46   host = connection["host"]
47   port = connection["port"].to_i
48   nickname = connection["nickname"]
49   description = connection["description"]
50   
51   if connection.has_key? "prefix" then
52     PluginBase.cmd_prefix = connection["prefix"]
53   end
54   
55   EventMachine::run do
56     EventMachine::open_keyboard KeyboardInput
57     setupConnection(host, port, nickname, description, 0)
58   end
59   puts "Shutting Down"
60 end
62 def setupConnection(host, port, nickname, description, sleep)
63   $socket = DCClientProtocol.connect(host, port, nickname,
64                                      :description => description, :debug => $debug,
65                                      :version => RUBYBOT_VERSION) do |c|
66     c.registerCallback :message do |socket, sender, message, isprivate|
67       if isprivate or sender == "*Dtella" then
68         puts "<#{sender}> #{message}"
69       end
70       if message[0,1] == PluginBase::CMD_PREFIX then
71         cmd, args = message[1..-1].split(" ", 2)
72         args = "" if args.nil?
73         if cmd == "reload" and isprivate then
74           # special sekrit reload command
75           PluginBase.loadPlugins
76           socket.sendPrivateMessage(sender, "Plugins have been reloaded")
77         elsif cmd == "quit" and isprivate then
78           # super-sekrit quit command
79           socket.close
80         elsif PluginBase.has_command?(cmd) then
81           begin
82             PluginBase.dispatch(socket, cmd, sender, isprivate, args)
83           rescue StandardError => e
84             socket.sendPrivateMessage(sender, "An error occurred executing your command: #{e.to_s}")
85             STDERR.puts "ERROR: #{e.to_s}"
86             PP.pp(e.backtrace, STDERR)
87           end
88         elsif isprivate then
89           socket.sendPrivateMessage(sender, "Unknown command: #{PluginBase::CMD_PREFIX}#{cmd}")
90         end
91       end
92     end
93     c.registerCallback :error do |socket, message|
94       STDERR.puts "! #{message}"
95     end
96     c.registerCallback :peer_error do |socket, peer, message|
97       STDERR.puts "! Peer #{peer.host}:#{peer.port}"
98     end
99     c.registerCallback :unbind do |socket|
100       if c.quit then
101         # this is our only socket for the moment
102         EventMachine.stop_event_loop
103       else
104         EventMachine::add_timer(SLEEP_TABLE[sleep]) do
105           sleep += 1 unless sleep == SLEEP_TABLE.size - 1
106           setupConnection(host, port, nickname, description, sleep)
107         end
108       end
109     end
110     c.registerCallback :connected do |socket|
111       puts "Connected"
112       socket.registerCallback :unbind do |socket|
113         if c.quit then
114           # this is our only socket for the moment
115           EventMachine.stop_event_loop
116         else
117           setupConnection(host, port, nickname, description, 0)
118         end
119       end
120     end
121     c.registerCallback :reverse_connection do |socket, nick|
122       puts "* Bouncing RevConnectToMe back to user: #{nick}"
123     end
124     c.registerCallback :peer_initialized do |socket, peer|
125       puts "* Connecting to peer: #{peer.host}:#{peer.port}"
126     end
127     c.registerCallback :peer_unbind do |socket, peer|
128       puts "* Connection to peer #{peer.remote_nick} closed"
129     end
130     c.registerCallback :peer_get do |socket,peer,filename|
131       puts "* Peer #{peer.remote_nick} requested: #{filename}"
132     end
133   end
136 main