Level of stubbornness skyrocketed
authorStiletto <blasux@blasux.ru>
Tue, 23 Oct 2012 18:33:49 +0400
changeset 2 4e050075fab9
parent 1 76caf6a3f413
child 3 dd7a02c6d476
Level of stubbornness skyrocketed
iswydt.vala
muc.vala
--- a/iswydt.vala	Fri Oct 19 00:38:54 2012 +0400
+++ b/iswydt.vala	Tue Oct 23 18:33:49 2012 +0400
@@ -24,6 +24,7 @@
     public Module[] modules;
 
     public signal void state_changed(State old_state, State new_state, string description);
+    public signal void check_time();
     protected void _change_state(State new_state, string description) {
         var old_state = this._state;
         if (old_state != new_state) {
@@ -90,6 +91,10 @@
                 this.rooms[room.jid] = room;*/
             }
         });
+        check_time.connect( () => {
+            if (_state == State.DISCONNECTED)
+                open();
+        });
     }
     public void open() {
 
@@ -137,8 +142,15 @@
     var cfg = new Config.from_file(args[1]);
     var loop = new MainLoop();
     var account = new Connection(cfg);
-    account.open();
+    //account.open();
     stdout.printf("Fuck yeah\n");
+    var checktimer = new TimeoutSource(2000);
+    checktimer.set_callback(() => {
+        account.check_time();
+        //stderr.printf("TimeoutSource OLOLO\n");
+        return true;
+    });
+    checktimer.attach(loop.get_context());
     loop.run();
     return 0;
 }
--- a/muc.vala	Fri Oct 19 00:38:54 2012 +0400
+++ b/muc.vala	Tue Oct 23 18:33:49 2012 +0400
@@ -10,6 +10,8 @@
 }
 
 class ModuleMuc : Module {
+    public static const string NS_MUC_USER = "http://jabber.org/protocol/muc#user";
+
     public enum Affiliation {
         NONE,
         OUTCAST,
@@ -66,12 +68,14 @@
     public signal void on_role(Conference conf, Occupant occupant, Role prev);
     public signal void on_affil(Conference conf, Occupant occupant, Affiliation prev);
     public signal void on_nick(Conference conf, Occupant occupant, string prev);
+    public signal void on_message(Conference conf, Occupant occupant, Lm.MessageNode message, string body);
     public signal void on_subject(Conference conf);
 
     public class Conference : Object {
         public string jid;
         public string nick;
         public string desired_nick;
+        public bool enabled;
         public string subject;
 
         protected State _state;
@@ -87,6 +91,8 @@
                 this._state = new_state;
                 stderr.printf("MUC State changed %s -> %s : %s\n",old_state.to_string(), new_state.to_string(), description);
                 module.state_changed(this, old_state, new_state, description);
+                if (new_state == State.DISCONNECTED)
+                    occupants.clear();
             } else
                 stderr.printf("MUC State not changed %s : %s\n",old_state.to_string(), description);
         }
@@ -94,7 +100,7 @@
         public Conference(ModuleMuc module, string jid) {
             this.module = module;
             var section = "muc "+jid;
-            this.desired_nick = module.cfg[section,"nick"];
+            this.desired_nick = module.cfg.get_default(section,"nick",module.cfg.get_default("muc","nick",Random.next_int().to_string()));
             this.nick = this.desired_nick;
             this.jid = jid;
             this._state = State.DISCONNECTED;
@@ -108,7 +114,7 @@
                 prs.node.add_child("x",null).set_attribute("xmlns","http://jabber.org/protocol/muc");
                 module.conn.cn.send(prs);
                 nick = desired_nick;
-                _change_state(State.CONNECTING, "requested to join");
+                _change_state(State.CONNECTING, "requested to join: "+desc);
             }
         }
         
