-
Notifications
You must be signed in to change notification settings - Fork 2
/
groupchat.rb
193 lines (152 loc) · 4.88 KB
/
groupchat.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#--
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
#
# This file is part of torchat for ruby.
#
# torchat for ruby is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# torchat for ruby is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
#++
class Torchat; module Protocol
# The groupchat extension is made to support, you can guess it, groupchats.
#
# The following text describes the lifecycle of a group chat.
#
# The person that starts the groupchat starts it by inviting the first person
# to it, the invite packet has a cookie inside that will also be the id of the
# groupchat throughout all its lifecycle.
#
# After the invite packet a participants packet is sent to the invited person,
# this packet has inside the list of ids of the current groupchat.
#
# After receiving the participants packet the invited starts connections to all the
# participants and sends them a packet asking them if they're really participating
# in the groupchat. The contacts that aren't in his buddy list are added as temporary
# buddies. If any of the participants are in his blocked list, a leave packet will be
# sent, refusing to join the groupchat, otherwise a join packet will be sent.
#
# After the participants packet an invited packet is sent to the already present participants,
# in this way they'll know who invited that person and that that person is going to join the
# groupchat.
#
# The messaging in the groupchat is simply sent to every other participant from the sender
# of the message.
#
# To exit the groupchat a leave packet is sent to every participant present in the groupchat.
#
# On disconnection of any of the participants it will obviously mean leaving the groupchat.
define_extension :groupchat do
# This packet is sent to the person you want to invite to the groupchat,
# the packet only contains the id of the groupchat.
define_packet :invite do
define_unpacker_for 1
def initialize (id = nil)
@internal = id || Torchat.new_cookie
end
def id
@internal
end
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id})>"
end
end
# This packet is used to tell the invited who are the participants.
define_packet :participants do
define_unpacker_for 1 .. -1
attr_accessor :id
def initialize (id, *participants)
@id = id
@internal = participants.flatten.uniq
end
def method_missing (id, *args, &block)
return @internal.__send__ id, *args, &block if @internal.respond_to? id
super
end
def pack
super("#{id} #{join ' '}")
end
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id}): #{@internal.join ', '}>"
end
end
# This packet is used to ask if the person is really participating in the groupchat
define_packet :participating? do
define_unpacker_for 1
def id
@internal
end
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id})>"
end
end
# This packet is sent to accept the invitation to the groupchat
define_packet :join do
define_unpacker_for 1
def id
@internal
end
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id})>"
end
end
# This packet is sent to every participant in a groupchat to tell them you're leaving
define_packet :leave do
define_unpacker_for 1 .. 2
attr_accessor :id, :reason
def initialize (id, reason = nil)
@id = id
@reason = reason
end
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id})#{": #{reason.inspect}" if reason}>"
end
end
# This packet is used to tell the already present participants about who you invited.
define_packet :invited do
define_unpacker_for 2
attr_accessor :id
def initialize (id, buddy)
@id = id
@internal = buddy.is_a?(Buddy) ? buddy.id : buddy
end
def pack
super("#{id} #{to_s}")
end
def to_s
@internal
end
alias to_str to_s
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id}): #{to_s.inspect}>"
end
end
# This packet is sent to all participants and is just a message.
define_packet :message do
define_unpacker_for 2
attr_accessor :id
def initialize (id, message)
@id = id
@internal = message
end
def pack
super("#{id} #{to_s}")
end
def to_s
@internal
end
alias to_str to_s
def inspect
"#<Torchat::Packet[#{type}#{", #{extension}" if extension}](#{id}): #{to_s.inspect}>"
end
end
end
end; end