spox-mod_spox 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/CHANGELOG +5 -0
  2. data/README.rdoc +61 -1
  3. data/bin/mod_spox +1 -7
  4. data/data/mod_spox/extras/AutoKick.rb +3 -2
  5. data/data/mod_spox/extras/AutoMode.rb +2 -1
  6. data/data/mod_spox/extras/AutoRejoin.rb +5 -4
  7. data/data/mod_spox/extras/Bouncer.rb +243 -131
  8. data/data/mod_spox/extras/FloodKicker.rb +2 -1
  9. data/data/mod_spox/extras/Fortune.rb +5 -1
  10. data/data/mod_spox/extras/Karma.rb +2 -1
  11. data/data/mod_spox/extras/Logger.rb +11 -9
  12. data/data/mod_spox/extras/NickServ.rb +2 -1
  13. data/data/mod_spox/extras/PhpCli.rb +1 -1
  14. data/data/mod_spox/extras/PhpFuncLookup.rb +2 -1
  15. data/data/mod_spox/extras/RegexTracker.rb +2 -1
  16. data/data/mod_spox/extras/Roulette.rb +2 -1
  17. data/data/mod_spox/extras/Seen.rb +10 -8
  18. data/data/mod_spox/extras/Topten.rb +2 -1
  19. data/data/mod_spox/extras/Translate.rb +2 -1
  20. data/data/mod_spox/extras/Twitter.rb +1 -1
  21. data/data/mod_spox/plugins/Authenticator.rb +7 -7
  22. data/data/mod_spox/plugins/Banner.rb +6 -6
  23. data/data/mod_spox/plugins/BotNick.rb +2 -1
  24. data/data/mod_spox/plugins/Initializer.rb +4 -4
  25. data/data/mod_spox/plugins/Joiner.rb +1 -1
  26. data/data/mod_spox/plugins/PluginLoader.rb +1 -1
  27. data/data/mod_spox/plugins/Ponger.rb +8 -8
  28. data/data/mod_spox/plugins/Status.rb +1 -1
  29. data/lib/mod_spox/Bot.rb +27 -27
  30. data/lib/mod_spox/BotConfig.rb +17 -21
  31. data/lib/mod_spox/Filter.rb +29 -0
  32. data/lib/mod_spox/FilterManager.rb +63 -0
  33. data/lib/mod_spox/Helpers.rb +120 -14
  34. data/lib/mod_spox/Loader.rb +1 -1
  35. data/lib/mod_spox/MessageFactory.rb +10 -2
  36. data/lib/mod_spox/Pipeline.rb +66 -61
  37. data/lib/mod_spox/PluginManager.rb +5 -5
  38. data/lib/mod_spox/PriorityQueue.rb +21 -8
  39. data/lib/mod_spox/Sockets.rb +6 -6
  40. data/lib/mod_spox/Timer.rb +3 -3
  41. data/lib/mod_spox/Version.rb +2 -2
  42. data/lib/mod_spox/handlers/UserHost.rb +32 -0
  43. data/lib/mod_spox/handlers/Whois.rb +7 -7
  44. data/lib/mod_spox/messages/incoming/Pong.rb +11 -2
  45. data/lib/mod_spox/messages/incoming/UserHost.rb +24 -0
  46. data/lib/mod_spox/messages/internal/FilterAdd.rb +20 -0
  47. data/lib/mod_spox/messages/internal/FilterList.rb +18 -0
  48. data/lib/mod_spox/messages/internal/FilterListing.rb +22 -0
  49. data/lib/mod_spox/messages/internal/FilterRemove.rb +20 -0
  50. data/lib/mod_spox/messages/internal/Incoming.rb +15 -0
  51. data/lib/mod_spox/migrations/006_ignore.rb +21 -0
  52. data/lib/mod_spox/models/Nick.rb +11 -0
  53. data/lib/mod_spox/rfc2812.rb +2 -1
  54. data/lib/mod_spox/rfc2812_full.rb +185 -0
  55. data/tests/BotHolder.rb +7 -1
  56. data/tests/handlers/tc_Created.rb +28 -8
  57. data/tests/handlers/tc_Invite.rb +11 -9
  58. data/tests/handlers/tc_Join.rb +36 -16
  59. data/tests/handlers/tc_Kick.rb +27 -6
  60. data/tests/handlers/tc_Mode.rb +23 -13
  61. data/tests/handlers/tc_Names.rb +29 -9
  62. data/tests/handlers/tc_Nick.rb +30 -8
  63. data/tests/handlers/tc_Part.rb +30 -20
  64. data/tests/handlers/tc_Ping.rb +32 -19
  65. data/tests/handlers/tc_Pong.rb +28 -8
  66. data/tests/handlers/tc_Privmsg.rb +33 -13
  67. data/tests/handlers/tc_Quit.rb +30 -17
  68. data/tests/handlers/tc_Who.rb +8 -3
  69. data/tests/handlers/tc_Whois.rb +7 -3
  70. data/tests/lib/tc_BotConfig.rb +35 -0
  71. data/tests/lib/tc_Helpers.rb +139 -0
  72. data/tests/lib/tc_PriorityQueue.rb +31 -0
  73. metadata +17 -2
