33 case "participant": return Role.PARTICIPANT; |
33 case "participant": return Role.PARTICIPANT; |
34 case "visitor": return Role.VISITOR; |
34 case "visitor": return Role.VISITOR; |
35 } |
35 } |
36 return Role.NONE; |
36 return Role.NONE; |
37 } |
37 } |
|
38 static string role_to_string(Role role) { |
|
39 switch (role) { |
|
40 case Role.MODERATOR: return "moderator"; |
|
41 case Role.PARTICIPANT: return "participant"; |
|
42 case Role.VISITOR: return "visitor"; |
|
43 } |
|
44 return "none"; |
|
45 } |
|
46 |
38 static Affiliation affil_from_string(string affil) { |
47 static Affiliation affil_from_string(string affil) { |
39 switch (affil) { |
48 switch (affil) { |
40 case "owner": return Affiliation.OWNER; |
49 case "owner": return Affiliation.OWNER; |
41 case "admin": return Affiliation.ADMIN; |
50 case "admin": return Affiliation.ADMIN; |
42 case "member": return Affiliation.MEMBER; |
51 case "member": return Affiliation.MEMBER; |
43 case "outcast": return Affiliation.OUTCAST; |
52 case "outcast": return Affiliation.OUTCAST; |
44 } |
53 } |
45 return Affiliation.NONE; |
54 return Affiliation.NONE; |
|
55 } |
|
56 static string affil_to_string(Affiliation affil) { |
|
57 switch (affil) { |
|
58 case Affiliation.OWNER: return "owner"; |
|
59 case Affiliation.ADMIN: return "admin"; |
|
60 case Affiliation.MEMBER: return "member"; |
|
61 case Affiliation.OUTCAST: return "outcast"; |
|
62 } |
|
63 return "none"; |
46 } |
64 } |
47 |
65 |
48 public class Occupant : Object { |
66 public class Occupant : Object { |
49 public weak Conference conference; |
67 public weak Conference conference; |
50 public string nick; |
68 public string nick; |
51 public string real_jid; |
69 public string real_jid; |
52 public string status; |
70 public string status; |
53 public Affiliation affil; |
71 public Affiliation affil; |
54 public Role role; |
72 public Role role; |
55 public bool isme; |
73 public bool isme; |
|
74 public void public_message(string text) { |
|
75 var msg = new Lm.Message(conference.jid, Lm.MessageType.MESSAGE); |
|
76 msg.node.set_attribute("type","groupchat"); |
|
77 msg.node.add_child("body",nick+": "+text); |
|
78 conference.module.conn.cn.send(msg); |
|
79 } |
56 } |
80 } |
57 |
81 |
58 public enum State { |
82 public enum State { |
59 CONNECTED, |
83 CONNECTED, |
60 DISCOVERING, |
84 DISCOVERING, |
82 protected State _state; |
106 protected State _state; |
83 public Time time; |
107 public Time time; |
84 public State state { get { return _state; } } |
108 public State state { get { return _state; } } |
85 public Gee.HashMap<string,Occupant> occupants; |
109 public Gee.HashMap<string,Occupant> occupants; |
86 protected string presence_join_id; |
110 protected string presence_join_id; |
87 protected weak ModuleMuc module; |
111 public string pingcheck_id; |
|
112 public time_t last_check; |
|
113 public weak ModuleMuc module; |
88 |
114 |
89 protected void _change_state(State new_state, string description) { |
115 protected void _change_state(State new_state, string description) { |
90 var old_state = this._state; |
116 var old_state = this._state; |
91 if (old_state != new_state) { |
117 if (old_state != new_state) { |
92 this._state = new_state; |
118 this._state = new_state; |
199 if( role!= Role.NONE) { |
225 if( role!= Role.NONE) { |
200 occupant = new Occupant(); |
226 occupant = new Occupant(); |
201 occupant.role = role; |
227 occupant.role = role; |
202 occupant.affil = affil; |
228 occupant.affil = affil; |
203 occupant.nick = from[1]; |
229 occupant.nick = from[1]; |
|
230 occupant.conference = this; |
204 occupants[from[1]] = occupant; |
231 occupants[from[1]] = occupant; |
205 occupant.isme = statuses.contains(110); |
232 occupant.isme = statuses.contains(110); |
206 log("Muc", LogLevelFlags.LEVEL_INFO, "MUC<%s> %s has joined as %s/%s.", this.jid, from[1], affil.to_string(), role.to_string()); |
233 log("Muc", LogLevelFlags.LEVEL_INFO, "MUC<%s> %s has joined as %s/%s.", this.jid, from[1], affil.to_string(), role.to_string()); |
207 if (statuses.contains(110)) { |
234 if (statuses.contains(110)) { |
208 this.nick = from[1]; |
235 this.nick = from[1]; |
209 _change_state(State.CONNECTED, "got own presence. we are "+this.nick); |
236 _change_state(State.CONNECTED, "got own presence. we are "+this.nick); |
210 } |
237 } |
211 module.on_join(this, occupant); |
238 module.on_join(this, occupant); |
212 } else |
239 } else { |
|
240 if (statuses.contains(110)) |
|
241 _change_state(State.DISCONNECTED, "got role none while joining"); |
213 log("Muc", LogLevelFlags.LEVEL_WARNING, "Got NONE role for new participant. Maybe we are reconnecting."); |
242 log("Muc", LogLevelFlags.LEVEL_WARNING, "Got NONE role for new participant. Maybe we are reconnecting."); |
|
243 } |
214 } |
244 } |
215 |
245 |
216 stdout.printf("User list: "); |
246 stdout.printf("User list: "); |
217 foreach (var a in occupants.keys) |
247 foreach (var a in occupants.keys) |
218 stdout.printf("%s <%s,%s>, ", a, occupants[a].affil.to_string(), occupants[a].role.to_string()); |
248 stdout.printf("%s <%s,%s>, ", a, occupants[a].affil.to_string(), occupants[a].role.to_string()); |
227 } else if (from.length==2) { |
257 } else if (from.length==2) { |
228 //if (from[1]==this.nick) |
258 //if (from[1]==this.nick) |
229 } |
259 } |
230 break; |
260 break; |
231 } |
261 } |
232 } else if ((message.get_type()==Lm.MessageType.MESSAGE)&&(type=="groupchat")) { |
262 } else if (message.get_type()==Lm.MessageType.MESSAGE) |
233 var subj = node.get_attribute("subject"); |
263 switch (type) { |
234 var occupant = (from.length > 1) ? occupants[from[1]] : null; |
264 case "groupchat": |
235 if (subj != null) { |
265 var subj = node.get_attribute("subject"); |
236 if (subj != this.subject) { |
266 var occupant = (from.length > 1) ? occupants[from[1]] : null; |
237 this.subject = subj; |
267 if (subj != null) { |
238 module.on_subject(this, occupant); |
268 if (subj != this.subject) { |
239 } |
269 this.subject = subj; |
240 } else { |
270 module.on_subject(this, occupant); |
241 var body = node.find_child("body"); |
271 } |
242 module.on_message(this, occupant, node, (body!=null) ? body.get_value() : null); |
272 } else { |
|
273 var body = node.find_child("body"); |
|
274 module.on_message(this, occupant, node, (body!=null) ? body.get_value() : null); |
|
275 } |
|
276 break; |
|
277 case "error": |
|
278 if (node.get_attribute("id")==pingcheck_id) { |
|
279 _change_state(State.DISCONNECTED, node.get_child("error").to_string()); |
|
280 } |
|
281 break; |
243 } |
282 } |
244 } |
|
245 return Lm.HandlerResult.ALLOW_MORE_HANDLERS; |
283 return Lm.HandlerResult.ALLOW_MORE_HANDLERS; |
246 } |
284 } |
247 public void part(string desc) { |
285 public void part(string desc) { |
248 if (_state != State.DISCONNECTED) { |
286 if (_state != State.DISCONNECTED) { |
249 var prs = new Lm.Message(jid+"/"+desired_nick, Lm.MessageType.PRESENCE); |
287 var prs = new Lm.Message(jid+"/"+desired_nick, Lm.MessageType.PRESENCE); |
303 if (conn.state == Connection.State.CONNECTED) |
341 if (conn.state == Connection.State.CONNECTED) |
304 foreach (var room in rooms.values) { |
342 foreach (var room in rooms.values) { |
305 if (room.enabled) { |
343 if (room.enabled) { |
306 if (room.state == State.DISCONNECTED) |
344 if (room.state == State.DISCONNECTED) |
307 room.join("Reconnect"); |
345 room.join("Reconnect"); |
|
346 else { |
|
347 time_t curtime = time_t(); |
|
348 if ((curtime - room.last_check) > 60) { // crappy check for netsplits |
|
349 room.last_check = curtime; |
|
350 var msg = new Lm.Message(room.jid, Lm.MessageType.MESSAGE); |
|
351 room.pingcheck_id = room.jid+"_"+Random.next_int().to_string(); |
|
352 msg.node.set_attribute("id",room.pingcheck_id); |
|
353 log("Muc", LogLevelFlags.LEVEL_DEBUG, "Ping check to %s", room.jid); |
|
354 room.module.conn.cn.send(msg); |
|
355 |
|
356 } |
|
357 } |
308 } else { |
358 } else { |
309 if (room.state == State.CONNECTED) |
359 if (room.state == State.CONNECTED) |
310 room.part("Disabled"); |
360 room.part("Disabled"); |
311 } |
361 } |
312 } |
362 } |