Procházet zdrojové kódy

[bugfix][IRC-con] use pending message ids to recognize sent messages

B Thibault před 8 roky
rodič
revize
57217bc350
2 změnil soubory, kde provedl 79 přidání a 21 odebrání
  1. 37 16
      srv/src/ircServer/ircConnection.js
  2. 42 5
      srv/src/slack.js

+ 37 - 16
srv/src/ircServer/ircConnection.js

@@ -9,7 +9,7 @@ const parseIrcCmd = require('./ircCmd.js').parse
 
     ,CONFIG = require("../../config.js");
 
-const DEBUG = false;
+const DEBUG = true;
 
 const SERVER_CONFIG = {
     port: CONFIG.port,
@@ -40,7 +40,7 @@ IrcConnection = module.exports.IrcConnection = function(sock) {
         data.toString("utf-8").split(/\r?\n/g).forEach((str) => { _this.parse(str); });
     });
     this.sock.once("close", () => {
-        console.log("[IRC] closed connection" +(this.account ? (" for user #" +this.account.id) : ""));
+        console.info("[IRC] closed connection" +(this.account ? (" for user #" +this.account.id) : ""));
         if (_this.pingInterval)
             clearInterval(_this.pingInterval);
         _this.polling = false;
@@ -90,7 +90,7 @@ IrcConnection.prototype.checkConnectionDone = function(account, nickname, userna
         this.realname = realname;
 
     if (!authed && this.isAuthed()) {
-        console.log("Authed new IRC client for user #" +this.account.id);
+        console.info("[IRC] Authed new user #" +this.account.id);
         this.write(":" +SERVER_CONFIG.hostname +" 001 " +this.nickname +" :Welcome");
         this.write(":" +SERVER_CONFIG.hostname +" 002 " +this.nickname +" :Your host is " +SERVER_CONFIG.hostname +"[" +this.sock.localAddress +"/" +SERVER_CONFIG.port +"], running version mimouchat");
         this.write(":" +SERVER_CONFIG.hostname +" 003 " +this.nickname +" :This server was created " +SERVER_CONFIG.created);
@@ -113,7 +113,6 @@ IrcConnection.prototype.checkConnectionDone = function(account, nickname, userna
                     console.error("Unknown service type for ", services[serviceId], " with account #" +req.account.id);
             }
         }
-
         this.pingInterval = setInterval(this.sendPing.bind(this), 60000);
         this.polling = true;
         this.poll();
@@ -212,11 +211,13 @@ IrcConnection.prototype.sendLiveUpdate = function(live) {
         let chanCompatId = this.chanCompat(chanId, this);
         live[chanId].forEach((msg) => {
             if (msg.user && this.chatContext.isMe(msg.user)) {
-                for (var i=0, nbPending =this.pendingMsgs.length; i < nbPending; i++)
-                    if (this.pendingMsgs[i].isMe === !!msg.isMeMessage && this.pendingMsgs[i].chan === chanId && this.pendingMsgs[i].msg === msg.text) {
-                        this.pendingMsgs.splice(i, 1);
+                if (msg.pendingId) {
+                    var pos = this.pendingMsgs.indexOf(msg.pendingId);
+                    if (pos >= 0) {
+                        this.pendingMsgs.splice(pos, 1);
                         return;
                     }
+                }
             }
             var pretext = ":" +(msg.user ? this.userCompat(msg.user) : msg.username) +" PRIVMSG " +chanCompatId +" :";
             if (msg.isMeMessage)
@@ -229,7 +230,8 @@ IrcConnection.prototype.sendLiveUpdate = function(live) {
 IrcConnection.prototype.poll = function() {
     var now = Date.now();
     var _this = this;
-    this.chatContext.poll(this.version || 0, now, (data) => {
+    // FIXME add new services / contexts
+    this.chatContext.poll(this.version || 0, now, null, false).then((data) => {
         if (_this.polling) {
             if (data.static)
                 _this.sendStaticUpdate(data.static);
@@ -239,7 +241,9 @@ IrcConnection.prototype.poll = function() {
                 _this.version = data.v;
             _this.poll();
         }
-    }, null, false);
+    }).catch(() => {
+        _this.poll();
+    });
 };
 
 IrcConnection.prototype.parse = function(str) {
@@ -282,7 +286,7 @@ IrcConnection.prototype.parse = function(str) {
                     }
                 break;
                 case "PRIVMSG":
-                    let msg = cmd.args[1],
+                    var msg = cmd.args[1],
                         target = cmd.args[0].split('@', 2),
                         sent = false;
                     if (target[0][0] === '#')
@@ -298,13 +302,11 @@ IrcConnection.prototype.parse = function(str) {
                                             msg = msg.substr(8, msg.length -9);
                                         else
                                             msg = msg.substr(8);
-                                        // FIXME id
-                                        msg = ctx.sendMeMsg(chan, [ msg ]);
-                                        this.pendingMsgs.push({isMe: true, chan: chan.id, msg: msg});
+                                        let msgId = ctx.sendMeMsg(chan, [ msg ]);
+                                        this.pendingMsgs.push(msgId);
                                     } else {
-                                        // FIXME id
-                                        msg = ctx.sendMsg(chan, [ msg ]);
-                                        this.pendingMsgs.push({isMe: false, chan: chan.id, msg: msg});
+                                        let msgId = ctx.sendMsg(chan, [ msg ]);
+                                        this.pendingMsgs.push(msgId);
                                     }
                                     sent = true;
                                     break ctxLoop;
@@ -315,6 +317,25 @@ IrcConnection.prototype.parse = function(str) {
                     if (!sent)
                         this.write(":" +SERVER_CONFIG.hostname +" NOTICE * :No such user or team " +cmd.args[0]);
                 break;
+
+                case "WHOIS":
+                    var target = cmd.args[0].split('@', 2);
+                    ctxLoop: for (let i =0, nbCtx = this.chatContext.contexts.length; i < nbCtx; i++) {
+                        let ctx = this.chatContext.contexts[i];
+                        if (ctx.getChatContext().team && ctx.getChatContext().team.name === target[1]) {
+                            for (let userId in ctx.getChatContext().users) {
+                                let user = ctx.getChatContext().users[userId];
+                                if (user.getName() === target[0]) {
+                                    this.write(":" +SERVER_CONFIG.hostname +" 311 " +cmd.args[0] +" " + user.name.replace(/\s/g, '_') +' ' +SERVER_CONFIG.hostname +' :' +user.realName);
+                                    this.write(":" +SERVER_CONFIG.hostname +" 312 " +cmd.args[0] +" " +SERVER_CONFIG.hostname +ctx.getChatContext().team.name.replace(/\s/g, '_') +' :' +user.realName);
+                                    this.write(":" +SERVER_CONFIG.hostname +" 318 " +cmd.args[0] +" " +cmd.args[0] +' :End of /WHOIS list.');
+                                    break ctxLoop;
+                                }
+                            }
+                        }
+                    }
+                break;
+
                 default:
                     if (DEBUG)
                         console.log(cmd);

+ 42 - 5
srv/src/slack.js

@@ -9,6 +9,8 @@ const
     ,config = require("../config.js")
     ,httpsRequest = require('./httpsRequest.js').httpsRequest
 
+    ,MeMessage = require('./message.js').MeMessage
+
     ,MultiChatManager = require('./multichatManager.js').MultiChatManager
 ;
 
@@ -77,6 +79,7 @@ function Slack(slackToken, manager) {
     this.history = {};
     this.pendingRtm = {};
     this.pendingMessages = [];
+    this.msgIds = {};
     this.pendingPing = false;
     this.connected = false;
     this.closing = false;
@@ -325,8 +328,12 @@ Slack.prototype.onMessage = function(msg, t) {
             var lastMsg = histo.push(msg, t, msgRef);
             if (lastMsg) {
                 this.data.liveV = t;
-                if (msgRef.msg && msgRef.msg.userId)
+                if (msgRef.msg && msgRef.msg.userId) {
                     this.data.stopTyping(channelId, msgRef.msg.userId, t);
+                    if (!msgRef.msg.pendingId) {
+                        this.removeMsgFromPending(channel, msgRef.msg);
+                    }
+                }
             }
             histo.resort();
             if (channel)
@@ -340,6 +347,22 @@ Slack.prototype.onMessage = function(msg, t) {
     }
 };
 
+Slack.prototype.removeExpiredMsgs = function(msg) {
+    // TODO retry
+};
+
+Slack.prototype.removeMsgFromPending = function(channel, msg) {
+    let isMe = msg instanceof MeMessage;
+    for (var i in this.msgIds) {
+        let j = this.msgIds[i];
+        if (j.isMe === isMe && j.text === msg.text && j.channel === channel.id) {
+            msg.pendingId = i;
+            delete this.msgIds[i];
+            return;
+        }
+    }
+};
+
 Slack.prototype.getRawMpims = function(cb) {
     httpsRequest(SLACK_ENDPOINT +GETAPI.listMpims
         +"?token=" +this.token, (status, content) => {
@@ -661,8 +684,15 @@ Slack.prototype.sendMeMsg = function(channel, text) {
         +"&channel=" +channel.remoteId
         +"&text=" +encodeURIComponent(text)
         +"&as_user=true");
-    let id = channel.id +'_' +text +'_' +Date.now();
-    // FIXME store if
+    let now = Date.now(),
+        id = channel.id +'_' +text +'_' +now;
+    this.msgIds[id] = {
+        channel: channel.id,
+        isMe: true,
+        text: text,
+        retry: 0,
+        t: now
+    };
     return id;
 };
 
@@ -767,8 +797,15 @@ Slack.prototype.sendMsg = function(channel, text, attachments) {
             +"&link_names=true"
             + (attachments ? ("&attachments=" +encodeURIComponent(JSON.stringify(attachments))) : "")
             +"&as_user=true");
-        // FIXME store if
-        let msgId = channel.id +'_' +decodedText +'_' +Date.now();
+        let now = Date.now(),
+            msgId = channel.id +'_' +decodedText +'_' +now;
+        this.msgIds[id] = {
+            channel: channel.id,
+            isMe: false,
+            text: decodedText,
+            retry: 0,
+            t: now
+        };
         return msgId;
     } else {
         var fullDecodedText = idify(this.data, text.join("\n")),