@@ -30,11 +30,11 @@ module ModSpox
30
30
  def initialize(pipeline)
31
31
  @plugins = Hash.new
32
32
  @pipeline = pipeline
33
- @pipeline.hook(self, :load_plugin, :Internal_PluginLoadRequest)
34
- @pipeline.hook(self, :unload_plugin, :Internal_PluginUnloadRequest)
35
- @pipeline.hook(self, :reload_plugins, :Internal_PluginReload)
36
- @pipeline.hook(self, :send_modules, :Internal_PluginModuleRequest)
37
- @pipeline.hook(self, :plugin_request, :Internal_PluginRequest)
33
+ @pipeline.hook(self, :load_plugin, ModSpox::Messages::Internal::PluginLoadRequest)
34
+ @pipeline.hook(self, :unload_plugin, ModSpox::Messages::Internal::PluginUnloadRequest)
35
+ @pipeline.hook(self, :reload_plugins, ModSpox::Messages::Internal::PluginReload)
36
+ @pipeline.hook(self, :send_modules, ModSpox::Messages::Internal::PluginModuleRequest)
37
+ @pipeline.hook(self, :plugin_request, ModSpox::Messages::Internal::PluginRequest)
38
38
  @plugins_module = Module.new
39
39
  @plugin_lock = Mutex.new
40
40
  load_plugins
@@ -10,28 +10,29 @@ module ModSpox
10
10
  # Create a priority queue
11
11
  def initialize
12
12
  @target_queues = {}
13
- @queues = {:PRIORITY => Queue.new, :NEW => Queue.new, :NORMAL => Queue.new, :WHOCARES => Queue.new}
13
+ @queues = {:PRIORITY => Array.new, :NEW => Array.new, :NORMAL => Array.new, :WHOCARES => Array.new}
14
14
  @lock = Mutex.new
15
15
  end
16
16
 
17
- # target:: message target (targets starting with * will be labelled WHOCARES
17
+ # target:: message target (targets starting with * will be given lowest priority)
18
18
  # message:: message to send
19
19
  # This prioritizes output to help reduce lag when lots of output
20
20
  # is being sent to another target. This will automatically decide
21
21
  # how to queue the message based on the target
22
22
  def priority_queue(target, message)
23
+ target = target.to_s
23
24
  @lock.synchronize do
24
25
  target.downcase!
25
26
  @target_queues[target] = Queue.new unless @target_queues[target]
26
27
  if(target[0].chr == '*')
27
28
  @target_queues[target] << message
28
- @queues[:WHOCARES] << @target_queues[target]
29
+ add_queue(:WHOCARES, @target_queues[target])
29
30
  else
30
31
  @target_queues[target] << message
31
32
  if(@target_queues[target].size < 2)
32
- @queues[:NEW] << @target_queues[target]
33
+ add_queue(:NEW, @target_queues[target])
33
34
  else
34
- @queues[:NORMAL] << @target_queues[target]
35
+ add_queue(:NORMAL, @target_queues[target])
35
36
  end
36
37
  end
37
38
  end
@@ -44,7 +45,7 @@ module ModSpox
44
45
  @lock.synchronize do
45
46
  @target_queues[:general] = Queue.new unless @target_queues[:general]
46
47
  @target_queues[:general] << message
47
- @queues[:PRIORITY] << @target_queues[:general]
48
+ add_queue(:PRIORITY, @target_queues[:general])
48
49
  end
49
50
  end
50
51
 
@@ -57,13 +58,25 @@ module ModSpox
57
58
  @lock.synchronize do
58
59
  [:PRIORITY, :NEW, :NORMAL, :WHOCARES].each do |k|
59
60
  unless(@queues[k].empty?)
60
- m = @queues[k].pop.pop
61
- break
61
+ q = @queues[k].shift
62
+ unless(q.empty?)
63
+ m = q.pop
64
+ add_queue(k, q) unless(q.empty?)
65
+ break
66
+ end
62
67
  end
