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 +8 -0
- data/Rakefile +51 -0
- data/lib/em-ruby-irc/IRC-Channel.rb +12 -0
- data/lib/em-ruby-irc/IRC-Connection.rb +127 -0
- data/lib/em-ruby-irc/IRC-Event.rb +65 -0
- data/lib/em-ruby-irc/IRC-User.rb +19 -0
- data/lib/em-ruby-irc/IRC-Utils.rb +107 -0
- data/lib/em-ruby-irc/IRC.rb +58 -0
- data/lib/em-ruby-irc/default-handlers.rb +72 -0
- data/lib/em-ruby-irc/eventmap.yml +247 -0
- data/lib/em-ruby-irc.rb +15 -0
- metadata +88 -0
data/README.rdoc
ADDED
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,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
|
data/lib/em-ruby-irc.rb
ADDED
@@ -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
|
+
|