--- a/muc.vala Wed Oct 24 15:07:07 2012 +0400
+++ b/muc.vala Mon Nov 05 23:53:52 2012 +0400
@@ -35,6 +35,15 @@
}
return Role.NONE;
}
+ static string role_to_string(Role role) {
+ switch (role) {
+ case Role.MODERATOR: return "moderator";
+ case Role.PARTICIPANT: return "participant";
+ case Role.VISITOR: return "visitor";
+ }
+ return "none";
+ }
+
static Affiliation affil_from_string(string affil) {
switch (affil) {
case "owner": return Affiliation.OWNER;
@@ -44,6 +53,15 @@
}
return Affiliation.NONE;
}
+ static string affil_to_string(Affiliation affil) {
+ switch (affil) {
+ case Affiliation.OWNER: return "owner";
+ case Affiliation.ADMIN: return "admin";
+ case Affiliation.MEMBER: return "member";
+ case Affiliation.OUTCAST: return "outcast";
+ }
+ return "none";
+ }
public class Occupant : Object {
public weak Conference conference;
@@ -53,6 +71,12 @@
public Affiliation affil;
public Role role;
public bool isme;
+ public void public_message(string text) {
+ var msg = new Lm.Message(conference.jid, Lm.MessageType.MESSAGE);
+ msg.node.set_attribute("type","groupchat");
+ msg.node.add_child("body",nick+": "+text);
+ conference.module.conn.cn.send(msg);
+ }
}
public enum State {
@@ -84,7 +108,9 @@
public State state { get { return _state; } }
public Gee.HashMap<string,Occupant> occupants;
protected string presence_join_id;
- protected weak ModuleMuc module;
+ public string pingcheck_id;
+ public time_t last_check;
+ public weak ModuleMuc module;
protected void _change_state(State new_state, string description) {
var old_state = this._state;
@@ -201,6 +227,7 @@
occupant.role = role;
occupant.affil = affil;
occupant.nick = from[1];
+ occupant.conference = this;
occupants[from[1]] = occupant;
occupant.isme = statuses.contains(110);
log("Muc", LogLevelFlags.LEVEL_INFO, "MUC<%s> %s has joined as %s/%s.", this.jid, from[1], affil.to_string(), role.to_string());
@@ -209,8 +236,11 @@
_change_state(State.CONNECTED, "got own presence. we are "+this.nick);
}
module.on_join(this, occupant);
- } else
+ } else {
+ if (statuses.contains(110))
+ _change_state(State.DISCONNECTED, "got role none while joining");
log("Muc", LogLevelFlags.LEVEL_WARNING, "Got NONE role for new participant. Maybe we are reconnecting.");
+ }
}
stdout.printf("User list: ");
@@ -229,19 +259,27 @@
}
break;
}
- } else if ((message.get_type()==Lm.MessageType.MESSAGE)&&(type=="groupchat")) {
- var subj = node.get_attribute("subject");
- var occupant = (from.length > 1) ? occupants[from[1]] : null;
- if (subj != null) {
- if (subj != this.subject) {
- this.subject = subj;
- module.on_subject(this, occupant);
- }
- } else {
- var body = node.find_child("body");
- module.on_message(this, occupant, node, (body!=null) ? body.get_value() : null);
+ } else if (message.get_type()==Lm.MessageType.MESSAGE)
+ switch (type) {
+ case "groupchat":
+ var subj = node.get_attribute("subject");
+ var occupant = (from.length > 1) ? occupants[from[1]] : null;
+ if (subj != null) {
+ if (subj != this.subject) {
+ this.subject = subj;
+ module.on_subject(this, occupant);
+ }
+ } else {
+ var body = node.find_child("body");
+ module.on_message(this, occupant, node, (body!=null) ? body.get_value() : null);
+ }
+ break;
+ case "error":
+ if (node.get_attribute("id")==pingcheck_id) {
+ _change_state(State.DISCONNECTED, node.get_child("error").to_string());
+ }
+ break;
}
- }
return Lm.HandlerResult.ALLOW_MORE_HANDLERS;
}
public void part(string desc) {
@@ -305,6 +343,18 @@
if (room.enabled) {
if (room.state == State.DISCONNECTED)
room.join("Reconnect");
+ else {
+ time_t curtime = time_t();
+ if ((curtime - room.last_check) > 60) { // crappy check for netsplits
+ room.last_check = curtime;
+ var msg = new Lm.Message(room.jid, Lm.MessageType.MESSAGE);
+ room.pingcheck_id = room.jid+"_"+Random.next_int().to_string();
+ msg.node.set_attribute("id",room.pingcheck_id);
+ log("Muc", LogLevelFlags.LEVEL_DEBUG, "Ping check to %s", room.jid);
+ room.module.conn.cn.send(msg);
+
+ }
+ }
} else {
if (room.state == State.CONNECTED)
room.part("Disabled");