63
68
  end
64
69
  end
65
70
  raise Exceptions::EmptyQueue.new if m.nil?
66
71
  return m
67
72
  end
73
+
74
+ private
75
+
76
+ def add_queue(name, queue)
77
+ unless(@queues[name].include?(queue))
78
+ @queues[name] << queue
79
+ end
80
+ end
68
81
  end
69
82
  end
@@ -27,12 +27,12 @@ module ModSpox
27
27
  @dcc_wait = 30
28
28
  @pipeline = bot.pipeline
29
29
  @factory = bot.factory
30
- @pipeline.hook(self, :check_dcc, :Incoming_Privmsg)
31
- @pipeline.hook(self, :return_socket, :Internal_DCCRequest)
32
- @pipeline.hook(self, :dcc_listener, :Internal_DCCListener)
33
- @pipeline.hook(self, :disconnect_irc, :Internal_Disconnected)
34
- @pipeline.hook(self, :queue_messages, :Internal_QueueSocket)
35
- @pipeline.hook(self, :unqueue_messages, :Internal_UnqueueSocket)
30
+ @pipeline.hook(self, :check_dcc, ModSpox::Messages::Incoming::Privmsg)
31
+ @pipeline.hook(self, :return_socket, ModSpox::Messages::Internal::DCCRequest)
32
+ @pipeline.hook(self, :dcc_listener, ModSpox::Messages::Internal::DCCListener)
33
+ @pipeline.hook(self, :disconnect_irc, ModSpox::Messages::Internal::Disconnected)
34
+ @pipeline.hook(self, :queue_messages, ModSpox::Messages::Internal::QueueSocket)
35
+ @pipeline.hook(self, :unqueue_messages, ModSpox::Messages::Internal::UnqueueSocket)
36
36
  @queues = {:irc => Queue.new, :dcc => Queue.new}
37
37
  @queue_messages = false
38
38
  end
@@ -13,9 +13,9 @@ module ModSpox
13
13
  def initialize(timer, pipeline)
14
14
  @pipeline = pipeline
15
15
  @timer = timer
16
- {:Internal_TimerAdd => :add_message,
17
- :Internal_TimerRemove => :remove_message,
18
- :Internal_TimerClear => :clear}.each_pair do |type,method|
16
+ {ModSpox::Messages::Internal::TimerAdd => :add_message,
17
+ ModSpox::Messages::Internal::TimerRemove => :remove_message,
18
+ ModSpox::Messages::Internal::TimerClear => :clear}.each_pair do |type,method|
19
19
  @pipeline.hook(self, method, type)
20
20
  end
21
21
  end
@@ -1,6 +1,6 @@
1
1
  module ModSpox
2
- @botversion='0.3.1'
3
- @botcodename='potato shotgun'
2
+ @botversion='0.3.2'
3
+ @botcodename='potato cannon'
4
4
  @verbosity = 0
5
5
  @mod_spox_path = nil
6
6
  @daemon_bot = false
@@ -0,0 +1,32 @@
1
+ require 'mod_spox/handlers/Handler'
2
+ require 'mod_spox/messages/incoming/UserHost'
3
+ module ModSpox
4
+ module Handlers
5
+ class YourHost < Handler
6
+ def initialize(handlers)
7
+ handlers[RFC[:RPL_USERHOST][:value]] = self
8
+ end
9
+ # :not.configured 302 spox :mod_spox=+~mod_spox@some.host
10
+ def process(string)
11
+ begin
12
+ mod = string.dup
13
+ mod.slice!(0)
14
+ server = mod.slice!(0, mod.index(' ')-1)
15
+ 3.times{ mod.slice!(0, mod.index(' ')) }
16
+ mod.slice!(0)
17
+ nickname = mod.slice!(0, mod.index('=')-1)
18
+ mod.slice!(0, 1)
19
+ username = mod.slice!(0, mod.index('@')-1)
20
+ mod.slice!(0)
21
+ host = mod
22
+ nick = find_model(nickname)
23
+ nick.username = username
24
+ nick.host = host
25
+ return Messages::Incoming::UserHost.new(string, server, nick, username, host)
26
+ rescue Object => boom
27
+ Logger.error("Failed to process USERHOST message. Reason: #{boom}")
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -29,7 +29,7 @@ module ModSpox
29
29
  string.slice!(0..string.index(' '))
30
30
  end
31
31
  case string.slice!(0..string.index(' ')-1)
