JavaScript 循环不退出

JavaScript Loop doesn't exit

能想到的我都试过了

我正在为 IMVU 构建一种聊天机器人,在 IMVU 移动网站上使用注入 JavaScript。我有一个循环来抓取收到的消息,并搜索某些关键术语,例如以斜杠 (/) 开头的消息,表示对机器人的命令。

当使用某些命令时,我遇到了一个问题,即机器人似乎卡在了循环中,几乎就像 for 循环的索引在循环内部被修改一样。代码包含在下面。

如果您需要更多,请询问,如果您发现可能导致问题的原因,请告诉我。我已经无计可施了。

请注意:jQuery 已正确注入,我所有的变量都在那里,调试控制台中没有错误,运行 在 Chrome 41.0.2272.101m 下 Windows 7 x64.

function verifyCommand() {
  if (document.getElementsByClassName("message-list-item").length > last_cmd_count && !processing_commands) {
    var new_length = $('.message-list .message-list-item').length;
    console.log("Begin processing commands... ** SYSTEM LOCK **");
    console.log(new_length);
    for (var i = last_cmd_count; i < (new_length); i++) {
      processing_commands = true;
      try {
        var callinguser = $('.message-list .message-list-item .header .username .username-text')[i].innerText.replace("Guest_", "");
        var messagetext = $('.message-list .message-list-item .message .message-text')[i].innerText
        if (callinguser != "USERNAME REMOVED") {
          if (messagetext.substr(0, 1) == "/") {
            if (strContains(callinguser, "IMVU User")) {
              die();
            }
            processCommand(messagetext.substr(1), callinguser);
          } else {
            if (messagetext.toLowerCase().indexOf('roomgreet') > -1 || messagetext.toLowerCase().indexOf('room greet') > -1) {
              if (detectFlirt()) {
                sendMsgRaw('Please do not hit on me, ' + callinguser + '.');
                if (!isAdmin(callinguser)) {
                  logIdiot(callinguser);
                }
              } else if (strContains(messagetext, 'what is ')) {
                sendMsgRaw('Please use /solve or /advsolve for math.');
              } else {
                if (callinguser != "USERNAME REMOVED") {
                  ident();
                }
              }
            }
            if (strContains(messagetext, 'free') && strContains(messagetext, 'credits') && strContains(messagetext, 'http://')) {
              sendMsgFrom("*** SCAM ALERT ***", callinguser);
            }
          }
        }
      } catch (ex) {} finally {}
    }
    processing_commands = false;
    last_cmd_count = new_length;
    console.log("Finish processing commands... ** SYSTEM FREE **");
    if (monitoring) {
      verifyUserMessageCount();
    }
  }
}

HTML 的 IMVU 移动消息可在 http://common.snftech.tk/imvu/roomgreet-html-sample.htm

处找到

我认为你的问题是这个

if (messagetext.substr(0,1) == "/") {

如果用户在“/”前面有一个space那么它不会解释为命令所以你需要处理

var messagetext =  $('.message-list .message-list-item .message .message-text')[i].innerText

像这样从消息文本中删除所有白色space

messagetext.text().replace(" ", "");

您还应该在

中捕获更多错误
if (messagetext.substr(0,1) == "/") {

尝试更改您的函数以使用 each() 循环遍历每个元素,而不是您拥有的循环。处理完一个元素后,将 "processed" class 添加到该元素,这样我们以后就不会再看它们了。这应该比强迫我们的逻辑跟上已经处理过的逻辑更稳定。

Here is a jsFiddle,,从您的页面中抛出实际导致问题的 html,看看它是否仍然出现

function verifyCommand() {
  //fixed some logic in here
  if ($(".message-list-item").length > last_cmd_count && !processing_commands) {
    processing_commands = true; // you should set this immediately 
    var new_length = $('.message-list-item').length;
    console.log("Begin processing commands... ** SYSTEM LOCK **");
    console.log('Last command count: '+ last_cmd_count +', New Length: '+new_length);
    var newMessages = $('.message-list-item:not(.processed)'); // get all of the message elements that do not have the class "processed" 
    // loop through each of the message elements
    newMessages.each(function(index, element){
         console.log('Processing new element at index '+index );
         try {
              var callinguser = $(this).find('.username-text').text().replace("Guest_", "");
              var messagetext = $(this).find('.message-text').text();
              $(this).addClass('processed'); // add processed class to the element so we know not to process it again later  
              if (callinguser != "RoomGreet") {
                if (messagetext.match(/^\//)) {
                  if (callinguser.match(/IMVU User/)) {
                    die();
                  }
                  processCommand(messagetext.substr(1), callinguser);
                }
                else {
                    if (detectFlirt(messagetext)) {
                      if (!isAdmin(callinguser)) {
                        sendMsgRaw('Please do not hit on me, ' + callinguser + '.');
                        logIdiot(callinguser);
                      }
                    }
                    else if (messagetext.match('what is ')) {
                      sendMsgRaw('Please use /solve or /advsolve for math.');
                    }
                    else {
                      if (callinguser != "Nezzle" && !isAdmin(callinguser)) {
                        ident();
                      }
                    }
                  if (strContains(messagetext,"imvu") && strContains(messagetext,"credits") && strContains(messagetext,"http://")) {
                    sendMsgFrom("*** SCAM ALERT ***", callinguser);
                  }
                }
              }
         }
         catch (ex) {
             console.log('caught error');
         } 
         finally {
         }
    });
    last_cmd_count = new_length;
    console.log("Finish processing commands... ** SYSTEM FREE **");
    processing_commands = false;
    if (monitoring) {
      verifyUserMessageCount();
    }
  }
}