# HG changeset patch # User Stiletto # Date 1352145232 -14400 # Node ID 0f0cf428409fc08f348a6073da76a59bf7f99bb1 # Parent 6b0d56b01ba0effa84490c76b47623e310114151 Crappy reconnector diff -r 6b0d56b01ba0 -r 0f0cf428409f muc.vala --- 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 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");