32
- whenRFC[:RPL_WHOISUSER][:value]
32
+ when RFC[:RPL_WHOISUSER][:value]
33
33
  string.slice!(0)
34
34
  string.slice!(0..string.index(' '))
35
35
  nick = find_model(string.slice!(0..string.index(' ')-1))
@@ -42,7 +42,7 @@ module ModSpox
42
42
  nick.save_changes
43
43
  @cache[nick.nick] = Messages::Incoming::Whois.new(nick)
44
44
  @cache[nick.nick].raw_push(orig)
45
- whenRFC[:RPL_WHOISCHANNELS][:value]
45
+ when RFC[:RPL_WHOISCHANNELS][:value]
46
46
  2.times{string.slice!(0..string.index(' '))}
47
47
  nick = find_model(string.slice!(0..string.index(' ')-1))
48
48
  @cache[nick.nick] = Messages::Incoming::Whois.new(nick) unless @cache[nick.nick]
@@ -63,7 +63,7 @@ module ModSpox
63
63
  end
64
64
  end
65
65
  @cache[nick.nick].raw_push(orig)
66
- whenRFC[:RPL_WHOISSERVER][:value]
66
+ when RFC[:RPL_WHOISSERVER][:value]
67
67
  2.times{string.slice!(0..string.index(' '))}
68
68
  nick = find_model(string.slice!(0..string.index(' ')-1))
69
69
  string.slice!(0)
@@ -71,13 +71,13 @@ module ModSpox
71
71
  nick.connected_to = string.slice!(0..string.index(' ')-1)
72
72
  nick.save_changes
73
73
  @cache[nick.nick].raw_push(orig)
74
- whenRFC[:RPL_WHOISIDENTIFIED][:value]
74
+ when RFC[:RPL_WHOISIDENTIFIED][:value]
75
75
  2.times{string.slice!(0..string.index(' '))}
76
76
  nick = find_model(string.slice!(0..string.index(' ')-1))
77
77
  @cache[nick.nick] = Messages::Incoming::Whois.new(nick) unless @cache[nick.nick]
78
78
  nick.auth.services_identified = true
79
79
  @cache[nick.nick].raw_push(orig)
80
- whenRFC[:RPL_WHOISIDLE][:value]
80
+ when RFC[:RPL_WHOISIDLE][:value]
81
81
  2.times{string.slice!(0..string.index(' '))}
82
82
  nick = find_model(string.slice!(0..string.index(' ')-1))
83
83
  string.slice!(0)
@@ -87,13 +87,13 @@ module ModSpox
87
87
  nick.connected_at = Time.at(string.slice!(0..string.index(' ')-1).to_i)
88
88
  nick.save_changes
89
89
  @cache[nick.nick].raw_push(orig)
90
- whenRFC[:RPL_WHOISOPERATOR][:value]
90
+ when RFC[:RPL_WHOISOPERATOR][:value]
91
91
  2.times{string.slice!(0..string.index(' '))}
92
92
  nick = find_model(string.slice!(0..string.index(' ')-1))
93
93
  string.slice!(0)
94
94
  @cache[nick.nick] = Messages::Incoming::Whois.new(nick) unless @cache[nick.nick]
95
95
  @cache[nick.nick].raw_push(orig)
96
- whenRFC[:RPL_ENDOFWHOIS][:value]
96
+ when RFC[:RPL_ENDOFWHOIS][:value]
97
97
  2.times{string.slice!(0..string.index(' '))}
98
98
  nick = find_model(string.slice!(0..string.index(' ')-1))
99
99
  @cache[nick.nick] = Messages::Incoming::Whois.new(nick) unless @cache[nick.nick]
@@ -1,8 +1,17 @@
1
- require 'mod_spox/messages/incoming/Ping'
1
+ require 'mod_spox/messages/incoming/Message'
2
2
  module ModSpox
3
3
  module Messages
4
4
  module Incoming
5
- class Pong < Ping
5
+ class Pong < Message
6
+ # server of origin
7
+ attr_reader :server
8
+ # string
9
+ attr_reader :string
10
+ def initialize(raw, server, string)
11
+ super(raw)
12
+ @server = server
13
+ @string = string
14
+ end
6
15
  end
7
16
  end
8
17
  end
