-
Notifications
You must be signed in to change notification settings - Fork 0
/
notification_server.rb
117 lines (100 loc) · 2.8 KB
/
notification_server.rb
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 Msn::NotificationServer < EventMachine::Connection
include Msn::Protocol
attr_reader :messenger
attr_reader :guid
def initialize(messenger)
@messenger = messenger
@guid = Guid.new.to_s
@switchboards = {}
on_event 'ADL' do |header, data|
data = Nokogiri::XML(data)
domain = data.xpath('//ml/d').first['n']
c = data.xpath('//ml/d/c').first
username = c['n']
display_name = c['f']
messenger.contact_request "#{username}@#{domain}", display_name
end
end
def username_guid
@username_guid ||= "#{messenger.username};{#{guid}}"
end
def send_message(email, text)
switchboard = @switchboards[email]
if switchboard
switchboard.send_message text
else
Fiber.new do
response = xfr "SB"
switchboard = create_switchboard email, response[3]
switchboard.on_event 'JOI' do
switchboard.clear_event 'JOI'
switchboard.send_message text
end
switchboard.usr username_guid, response[5]
switchboard.cal email
end.resume
end
end
def username
messenger.username
end
def password
messenger.password
end
def post_init
super
login
end
def login
Fiber.new do
ver "MSNP18", "CVR0"
cvr "0x0409", "winnt", "5.1", "i386", "MSNMSGR", "8.5.1302", "BC01", username
response = usr "SSO", "I", username
if response[0] == "XFR" && response[2] == "NS"
host, port = response[3].split ':'
@reconnect_host, @reconnect_port = response[3].split ':'
close_connection
else
login_to_nexus(response[4], response[5])
end
end.resume
end
def login_to_nexus(policy, nonce)
nexus = Msn::Nexus.new policy, nonce
token, return_value = nexus.login messenger.username, messenger.password
first_msg = true
on_event('MSG') do
if first_msg
first_msg = false
messenger.ready
end
end
on_event('RNG') do |header|
switchboard = create_switchboard header[5], header[2]
switchboard.ans username_guid, header[4], header[1]
end
response = usr "SSO", "S", token, return_value, guid
if response[2] != "OK"
raise "Login failed (3)"
end
end
def create_switchboard(email, host_and_port)
host, port = host_and_port.split(':')
switchboard = EM.connect host, port, Msn::Switchboard, messenger
switchboard.on_event 'BYE' do |header|
destroy_switchboard email if header[1] =~ /#{email}/
end
@switchboards[email] = switchboard
end
def destroy_switchboard(email)
switchboard = @switchboards.delete email
switchboard.close_connection
end
def unbind
if @reconnect_host
reconnect @reconnect_host, @reconnect_port.to_i
@reconnect_host = @reconnect_port = nil
login
end
end
end