File: client.rb

package info (click to toggle)
ruby-net-irc 0.0.9-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 408 kB
  • sloc: ruby: 7,268; makefile: 3
file content (117 lines) | stat: -rw-r--r-- 2,471 bytes parent folder | download | duplicates (4)
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
class Net::IRC::Client
	include Net::IRC
	include Constants

	attr_reader :host, :port, :opts
	attr_reader :prefix, :channels

	def initialize(host, port, opts={})
		@host          = host
		@port          = port
		@opts          = OpenStruct.new(opts)
		@log           = @opts.logger || Logger.new($stdout)
		@server_config = Message::ServerConfig.new
		@channels = {
#			"#channel" => {
#				:modes => [],
#				:users => [],
#			}
		}
		@channels.extend(MonitorMixin)
	end

	# Connect to server and start loop.
	def start
		# reset config
		@server_config = Message::ServerConfig.new
		@socket = TCPSocket.open(@host, @port)
		on_connected
		post PASS, @opts.pass if @opts.pass
		post NICK, @opts.nick
		post USER, @opts.user, "0", "*", @opts.real
		while l = @socket.gets
			begin
				@log.debug "RECEIVE: #{l.chomp}"
				m = Message.parse(l)
				next if on_message(m) === true
				name = "on_#{(COMMANDS[m.command.upcase] || m.command).downcase}"
				send(name, m) if respond_to?(name)
			rescue Exception => e
				warn e
				warn e.backtrace.join("\r\t")
				raise
			rescue Message::InvalidMessage
				@log.error "MessageParse: " + l.inspect
			end
		end
	rescue IOError
	ensure
		finish
	end

	# Close connection to server.
	def finish
		begin
			@socket.close
		rescue
		end
		on_disconnected
	end

	# Catch all messages.
	# If this method return true, aother callback will not be called.
	def on_message(m)
	end

	# Default RPL_WELCOME callback.
	# This sets @prefix from the message.
	def on_rpl_welcome(m)
		@prefix = Prefix.new(m[1][/\S+\z/])
	end

	# Default RPL_ISUPPORT callback.
	# This detects server's configurations.
	def on_rpl_isupport(m)
		@server_config.set(m)
	end

	# Default PING callback. Response PONG.
	def on_ping(m)
		post PONG, @prefix ? @prefix.nick : ""
	end

	# Do nothing.
	# This is for avoiding error on calling super.
	# So you can always call super at subclass.
	def method_missing(name, *args)
	end

	# Call when socket connected.
	def on_connected
	end

	# Call when socket closed.
	def on_disconnected
	end

	private

	# Post message to server.
	#
	#     include Net::IRC::Constants
	#     post PRIVMSG, "#channel", "foobar"
	def post(command, *params)
		m = Message.new(nil, command, params.map {|s|
			if s
				s.force_encoding("ASCII-8BIT") if s.respond_to? :force_encoding
				#s.gsub(/\r\n|[\r\n]/, " ")
				s.tr("\r\n", " ")
			else
				""
			end
		})

		@log.debug "SEND: #{m.to_s.chomp}"
		@socket << m
	end
end # Client