@@ -123,41 +129,51 @@
                     case "unavailable":
                         if (from.length==2) {
                             var statuses = new Gee.HashSet<int>();
+                            var occupant = occupants[from[1]];
+                            var affil = Affiliation.NONE;
+                            var role = Role.NONE;
+                            string prs_nick = null;
 
-                            var x = node.get_child("x");
-                            var child = x!=null ? x.children : null;
-                            while (child != null) {
-                                stdout.printf("Child %s %s\n", child.name, child.get_attribute("code"));
-                                if (child.name == "status") {
-                                    var code = child.get_attribute("code");
-                                    if (code!=null)
-                                        statuses.add(code.to_int());
+                            var chn = node.children;
+                            while (chn != null) {
+                                switch (chn.name) {
+                                    
+                                    case "x":
+                                        switch (chn.get_attribute("xmlns")) {
+                                            case NS_MUC_USER:
+                                                var child = chn.children;
+                                                while (child != null) {
+                                                    stdout.printf("Child %s %s\n", child.name, child.get_attribute("code"));
+                                                    if (child.name == "status") {
+                                                        var code = child.get_attribute("code");
+                                                        if (code!=null)
+                                                            statuses.add(code.to_int());
+                                                    }
+                                                    child = child.next;
+                                                }
+                                                var item = chn.get_child("item");
+                                                if (item == null)
+                                                    log("Muc", LogLevelFlags.LEVEL_ERROR, "Your MUC server is shit. No role and affiliation info in presences: %s", node.to_string());
+                                                affil = affil_from_string(item.get_attribute("affiliation"));
+                                                role = role_from_string(item.get_attribute("role")); 
+                                                prs_nick = item.get_attribute("nick");
+                                                break;
+                                        }
+                                        break;
                                 }
-                                child = child.next;
+                                chn = chn.next;
                             }
 
                             if (statuses.contains(110) && (_state == State.CONNECTED))
                                 log("Muc", LogLevelFlags.LEVEL_INFO, "Joined a room which I was already in: %s", from[0]);
 
-                            var occupant = occupants[from[1]];
-                            var item = x != null ? x.get_child("item") : null;
-                            var affil = Affiliation.NONE;
-                            var role = Role.NONE;
-                            string nick = null;
-                            if (item != null) {
-                                affil = affil_from_string(item.get_attribute("affiliation"));
-                                role = role_from_string(item.get_attribute("role")); 
-                                nick = item.get_attribute("nick");
-                            } else
-                                log("Muc", LogLevelFlags.LEVEL_ERROR, "Your MUC server is shit. No role and affiliation info in presences: %s", node.to_string());
                             if (occupant != null) {
                                 if (role == Role.NONE) {
                                     occupants.unset(from[1]);
                                     log("Muc", LogLevelFlags.LEVEL_INFO, "MUC<%s> %s has parted.", this.jid, from[1]);
                                     module.on_part(this, occupant);
-                                    if (from[1]==this.nick) {
+                                    if (occupant.isme) {
                                         _change_state(State.DISCONNECTED, "we became unavailable");
-                                        occupants.clear();
                                     }
                                 } else {
                                     if (affil != occupant.affil) {
@@ -170,10 +186,10 @@
                                         occupant.role = role;
                                         module.on_role(this, occupant, prev);
                                     }
-                                    if (statuses.contains(303) && (nick!=null)) {
-                                        occupants[nick] = occupant;
+                                    if (statuses.contains(303) && (prs_nick!=null)) {
+                                        occupants[prs_nick] = occupant;
                                         occupants.unset(from[1]);
-                                        occupant.nick = nick;
+                                        occupant.nick = prs_nick;
                                         module.on_nick(this, occupant, from[1]);
                                     }
                                 }
@@ -186,8 +202,10 @@
                                 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());
-                                if (statuses.contains(110))
+                                if (statuses.contains(110)) {
+                                    this.nick = from[1];
                                     _change_state(State.CONNECTED, "got own presence. we are "+this.nick);
+                                }
                                 module.on_join(this, occupant);
                             }
                             
@@ -214,11 +232,27 @@
                         this.subject = subj;
                         module.on_subject(this);
                     }
+                } else {
+                    var occupant = (from.length > 1) ? occupants[from[1]] : null;
+                    var body = node.find_child("body");
+                    module.on_message(this, occupant, node, (body!=null) ? body.get_value() : null);
                 }
             }
             return Lm.HandlerResult.ALLOW_MORE_HANDLERS;
         }
         public void part(string desc) {
+            if (_state != State.DISCONNECTED) {
+                var prs = new Lm.Message(jid+"/"+desired_nick, Lm.MessageType.PRESENCE);
+                presence_join_id = jid+"_"+Random.next_int().to_string();
+                prs.node.set_attribute("type","unavailable");
+                prs.node.add_child("x",null).set_attribute("xmlns","http://jabber.org/protocol/muc");
+                module.conn.cn.send(prs);
+                nick = desired_nick;
+            }
+        }
+
+        public void connection_lost() {
+            _change_state(State.DISCONNECTED, "connection lost");
         }
     }
 
@@ -241,15 +275,37 @@
             }
             return Lm.HandlerResult.ALLOW_MORE_HANDLERS;
         }, null);
+        var names = cfg.get_default("muc","mucs","").split(" ");
+        foreach (var name in names) {
+            var room = new Conference(this, name); //, "Ζαλυπα");
+            //room.join("Oh hai");
+            room.enabled = true;
+            this.rooms[room.jid] = room;
+        }
         conn.cn.register_message_handler(muc_handler, Lm.MessageType.MESSAGE, Lm.HandlerPriority.NORMAL);
         conn.cn.register_message_handler(muc_handler, Lm.MessageType.PRESENCE, Lm.HandlerPriority.NORMAL);
         conn.cn.register_message_handler(muc_handler, Lm.MessageType.IQ, Lm.HandlerPriority.NORMAL);
         conn.state_changed.connect( (olds, news, desc) => {
-            if (news == Connection.State.CONNECTED) {
-                var room = new Conference(this, "говнохост@conference.blasux.ru"); //, "Ζαλυπα");
-                room.join("Oh hai");
-                this.rooms[room.jid] = room;
+            switch (news) {
+                case Connection.State.CONNECTED:
+                    break;
+                case Connection.State.DISCONNECTED:
+                    foreach(var room in rooms.values)
+                        room.connection_lost();
+                    break;
             }
         });
+        conn.check_time.connect( () => {
+            if (conn.state == Connection.State.CONNECTED)
+                foreach (var room in rooms.values) {
+                    if (room.enabled) {
+                        if (room.state == State.DISCONNECTED)
+                            room.join("Reconnect");
+                    } else {
+                        if (room.state == State.CONNECTED)
+                            room.part("Disabled");
+                    }
+                }
+        });
     }
 }