@@ -0,0 +1,24 @@
1
+ require 'mod_spox/messages/incoming/Message'
2
+ module ModSpox
3
+ module Messages
4
+ module Incoming
5
+ class UserHost < Message
6
+ # name of server bot is connected to
7
+ attr_reader :servername
8
+ # nick model for given user
9
+ attr_reader :nick
10
+ # username for nick
11
+ attr_reader :username
12
+ # host of nick
13
+ attr_reader :host
14
+ def initialize(raw, server, nick, username, host)
15
+ super(raw)
16
+ @servername = server
17
+ @nick = nick
18
+ @username = username
19
+ @host = host
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'mod_spox/messages/internal/Request'
2
+ module ModSpox
3
+ module Messages
4
+ module Internal
5
+ class FilterAdd
6
+ # ModSpox::Filter
7
+ attr_reader :filter
8
+ # Type of messages to filter
9
+ attr_reader :type
10
+ # filter:: ModSpox::Filter type object
11
+ # type:: message type to filter
12
+ # Add a new filter to the pipeline
13
+ def initialize(filter, type)
14
+ @filter = filter
15
+ @type = type
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ require 'mod_spox/messages/internal/Request'
2
+ module ModSpox
3
+ module Messages
4
+ module Internal
5
+ class FilterList
6
+ # message type
7
+ attr_reader :type
8
+
9
+ # type:: message type
10
+ # Return list of currently enabled filters. If type is set,
11
+ # only filters for that type of message will be returned
12
+ def initialize(type)
13
+ @type = type
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'mod_spox/messages/internal/Request'
2
+ module ModSpox
3
+ module Messages
4
+ module Internal
5
+ class FilterListing
6
+ # message type
7
+ attr_reader :type
8
+ # filters currently enabled
9
+ attr_reader :filters
10
+
11
+ # type:: message type
12
+ # filters:: array of ModSpox::Filter objects
13
+ # Holds filter listing for given type. If type
14
+ # is nil, all enabled filters are returned
15
+ def initialize(type, filters)
16
+ @type = type
17
+ @filters = filters
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require 'mod_spox/messages/internal/Request'
2
+ module ModSpox
3
+ module Messages
4
+ module Internal
5
+ class FilterRemove
6
+ # ModSpox::Filter
7
+ attr_reader :filter
8
+ # Type of messages to filter
9
+ attr_reader :type
10
+ # filter:: ModSpox::Filter type object
11
+ # type:: message type to filter
12
+ # Add a new filter to the pipeline
13
+ def initialize(filter, type)
14
+ @filter = filter
15
+ @type = type
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module ModSpox
2
+ module Messages
3
+ module Internal
4
+ # This is used for incoming messages by the bot. It's
5
+ # only real purpose is for processing messages coming
6
+ # in from the bouncer, so the bot will perform commands.
7
+ class Incoming
8
+ attr_reader :message
9
+ def initialize(m)
10
+ @message = m
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module ModSpox
2
+ module Migrations
3
+ class Ignore < Sequel::Migration
4
+ def up
5
+ Database.db.create_table(:ignored_nicks) do
6
+ foreign_key :nick_id, :null => false, :table => :nicks, :unique => true
7
+ varchar :type, :null => false, :default => 'output'
8
+ end
9
+ Database.db.create_table(:ignored_masks) do
10
+ primary_key :id, :null => false
11
+ varchar :mask, :null => false, :unique => true
12
+ varchar :type, :null => false, :default => 'output'
13
+ end
14
+ end
15
+ def down
16
+ Database.db.drop_table(:ignored_nicks)
17
+ Database.db.drop_table(:ignored_masks)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -96,6 +96,17 @@ module ModSpox
96
96
  super(val)
97
97
  end
98
98
 
99
+ # override the default here and build the source
100
+ # from parts if they exist but the source is empty
101
+ def source
102
+ unless(values[:source])
103
+ if(values[:host] && values[:username])
104
+ update :source => "#{values[:nick]}!#{values[:username]}@#{values[:host]}"
105
+ end
106
+ end
107
+ super
108
+ end
109
+
99
110
  # Auth model associated with nick
100
111
  def auth
101
112
  if(auths.empty?)
@@ -15,11 +15,12 @@ module ModSpox
15
15
  :QUIT => {:value => :QUIT, :handlers => ['Quit']},
16
16
  #client server messages#
17
17
  :RPL_WELCOME => {:value => '001', :handlers => ['Welcome']},
18
- :RPL_YOURHOST => {:value => '002'},
18
+ :RPL_YOURHOST => {:value => '002', :handlers => ['YourHost']},
19
19
  :RPL_CREATED => {:value => '003', :handlers => ['Created']},
20
20
  :RPL_MYINFO => {:value => '004', :handlers => ['MyInfo']},
21
21
  :RPL_BOUNCE => {:value => '005', :handlers => ['Bounce']},
