em-ruby-irc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,8 @@
1
+ = REQUIREMENTS
2
+
3
+ - eventmachine
4
+ - yaml
5
+
6
+ = DESCRIPTION
7
+
8
+ Under major development and major design changes. Will be doing some major reworking, so stay tuned
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require "rake"
2
+ require "rake/clean"
3
+ require "rake/gempackagetask"
4
+ require "rake/rdoctask"
5
+ require "spec/rake/spectask"
6
+
7
+ require 'lib/em-ruby-irc'
8
+
9
+ NAME = 'em-ruby-irc'
10
+ VERSION = EMIRC::VERSION
11
+ TITLE = "EM IRC Bot Framework"
12
+ CLEAN.include ["*.gem", "rdoc"]
13
+ RDOC_OPTS = [
14
+ "-U", "--title", TITLE,
15
+ "--op", "rdoc",
16
+ "--main", "README.rdoc"
17
+ ]
18
+
19
+ Rake::RDocTask.new do |rdoc|
20
+ rdoc.rdoc_dir = "rdoc"
21
+ rdoc.options += RDOC_OPTS
22
+ rdoc.rdoc_files.add %w(README.rdoc lib/**/*.rb)
23
+ end
24
+
25
+ desc "Package"
26
+ task :package => [:clean] do |p|
27
+ sh "gem build #{NAME}.gemspec"
28
+ end
29
+
30
+ desc "Install gem"
31
+ task :install => [:package] do
32
+ sh "sudo gem install ./#{NAME}-#{VERSION} --local"
33
+ end
34
+
35
+ desc "Uninstall gem"
36
+ task :uninstall => [:clean] do
37
+ sh "sudo gem uninstall #{NAME}"
38
+ end
39
+
40
+ desc "Upload gem to gemcutter"
41
+ task :release => [:package] do
42
+ sh "gem push ./#{NAME}-#{VERSION}.gem"
43
+ end
44
+
45
+ desc "Run all specs"
46
+ Spec::Rake::SpecTask.new(:spec) do |t|
47
+ t.spec_files = Dir['spec/**/*_spec.rb']
48
+ end
49
+
50
+ task :default => [:clean, :spec]
51
+
@@ -0,0 +1,12 @@
1
+ module IRC
2
+ class Channel
3
+ attr_reader :name
4
+ attr_accessor :users
5
+
6
+ #Initialize channel and set userlist
7
+ def initialize(name)
8
+ @name = name
9
+ @users = Array.new
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,127 @@
1
+ require 'logger'
2
+
3
+ module IRC
4
+ class Connection < EventMachine::Connection
5
+ attr_reader :realname, :username, :channels, :users, :name, :command_char
6
+ attr_accessor :irc_handlers, :channels, :users, :setup, :nickname
7
+
8
+ def initialize(args)
9
+ begin
10
+ @name = args[:setup].name
11
+ @setup = args[:setup]
12
+ @nickname = @setup.config["nickname"]
13
+ @realname = @setup.config["realname"]
14
+ @username = @setup.config["username"]
15
+ @command_char = @setup.config["command_char"]
16
+ @channels = Array.new
17
+ @users = Array.new
18
+ @irc_handlers = Hash.new()
19
+ super
20
+ rescue => err
21
+ log_error(err)
22
+ end
23
+ end
24
+
25
+ #Start handlers
26
+ def post_init
27
+ logger.debug("Firing post_init")
28
+ begin
29
+ unless setup.startup_handlers.nil?
30
+ setup.startup_handlers.each do |handler|
31
+ handler.call(self) unless handler.nil?
32
+ end
33
+ end
34
+ rescue => err
35
+ log_error(err)
36
+ end
37
+ end
38
+
39
+ def connection_completed
40
+ logger.debug("Firing connection_completed")
41
+ send_to_server "NICK #{@nickname}"
42
+ send_to_server "USER #{@username} 8 * :#{@realname}"
43
+ end
44
+
45
+ def receive_data(data)
46
+ data.split("\n").each do |line|
47
+ log_irc(line)
48
+ IRC::Event.new(line, self)
49
+ end
50
+ end
51
+
52
+ def send_to_server(message)
53
+ log_irc(message)
54
+ send_data "#{message}\n"
55
+ end
56
+
57
+ def unbind
58
+ logger.info("[#{self.name}] Connection lost, sleeping 10 seconds")
59
+ sleep 10
60
+ logger.info("[#{self.name}] Reconnecting to: #{setup.config["server_address"]} Port: #{setup.config["server_port"]}")
61
+ EventMachine::reconnect setup.config["server_address"], setup.config["server_port"].to_i, self
62
+ end
63
+
64
+ def add_message_handler(event_type, proc=nil, &handler)
65
+ self.irc_handlers[event_type] = Array.new unless self.irc_handlers[event_type].class == Array
66
+ self.irc_handlers[event_type] << proc
67
+ end
68
+
69
+ def log
70
+ if @log.nil?
71
+ @log = Logger.new("logs/#{@name}.log")
72
+ @log.level = Logger::INFO
73
+ end
74
+ @log
75
+ end
76
+
77
+ def log_irc(line)
78
+ log.info(line)
79
+ end
80
+
81
+ #Command helpers for easier coding (join, part, quit, kick, ban, etc)
82
+ def join(channel)
83
+ send_to_server("JOIN #{channel}")
84
+ end
85
+
86
+ def part(channel)
87
+ send_to_server("PART #{channel}")
88
+ end
89
+
90
+ def send_message(target, message)
91
+ send_to_server("PRIVMSG #{target} :#{message}")
92
+ end
93
+
94
+ def send_notice(target, message)
95
+ send_to_server("NOTICE #{target} :#{message}")
96
+ end
97
+
98
+ def quit(message)
99
+ send_to_server("QUIT :#{message}")
100
+ end
101
+
102
+ def action(target, message)
103
+ send_ctcp(target, 'ACTION', action);
104
+ end
105
+
106
+ def ctcp(target, type, message)
107
+ send_to_server("PRIVMSG #{target} :\001#{type} #{message}");
108
+ end
109
+
110
+ def kick(channel, target, message="Bye!")
111
+ send_to_server("KICK #{channel} #{target} :#{message}")
112
+ end
113
+
114
+ def op(channel, target)
115
+ mode(channel, "+o", target)
116
+ end
117
+
118
+ def deop(channel, target)
119
+ mode(channel, "+o", target)
120
+ end
121
+
122
+ def mode(target, mode, arg=nil)
123
+ send_to_server("MODE #{target} #{mode} #{arg}") unless arg.nil?
124
+ send_to_server("MODE #{target} #{mode}")
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,65 @@
1
+ require 'yaml'
2
+
3
+ # This is a lookup class for IRC event name mapping
4
+ class EventLookup
5
+ @@lookup = YAML.load_file("#{File.dirname(__FILE__)}/eventmap.yml")
6
+
7
+ # returns the event name, given a number
8
+ def EventLookup::find_by_number(num)
9
+ return @@lookup[num.to_i]
10
+ end
11
+ end
12
+
13
+ # This is a lookup class for IRC event name mapping
14
+ module IRC
15
+ class Event
16
+ attr_reader :hostmask, :message, :event_type, :from, :channel, :target, :mode, :stats
17
+ attr_accessor :connection
18
+ def initialize(data, connection)
19
+ @connection = connection
20
+ data.chomp!
21
+ data.sub!(/^:/, '')
22
+ mess_parts = data.split(':', 2);
23
+ unless mess_parts.nil? or mess_parts.size < 2
24
+ # mess_parts[0] is server info
25
+ # mess_parts[1] is the message that was sent
26
+ @message = mess_parts[1]
27
+ @stats = mess_parts[0].scan(/[\/\=\-\_\~\"\`\|\^\{\}\[\]\w.\#\@\+]+/)
28
+ unless @stats[0].nil?
29
+ if @stats[0].match(/^PING/)
30
+ @event_type = 'ping'
31
+ elsif @stats[1] && @stats[1].match(/^\d+$/)
32
+ @event_type = EventLookup::find_by_number(@stats[1]);
33
+ @channel = @stats[3].downcase unless @stats[3].nil?
34
+ @channel = @stats[3] if @stats[3].nil?
35
+ else
36
+ @event_type = @stats[2].downcase if @stats[2]
37
+ end
38
+
39
+ if @event_type != 'ping'
40
+ @from = @stats[0].downcase
41
+ end
42
+
43
+ # FIXME: this list would probably be more accurate to exclude commands than to include them
44
+ @hostmask = @stats[1] if %W(topic privmsg join).include? @event_type
45
+ @channel = @stats[3].downcase if @stats[3] && !@channel
46
+ @target = @stats[5].downcase if @stats[5]
47
+ @mode = @stats[4] if @stats[4]
48
+ run_handlers(@event_type) unless @event_type.nil?
49
+ end
50
+ end
51
+ #logger.debug(data)
52
+ end
53
+
54
+ def run_handlers(event_type)
55
+ begin
56
+ return if connection.irc_handlers.size == 0 or connection.irc_handlers[event_type].nil?
57
+ connection.irc_handlers[event_type].each do |handler|
58
+ handler.call(self) unless handler.nil?
59
+ end
60
+ rescue => err
61
+ log_error(err)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,19 @@
1
+ module IRC
2
+ class User
3
+ attr_reader :name
4
+ attr_accessor :hostmask, :user_data
5
+ attr_writer :logged_in
6
+
7
+ def initialize(name, hostmask=nil)
8
+ @name = name
9
+ @hostmask = String.new
10
+ @hostmask = hostmask unless hostmask.nil?
11
+ @logged_in = false
12
+ @user_data = nil
13
+ end
14
+
15
+ def logged_in?
16
+ @logged_in
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,107 @@
1
+ module IRC
2
+ class Utils
3
+ #Adds the channel to the global channel list (IRC::Connection#channels) and then returns it
4
+ def self.channel(connection, channel_name)
5
+ channel_name = channel_name.downcase.chomp
6
+ channel = connection.channels.select { |obj| obj.name == channel_name }.first
7
+ if channel.nil?
8
+ channel = IRC::Channel.new(channel_name)
9
+ connection.channels << channel
10
+ end
11
+ return channel
12
+ end
13
+
14
+ #Removes the user from the channel userlist, and if the user is not on any other channel userlists, it deletes it from global as well.
15
+ def self.remove_channel_user(connection, channel_name, user_name)
16
+ user_name = sanitize_nickname(user_name)
17
+ channel_name = channel_name.downcase.chomp
18
+ channel = channel(connection, channel_name)
19
+ user = channel.users.select { |obj| obj.name == user_name }.first
20
+ unless user.nil?
21
+ channel.users.delete(user)
22
+ keep_user = false
23
+ connection.channels.each do |thischannel|
24
+ unless thischannel.users.select { |obj| obj.name == user_name }.first.nil?
25
+ keep_user = true
26
+ end
27
+ end
28
+ connection.users.delete(user) unless keep_user
29
+ end
30
+ end
31
+
32
+ #Removes the channel from the global channel list (IRC::Connection#channels)
33
+ def self.remove_channel(connection, channel_name)
34
+ channel_name = channel_name.downcase.chomp
35
+ channel = connection.channels.select { |obj| obj.name == channel_name }.first
36
+ connection.channels.delete(channel) unless channel.nil?
37
+ end
38
+
39
+ #Creates the user in the channel userlist (IRC::Channel#users) and then returns the user
40
+ def self.channel_user(connection, channel_name, user_name, hostmask=nil)
41
+ return false if channel_name.nil? or user_name.nil?
42
+ user_name = sanitize_nickname(user_name)
43
+ channel_name = channel_name.downcase.chomp
44
+ user = global_user(connection, user_name, hostmask)
45
+ channel = channel(connection, channel_name)
46
+ channel_user = channel.users.select { |obj| obj.name == user_name }.first
47
+ if channel_user.nil?
48
+ channel.users << user
49
+ end
50
+ return user
51
+ end
52
+
53
+ #Returns a user from an event.
54
+ def self.get_channel_user_from_event(event, user=nil)
55
+ if user.nil?
56
+ channel_user(event.connection, event.channel, event.from)
57
+ else
58
+ channel_user(event.connection, event.channel, user)
59
+ end
60
+ end
61
+
62
+ #Creates the user in the global userlist (IRC::Connection#users) and then returns the user
63
+ def self.global_user(connection, user_name, hostmask=nil)
64
+ user_name = sanitize_nickname(user_name)
65
+ user = connection.users.select { |obj| obj.name == user_name }.first
66
+ if user.nil?
67
+ user = IRC::User.new(user_name, hostmask)
68
+ connection.users << user
69
+ end
70
+ user.hostmask = hostmask unless hostmask.nil?
71
+ return user
72
+ end
73
+
74
+ #Update the users hostmask
75
+ def self.update_hostname(connection, user_name, hostmask)
76
+ user_name = sanitize_nickname(user_name)
77
+ user = connection.users.select { |obj| obj.name == user_name }.first
78
+ user.hostmask = hostmask unless user.nil? or hostmask.nil?
79
+ return user
80
+ end
81
+
82
+ def self.sanitize_nickname(nickname)
83
+ return nickname.downcase.chomp.match(/(?![\@\%\&\+])([\-\_\[\]\{\}\\\|\`\^a-zA-Z0-9]*)/)[0]
84
+ end
85
+
86
+ #Converts a hostmask like *brian@*.google.com to .*brian@.*google.com so it can be properly used in a regex
87
+ def self.regex_mask(hostmask)
88
+ hostmask.gsub(/([\[\]\(\)\?\^\$])\\/, '\\1').gsub(/\./, '\.').gsub(/\[/, '\[').gsub(/\]/, '\]').gsub(/\*/, '.*').sub(/^/, '^').sub(/$/, '$')
89
+ end
90
+
91
+ #Sets up all connections into global @@connections
92
+ def self.setup_connections(bot, config)
93
+ connections = {}
94
+ config['networks'].each do |network, server_setup|
95
+ connections[network] = IRC::Setup.new(bot, network, server_setup)
96
+ end
97
+ return connections
98
+ end
99
+
100
+ def self.add_handler(eventname, proc, network)
101
+ network.add_startup_handler(lambda {|bot|
102
+ bot.add_message_handler(eventname, proc)
103
+ })
104
+ end
105
+ end
106
+ end
107
+
@@ -0,0 +1,58 @@
1
+ # This hash is used to store all of the connections, its the only global var set by the library
2
+ @@connections = Hash.new
3
+
4
+ #TODO: need to make setup actually allow multiple connections and to handle all of the EM stuff
5
+
6
+ module IRC
7
+ class Setup
8
+ attr_reader :name, :config
9
+ attr_accessor :connection, :startup_handlers, :memcache, :bot
10
+ def initialize(bot, name, config)
11
+ @name = name
12
+ @connection = nil
13
+ @startup_handlers = Array.new
14
+ @config = config
15
+ @memcache = nil
16
+ @bot = bot
17
+ default_handlers
18
+ end
19
+
20
+ def add_startup_handler(proc=nil, &handler)
21
+ startup_handlers << proc
22
+ end
23
+
24
+ def reset_startup_handlers
25
+ startup_handlers.clear
26
+ end
27
+
28
+ def connect
29
+ begin
30
+ if defined?(EventMachine::fork_reactor)
31
+ logger.warn("Event machine supports forking, attempting to fork.")
32
+ pid = EventMachine::fork_reactor {
33
+ begin
34
+ self.connection = EventMachine::connect(config["server_address"], config["server_port"].to_i, IRC::Connection, :setup => self)
35
+ rescue => err
36
+ log_error(err)
37
+ end
38
+ }
39
+
40
+ File.open("#{self.name}.pid", 'w') {|f| f << pid}
41
+ Process.detach(pid)
42
+ else
43
+ logger.warn("WARNING: Version of eventmachine does not support forking. If you specified multiple connections you will only connect to one.")
44
+ EventMachine::run {
45
+ begin
46
+ self.connection = EventMachine::connect(config["server_address"], config["server_port"].to_i, IRC::Connection, :setup => self)
47
+ rescue => err
48
+ log_error(err)
49
+ end
50
+ }
51
+ end
52
+ rescue => err
53
+ log_error(err)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,72 @@
1
+ module IRC
2
+ class Setup
3
+ def default_handlers
4
+ logger.debug("Starting default handlers")
5
+ begin
6
+ @default_join_handler = Proc.new do |event|
7
+ begin
8
+ #Issues a who command on the channel when I join so I can generate the users hostnames
9
+ event.connection.send_to_server "WHO #{event.message}" if event.from.downcase.chomp == event.connection.nickname.downcase.chomp
10
+ #Make sure the bot has this channel in memory
11
+ user = IRC::Utils.channel_user(event.connection, event.message, event.from, event.hostmask) #connection, channel, user
12
+ rescue => err
13
+ log_error(err)
14
+ end
15
+ end
16
+
17
+ @default_names_reply_handler = Proc.new do |event|
18
+ begin
19
+ users = event.message.split
20
+ users.each do |user|
21
+ channel_user = IRC::Utils.channel_user(event.connection, event.mode, user) #connection, channel, user
22
+ end
23
+ rescue => err
24
+ log_error(err)
25
+ end
26
+ end
27
+
28
+ @default_part_handler = Proc.new do |event|
29
+ begin
30
+ if event.from.downcase.chomp == event.connection.nickname.downcase.chomp
31
+ IRC::Utils.remove_channel(event.connection, event.channel)
32
+ else
33
+ IRC::Utils.remove_channel_user(event.connection, event.channel, event.from)
34
+ end
35
+ rescue => err
36
+ log_error(err)
37
+ end
38
+ end
39
+
40
+ @default_who_reply_handler = Proc.new do |event|
41
+ begin
42
+ IRC::Utils.update_hostname(event.connection, event.stats[7], "#{event.stats[4]}@#{event.stats[5]}")
43
+ rescue => err
44
+ log_error(err)
45
+ end
46
+ end
47
+
48
+ @default_nick_in_use_handler = Proc.new do |event|
49
+ begin
50
+ logger.debug("OMG NICKNAME IS BEING USED!")
51
+ new_nickname = event.connection.nickname[0,14] + rand(9).to_s
52
+ event.connection.send_to_server "NICK #{new_nickname}"
53
+ event.connection.send_to_server "USER #{event.connection.username} 8 * :#{event.connection.realname}"
54
+ event.connection.nickname = new_nickname
55
+ rescue => err
56
+ log_error(err)
57
+ end
58
+ end
59
+
60
+ logger.debug("Registering handlers")
61
+ IRC::Utils.add_handler('join', @default_join_handler, self)
62
+ IRC::Utils.add_handler('namreply', @default_names_reply_handler, self)
63
+ IRC::Utils.add_handler('part', @default_part_handler, self)
64
+ IRC::Utils.add_handler('whoreply', @default_who_reply_handler, self)
65
+ IRC::Utils.add_handler('nicknameinuse', @default_nick_in_use_handler, self)
66
+ IRC::Utils.add_handler('ping', lambda {|event| event.connection.send_to_server("PONG #{event.message}") }, self)
67
+ rescue => err
68
+ log_error(err)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,247 @@
1
+ # 001 ne 1 for the purpose of hash keying apparently.
2
+ 001 : welcome
3
+ 002 : yourhost
4
+ 003 : created
5
+ 004 : myinfo
6
+ 005 : map # Undernet Extension, Kajetan@Hinner.com, 17/11/98
7
+ 006 : mapmore # Undernet Extension, Kajetan@Hinner.com, 17/11/98
8
+ 007 : mapend # Undernet Extension, Kajetan@Hinner.com, 17/11/98
9
+ 008 : snomask # Undernet Extension, Kajetan@Hinner.com, 17/11/98
10
+ 009 : statmemtot # Undernet Extension, Kajetan@Hinner.com, 17/11/98
11
+ 010 : statmem # Undernet Extension, Kajetan@Hinner.com, 17/11/98
12
+ 200 : tracelink
13
+ 201 : traceconnecting
14
+ 202 : tracehandshake
15
+ 203 : traceunknown
16
+ 204 : traceoperator
17
+ 205 : traceuser
18
+ 206 : traceserver
19
+ 208 : tracenewtype
20
+ 209 : traceclass
21
+ 211 : statslinkinfo
22
+ 212 : statscommands
23
+ 213 : statscline
24
+ 214 : statsnline
25
+ 215 : statsiline
26
+ 216 : statskline
27
+ 217 : statsqline
28
+ 218 : statsyline
29
+ 219 : endofstats
30
+ 220 : statsbline # UnrealIrcd, Hendrik Frenzel
31
+ 221 : umodeis
32
+ 222 : sqline_nick # UnrealIrcd, Hendrik Frenzel
33
+ 223 : statsgline # UnrealIrcd, Hendrik Frenzel
34
+ 224 : statstline # UnrealIrcd, Hendrik Frenzel
35
+ 225 : statseline # UnrealIrcd, Hendrik Frenzel
36
+ 226 : statsnline # UnrealIrcd, Hendrik Frenzel
37
+ 227 : statsvline # UnrealIrcd, Hendrik Frenzel
38
+ 231 : serviceinfo
39
+ 232 : endofservices
40
+ 233 : service
41
+ 234 : servlist
42
+ 235 : servlistend
43
+ 241 : statslline
44
+ 242 : statsuptime
45
+ 243 : statsoline
46
+ 244 : statshline
47
+ 245 : statssline # Reserved, Kajetan@Hinner.com, 17/10/98
48
+ 246 : statstline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
49
+ 247 : statsgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
50
+ ### TODO: need numerics to be able to map to multiple strings
51
+ ### 247 : statsxline # UnrealIrcd, Hendrik Frenzel
52
+ 248 : statsuline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
53
+ 249 : statsdebug # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
54
+ 250 : luserconns # 1998-03-15 -- tkil
55
+ 251 : luserclient
56
+ 252 : luserop
57
+ 253 : luserunknown
58
+ 254 : luserchannels
59
+ 255 : luserme
60
+ 256 : adminme
61
+ 257 : adminloc1
62
+ 258 : adminloc2
63
+ 259 : adminemail
64
+ 261 : tracelog
65
+ 262 : endoftrace # 1997-11-24 -- archon
66
+ 265 : n_local # 1997-10-16 -- tkil
67
+ 266 : n_global # 1997-10-16 -- tkil
68
+ 271 : silelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
69
+ 272 : endofsilelist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
70
+ 275 : statsdline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
71
+ 280 : glist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
72
+ 281 : endofglist # Undernet Extension, Kajetan@Hinner.com, 17/10/98
73
+ 290 : helphdr # UnrealIrcd, Hendrik Frenzel
74
+ 291 : helpop # UnrealIrcd, Hendrik Frenzel
75
+ 292 : helptlr # UnrealIrcd, Hendrik Frenzel
76
+ 293 : helphlp # UnrealIrcd, Hendrik Frenzel
77
+ 294 : helpfwd # UnrealIrcd, Hendrik Frenzel
78
+ 295 : helpign # UnrealIrcd, Hendrik Frenzel
79
+ 300 : none
80
+ 301 : away
81
+ 302 : userhost
82
+ 303 : ison
83
+ 304 : rpl_text # Bahamut IRCD
84
+ 305 : unaway
85
+ 306 : nowaway
86
+ 307 : userip # Undernet Extension, Kajetan@Hinner.com, 17/10/98
87
+ 308 : rulesstart # UnrealIrcd, Hendrik Frenzel
88
+ 309 : endofrules # UnrealIrcd, Hendrik Frenzel
89
+ 310 : whoishelp # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
90
+ 311 : whoisuser
91
+ 312 : whoisserver
92
+ 313 : whoisoperator
93
+ 314 : whowasuser
94
+ 315 : endofwho
95
+ 316 : whoischanop
96
+ 317 : whoisidle
97
+ 318 : endofwhois
98
+ 319 : whoischannels
99
+ 320 : whoisvworld # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
100
+ 321 : liststart
101
+ 322 : list
102
+ 323 : listend
103
+ 324 : channelmodeis
104
+ 329 : channelcreate # 1997-11-24 -- archon
105
+ 331 : notopic
106
+ 332 : topic
107
+ 333 : topicinfo # 1997-11-24 -- archon
108
+ 334 : listusage # Undernet Extension, Kajetan@Hinner.com, 17/10/98
109
+ 335 : whoisbot # UnrealIrcd, Hendrik Frenzel
110
+ 341 : inviting
111
+ 342 : summoning
112
+ 346 : invitelist # UnrealIrcd, Hendrik Frenzel
113
+ 347 : endofinvitelist # UnrealIrcd, Hendrik Frenzel
114
+ 348 : exlist # UnrealIrcd, Hendrik Frenzel
115
+ 349 : endofexlist # UnrealIrcd, Hendrik Frenzel
116
+ 351 : version
117
+ 352 : whoreply
118
+ 353 : namreply
119
+ 354 : whospcrpl # Undernet Extension, Kajetan@Hinner.com, 17/10/98
120
+ 361 : killdone
121
+ 362 : closing
122
+ 363 : closeend
123
+ 364 : links
124
+ 365 : endoflinks
125
+ 366 : endofnames
126
+ 367 : banlist
127
+ 368 : endofbanlist
128
+ 369 : endofwhowas
129
+ 371 : info
130
+ 372 : motd
131
+ 373 : infostart
132
+ 374 : endofinfo
133
+ 375 : motdstart
134
+ 376 : endofmotd
135
+ 377 : motd2 # 1997-10-16 -- tkil
136
+ 378 : austmotd # (July01-01)Austnet Extension, found by Andypoo <andypoo@secret.com.au>
137
+ 379 : whoismodes # UnrealIrcd, Hendrik Frenzel
138
+ 381 : youreoper
139
+ 382 : rehashing
140
+ 383 : youreservice # UnrealIrcd, Hendrik Frenzel
141
+ 384 : myportis
142
+ 385 : notoperanymore # Unspecific Extension, Kajetan@Hinner.com, 17/10/98
143
+ 386 : qlist # UnrealIrcd, Hendrik Frenzel
144
+ 387 : endofqlist # UnrealIrcd, Hendrik Frenzel
145
+ 388 : alist # UnrealIrcd, Hendrik Frenzel
146
+ 389 : endofalist # UnrealIrcd, Hendrik Frenzel
147
+ 391 : time
148
+ 392 : usersstart
149
+ 393 : users
150
+ 394 : endofusers
151
+ 395 : nousers
152
+ 401 : nosuchnick
153
+ 402 : nosuchserver
154
+ 403 : nosuchchannel
155
+ 404 : cannotsendtochan
156
+ 405 : toomanychannels
157
+ 406 : wasnosuchnick
158
+ 407 : toomanytargets
159
+ 408 : nosuchservice # UnrealIrcd, Hendrik Frenzel
160
+ 409 : noorigin
161
+ 411 : norecipient
162
+ 412 : notexttosend
163
+ 413 : notoplevel
164
+ 414 : wildtoplevel
165
+ 416 : querytoolong # Undernet Extension, Kajetan@Hinner.com, 17/10/98
166
+ 421 : unknowncommand
167
+ 422 : nomotd
168
+ 423 : noadmininfo
169
+ 424 : fileerror
170
+ 425 : noopermotd # UnrealIrcd, Hendrik Frenzel
171
+ 431 : nonicknamegiven
172
+ 432 : erroneusnickname # This iz how its speld in thee RFC.
173
+ 433 : nicknameinuse
174
+ 434 : norules # UnrealIrcd, Hendrik Frenzel
175
+ 435 : serviceconfused # UnrealIrcd, Hendrik Frenzel
176
+ 436 : nickcollision
177
+ 437 : bannickchange # Undernet Extension, Kajetan@Hinner.com, 17/10/98
178
+ 438 : nicktoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98
179
+ 439 : targettoofast # Undernet Extension, Kajetan@Hinner.com, 17/10/98
180
+ 440 : servicesdown # Bahamut IRCD
181
+ 441 : usernotinchannel
182
+ 442 : notonchannel
183
+ 443 : useronchannel
184
+ 444 : nologin
185
+ 445 : summondisabled
186
+ 446 : usersdisabled
187
+ 447 : nonickchange # UnrealIrcd, Hendrik Frenzel
188
+ 451 : notregistered
189
+ 455 : hostilename # UnrealIrcd, Hendrik Frenzel
190
+ 459 : nohiding # UnrealIrcd, Hendrik Frenzel
191
+ 460 : notforhalfops # UnrealIrcd, Hendrik Frenzel
192
+ 461 : needmoreparams
193
+ 462 : alreadyregistered
194
+ 463 : nopermforhost
195
+ 464 : passwdmismatch
196
+ 465 : yourebannedcreep # I love this one...
197
+ 466 : youwillbebanned
198
+ 467 : keyset
199
+ 468 : invalidusername # Undernet Extension, Kajetan@Hinner.com, 17/10/98
200
+ 469 : linkset # UnrealIrcd, Hendrik Frenzel
201
+ 470 : linkchannel # UnrealIrcd, Hendrik Frenzel
202
+ 471 : channelisfull
203
+ 472 : unknownmode
204
+ 473 : inviteonlychan
205
+ 474 : bannedfromchan
206
+ 475 : badchannelkey
207
+ 476 : badchanmask
208
+ 477 : needreggednick # Bahamut IRCD
209
+ 478 : banlistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98
210
+ 479 : secureonlychannel # pircd
211
+ ### TODO: see above todo
212
+ ### 479 : linkfail # UnrealIrcd, Hendrik Frenzel
213
+ 480 : cannotknock # UnrealIrcd, Hendrik Frenzel
214
+ 481 : noprivileges
215
+ 482 : chanoprivsneeded
216
+ 483 : cantkillserver
217
+ 484 : ischanservice # Undernet Extension, Kajetan@Hinner.com, 17/10/98
218
+ 485 : killdeny # UnrealIrcd, Hendrik Frenzel
219
+ 486 : htmdisabled # UnrealIrcd, Hendrik Frenzel
220
+ 489 : secureonlychan # UnrealIrcd, Hendrik Frenzel
221
+ 491 : nooperhost
222
+ 492 : noservicehost
223
+ 501 : umodeunknownflag
224
+ 502 : usersdontmatch
225
+ 511 : silelistfull # Undernet Extension, Kajetan@Hinner.com, 17/10/98
226
+ 513 : nosuchgline # Undernet Extension, Kajetan@Hinner.com, 17/10/98
227
+ 513 : badping # Undernet Extension, Kajetan@Hinner.com, 17/10/98
228
+ 518 : noinvite # UnrealIrcd, Hendrik Frenzel
229
+ 519 : admonly # UnrealIrcd, Hendrik Frenzel
230
+ 520 : operonly # UnrealIrcd, Hendrik Frenzel
231
+ 521 : listsyntax # UnrealIrcd, Hendrik Frenzel
232
+ 524 : operspverify # UnrealIrcd, Hendrik Frenzel
233
+
234
+ 600 : rpl_logon # Bahamut IRCD
235
+ 601 : rpl_logoff # Bahamut IRCD
236
+ 602 : rpl_watchoff # UnrealIrcd, Hendrik Frenzel
237
+ 603 : rpl_watchstat # UnrealIrcd, Hendrik Frenzel
238
+ 604 : rpl_nowon # Bahamut IRCD
239
+ 605 : rpl_nowoff # Bahamut IRCD
240
+ 606 : rpl_watchlist # UnrealIrcd, Hendrik Frenzel
241
+ 607 : rpl_endofwatchlist # UnrealIrcd, Hendrik Frenzel
242
+ 610 : mapmore # UnrealIrcd, Hendrik Frenzel
243
+ 640 : rpl_dumping # UnrealIrcd, Hendrik Frenzel
244
+ 641 : rpl_dumprpl # UnrealIrcd, Hendrik Frenzel
245
+ 642 : rpl_eodump # UnrealIrcd, Hendrik Frenzel
246
+
247
+ 999 : numericerror # Bahamut IRCD
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+
4
+ require File.dirname(__FILE__) + '/em-ruby-irc/IRC.rb'
5
+ require File.dirname(__FILE__) + '/em-ruby-irc/IRC-Connection.rb'
6
+ require File.dirname(__FILE__) + '/em-ruby-irc/IRC-Event.rb'
7
+ require File.dirname(__FILE__) + '/em-ruby-irc/IRC-User.rb'
8
+ require File.dirname(__FILE__) + '/em-ruby-irc/IRC-Channel.rb'
9
+ require File.dirname(__FILE__) + '/em-ruby-irc/IRC-Utils.rb'
10
+ require File.dirname(__FILE__) + '/em-ruby-irc/default-handlers.rb'
11
+
12
+ module EMIRC
13
+ VERSION = '0.0.1'
14
+ end
15
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-ruby-irc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brian Stolz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-05-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: eventmachine
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.12.8
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.0
34
+ version:
35
+ description: EM IRC Bot Framework
36
+ email: brian@tecnobrat.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - README.rdoc
45
+ - Rakefile
46
+ - lib/em-ruby-irc/IRC-Event.rb
47
+ - lib/em-ruby-irc/eventmap.yml
48
+ - lib/em-ruby-irc/IRC-Utils.rb
49
+ - lib/em-ruby-irc/IRC-User.rb
50
+ - lib/em-ruby-irc/default-handlers.rb
51
+ - lib/em-ruby-irc/IRC-Channel.rb
52
+ - lib/em-ruby-irc/IRC-Connection.rb
53
+ - lib/em-ruby-irc/IRC.rb
54
+ - lib/em-ruby-irc.rb
55
+ has_rdoc: true
56
+ homepage: http://github.com/tecnobrat/em-ruby-irc
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --quiet
62
+ - --title
63
+ - EM IRC Bot Framework
64
+ - --main
65
+ - README.rdoc
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.8.6
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.5
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: EM IRC Bot Framework
87
+ test_files: []
88
+