22
22
  #response replies#
23
+ :RPL_USERHOST => {:value => '302', :handlers => ['UserHost']},
23
24
  :RPL_WHOISIDENTIFIED => {:value => '307', :handlers => ['Whois']},
24
25
  :RPL_WHOISUSER => {:value => '311', :handlers => ['Whois']},
25
26
  :RPL_WHOISSERVER => {:value => '312', :handlers => ['Whois']},
@@ -0,0 +1,185 @@
1
+ module ModSpox
2
+
3
+ RFC = {
4
+ # basic
5
+ :INVITE => {:value => :INVITE, :handlers => ['Invite']},
6
+ :JOIN => {:value => :JOIN, :handlers => ['Join']},
7
+ :KICK => {:value => :KICK, :handlers => ['Kick']},
8
+ :MODE => {:value => :MODE, :handlers => ['Mode']},
9
+ :NICK => {:value => :NICK, :handlers => ['Nick']},
10
+ :NOTICE => {:value => :NOTICE, :handlers => ['Notice']},
11
+ :PART => {:value => :PART, :handlers => ['Part']},
12
+ :PING => {:value => :PING, :handlers => ['Ping']},
13
+ :PONG => {:value => :PONG, :handlers => ['Pong']},
14
+ :PRIVMSG => {:value => :PRIVMSG, :handlers => ['Privmsg']},
15
+ :QUIT => {:value => :QUIT, :handlers => ['Quit']},
16
+ #client server messages#
17
+ :RPL_WELCOME => {:value => '001', :handlers => ['Welcome']},
18
+ :RPL_YOURHOST => {:value => '002'},
19
+ :RPL_CREATED => {:value => '003', :handlers => ['Created']},
20
+ :RPL_MYINFO => {:value => '004', :handlers => ['MyInfo']},
21
+ :RPL_BOUNCE => {:value => '005', :handlers => ['Bounce']},
22
+ #response replies#
23
+ :RPL_USERHOST => {:value => '302', :handlers => ['UserHost']},
24
+ :RPL_ISON => {:value => '303'},
25
+ :RPL_AWAY => {:value => '301'},
26
+ :RPL_UNAWAY => {:value => '305'},
27
+ :RPL_NOWAWAY => {:value => '306'},
28
+ :RPL_WHOISIDENTIFIED => {:value => '307', :handlers => ['Whois']},
29
+ :RPL_WHOISUSER => {:value => '311', :handlers => ['Whois']},
30
+ :RPL_WHOISSERVER => {:value => '312', :handlers => ['Whois']},
31
+ :RPL_WHOISOPERATOR => {:value => '313', :handlers => ['Whois']},
32
+ :RPL_WHOISIDLE => {:value => '317', :handlers => ['Whois']},
33
+ :RPL_ENDOFWHOIS => {:value => '318', :handlers => ['Whois']},
34
+ :RPL_WHOISCHANNELS => {:value => '319', :handlers => ['Whois']},
35
+ :RPL_WHOWASUSER => {:value => '314'},
36
+ :RPL_ENDOFWHOWAS => {:value => '369'},
37
+ :RPL_LISTSTART => {:value => '321'},
38
+ :RPL_LIST => {:value => '322'},
39
+ :RPL_LISTEND => {:value => '323'},
40
+ :RPL_UNIQOPIS => {:value => '325'},
41
+ :RPL_CHANNELMODEIS => {:value => '324'},
42
+ :RPL_NOTOPIC => {:value => '331', :handlers => ['Topic']},
43
+ :RPL_TOPIC => {:value => '332', :handlers => ['Topic']},
44
+ :RPL_TOPICINFO => {:value => '333', :handlers => ['Topic']},
45
+ :RPL_INVITING => {:value => '341'},
46
+ :RPL_SUMMONING => {:value => '342'},
47
+ :RPL_INVITELIST => {:value => '346'},
48
+ :RPL_ENDOFINVITELIST => {:value => '347'},
49
+ :RPL_EXCEPTLIST => {:value => '348'},
50
+ :RPL_ENDOFEXCEPTLIST => {:value => '349'},
51
+ :RPL_VERSION => {:value => '351'},
52
+ :RPL_WHOREPLY => {:value => '352', :handlers => ['Who']},
53
+ :RPL_ENDOFWHO => {:value => '315', :handlers => ['Who']},
54
+ :RPL_NAMREPLY => {:value => '353', :handlers => ['Names']},
55
+ :RPL_ENDOFNAMES => {:value => '366', :handlers => ['Names']},
56
+ :RPL_LINKS => {:value => '364'},
57
+ :RPL_ENDOFLINKS => {:value => '365'},
58
+ :RPL_BANLIST => {:value => '367'},
59
+ :RPL_ENDOFBANLIST => {:value => '368'},
60
+ :RPL_INFO => {:value => '371'},
61
+ :RPL_ENDOFINFO => {:value => '374'},
62
+ :RPL_MOTDSTART => {:value => '375', :handlers => ['Motd']},
63
+ :RPL_MOTD => {:value => '372', :handlers => ['Motd']},
64
+ :RPL_ENDOFMOTD => {:value => '376', :handlers => ['Motd']},
65
+ :RPL_YOUREOPER => {:value => '381'},
66
+ :RPL_REHASHING => {:value => '382'},
67
+ :RPL_YOURESERVICE => {:value => '383'},
68
+ :RPL_TIME => {:value => '391'},
69
+ :RPL_USERSSTART => {:value => '392'},
70
+ :RPL_USERS => {:value => '393'},
71
+ :RPL_ENDOFUSERS => {:value => '394'},
72
+ :RPL_NOUSERS => {:value => '395'},
73
+ :RPL_TRACELINK => {:value => '200'},
74
+ :RPL_TRACECONNECTING => {:value => '201'},
75
+ :RPL_TRACEHANDSHAKE => {:value => '202'},
76
+ :RPL_TRACEUNKNOWN => {:value => '203'},
77
+ :RPL_TRACEOPERATOR => {:value => '204'},
78
+ :RPL_TRACEUSER => {:value => '205'},
79
+ :RPL_TRACESERVER => {:value => '206'},
80
+ :RPL_TRACESERVICE => {:value => '207'},
81
+ :RPL_TRACENEWTYPE => {:value => '208'},
82
+ :RPL_TRACECLASS => {:value => '209'},
83
+ :RPL_TRACERECONNECT => {:value => '210'},
84
+ :RPL_TRACELOG => {:value => '261'},
85
+ :RPL_TRACEEND => {:value => '262'},
86
+ :RPL_STATSLINKINFO => {:value => '211'},
87
+ :RPL_STATSCOMMANDS => {:value => '212'},
88
+ :RPL_ENDOFSTATS => {:value => '219'},
89
+ :RPL_STATSUPTIME => {:value => '242'},
90
+ :RPL_STATSOLINE => {:value => '243'},
91
+ :RPL_UMODEIS => {:value => '221'},
92
+ :RPL_SERVLIST => {:value => '234'},
93
+ :RPL_SERVLISTEND => {:value => '235'},
94
+ :RPL_LUSERCLIENT => {:value => '251', :handlers => ['LuserClient']},
95
+ :RPL_LUSEROP => {:value => '252', :handlers => ['LuserOp']},
96
+ :RPL_LUSERUNKNOWN => {:value => '253', :handlers => ['LuserUnknown']},
97
+ :RPL_LUSERCHANNELS => {:value => '254', :handlers => ['LuserChannels']},
98
+ :RPL_LUSERME => {:value => '255', :handlers => ['LuserMe']},
99
+ :RPL_ADMINME => {:value => '256'},
100
+ :RPL_ADMINLOC1 => {:value => '257'},
101
+ :RPL_ADMINLOC2 => {:value => '258'},
102
+ :RPL_ADMINEMAIL => {:value => '259'},
103
+ :RPL_TRYAGAIN => {:value => '263'},
104
+ #error messages#
105
+ :ERR_NOSUCHNICK => {:value => '401'},
106
+ :ERR_NOSUCHSERVER => {:value => '402'},
107
+ :ERR_NOSUCHCHANNEL => {:value => '403'},
108
+ :ERR_CANNOTSENDTOCHAN => {:value => '404'},
109
+ :ERR_TOOMANYCHANNELS => {:value => '405'},
110
+ :ERR_WASNOSUCHNICK => {:value => '406'},
111
+ :ERR_TOOMANYTARGETS => {:value => '407'},
112
+ :ERR_NOSUCHSERVICE => {:value => '408'},
113
+ :ERR_NOORIGIN => {:value => '409'},
114
+ :ERR_NORECIPIENT => {:value => '411'},
115
+ :ERR_NOTEXTTOSEND => {:value => '412'},
116
+ :ERR_NOTOPLEVEL => {:value => '413'},
117
+ :ERR_WILDTOPLEVEL => {:value => '413'},
118
+ :ERR_BADMASK => {:value => '415'},
119
+ :ERR_UNKNOWNCOMMAND => {:value => '421'},
120
+ :ERR_NOMOTD => {:value => '422'},
121
+ :ERR_NOADMININFO => {:value => '423'},
122
+ :ERR_FILEERROR => {:value => '424'},
123
+ :ERR_NONICKNAMEGIVEN => {:value => '431'},
124
+ :ERR_ERRONEOUSNICKNAME => {:value => '432', :handlers => ['BadNick']},
125
+ :ERR_NICKNAMEINUSE => {:value => '433', :handlers => ['NickInUse']},
126
+ :ERR_NICKCOLLISION => {:value => '436'},
127
+ :ERR_UNAVAILRESOURCE => {:value => '437'},
128
+ :ERR_USERNOTINCHANNEL => {:value => '441'},
129
+ :ERR_NOTONCHANNEL => {:value => '442'},
130
+ :ERR_USERONCHANNEL => {:value => '443'},
131
+ :ERR_NOLOGIN => {:value => '444'},
132
+ :ERR_SUMMONDISABLED => {:value => '445'},
133
+ :ERR_USERDISABLED => {:value => '446'},
134
+ :ERR_NOTREGISTERED => {:value => '451'},
135
+ :ERR_NEEDMOREPARAMS => {:value => '461'},
136
+ :ERR_ALREADYREGISTERED => {:value => '462'},
137
+ :ERR_NOPERMFORHOST => {:value => '463'},
138
+ :ERR_PASSWDMISMATCH => {:value => '464'},
139
+ :ERR_YOUREBANNEDCREEP => {:value => '465'},
140
+ :ERR_YOUWILLBEBANNED => {:value => '466'},
141
+ :ERR_KEYSET => {:value => '467'},
142
+ :ERR_CHANNELISFULL => {:value => '471'},
143
+ :ERR_UNKNOWNMODE => {:value => '472'},
144
+ :ERR_INVITEONLYCHAN => {:value => '473'},
145
+ :ERR_BANNEDFROMCHAN => {:value => '474'},
146
+ :ERR_BADCHANNELKEY => {:value => '475'},
147
+ :ERR_BADCHANMASK => {:value => '476'},
148
+ :ERR_NOCHANMODES => {:value => '477'},
149
+ :ERR_BANLISTFULL => {:value => '478'},
150
+ :ERR_NOPRIVILEGES => {:value => '481'},
151
+ :ERR_CHANOPRIVSNEEDED => {:value => '482'},
152
+ :ERR_CANTKILLSERVER => {:value => '483'},
153
+ :ERR_RESTRICTED => {:value => '484'},
154
+ :ERR_UNIQOPPRIVSNEEDED => {:value => '485'},
155
+ :ERR_NOOPERHOST => {:value => '491'},
156
+ :ERR_UMODEUNKNOWNFLAG => {:value => '501'},
157
+ :ERR_USERSDONTMATCH => {:value => '502'},
158
+ #extras#
159
+ :RPL_SERVICEINFO => {:value => '231'},
160
+ :RPL_ENDOFSERVICES => {:value => '232'},
161
+ :RPL_SERVICE => {:value => '233'},
162
+ :RPL_NONE => {:value => '300'},
163
+ :RPL_WHOISCHANOP => {:value => '316'},
164
+ :RPL_KILLDONE => {:value => '361'},
165
+ :RPL_CLOSING => {:value => '362'},
166
+ :RPL_CLOSEEND => {:value => '363'},
167
+ :RPL_INFOSTART => {:value => '373'},
168
+ :RPL_MYPORTIS => {:value => '384'},
169
+ :RPL_STATSCLINE => {:value => '213'},
170
+ :RPL_STATSNLINE => {:value => '214'},
171
+ :RPL_STATSILINE => {:value => '215'},
172
+ :RPL_STATSKLINE => {:value => '216'},
173
+ :RPL_STATSQLINE => {:value => '217'},
174
+ :RPL_STATSYLINE => {:value => '218'},
175
+ :RPL_STATSVLINE => {:value => '240'},
176
+ :RPL_STATSLLINE => {:value => '241'},
177
+ :RPL_STATSHLINE => {:value => '244'},
178
+ :RPL_STATSSLINE => {:value => '244'},
179
+ :RPL_STATSPING => {:value => '246'},
180
+ :RPL_STATSBLINE => {:value => '247'},
181
+ :RPL_STATSDLINE => {:value => '250'},
182
+ :ERR_NOSERVICEHOST => {:value => '492'}
183
+ }
184
+ # i feel kinda dirty after that, but hey, lets keep things interesting!
185
+ end